Перейти к содержанию

    

Forger

Свой
  • Публикаций

    1 267
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о Forger

  • Звание
    Профессионал

Посетители профиля

3 326 просмотров профиля
  1. Точность внутрених клоков в STM32L4

    Calibration RC oscillator frequencies can vary from one chip to another due to manufacturing process variations, this is why each device is factory calibrated by ST for 1 % accuracy at TA=25°C. After reset, the factory calibration value is loaded in the HSICAL[7:0] bits in the Internal clock sources calibration register (RCC_ICSCR). If the application is subject to voltage or temperature variations this may affect the RC oscillator speed. You can trim the HSI16 frequency in the application using the HSITRIM[6:0] bits in the Internal clock sources calibration register (RCC_ICSCR). For more details on how to measure the HSI16 frequency variation, refer to Section 6.2.17: Internal/external clock measurement with TIM15/TIM16. The HSIRDY flag in the Clock control register (RCC_CR) indicates if the HSI16 RC is stable or not. At startup, the HSI16 RC output clock is not released until this bit is set by hardware. The HSI16 RC can be switched on and off using the HSION bit in the Clock control register (RCC_CR). STM32L4 Reference Manual (RM0394 Rev 4), стр. 182 В частности: After reset, the factory calibration value is loaded in the HSICAL[7:0] bits in the Internal clock sources calibration register (RCC_ICSCR). Товарищу передайте, чтобы не путал Datasheet и Reference Manual, у ST они имею разное назначение и ... размер :)
  2. Вот так: // stm32f1 stm32f1::AbstractPin::AbstractPin(PinName name) { .... switch (name / 16) { case (0): port = reinterpret_cast<Port>(GPIOA_BASE); if (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN) == 0) { SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_IOPARST); CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_IOPARST); SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN); } break; .... Хотя есть мысли, как урезать эту самую объемную часть из всего Pin.cpp ... через препроцессор и его "фишку" - ##
  3. Раз пошла такая пьянка, у себя библиотеку для пинов (в частности) использую вот так: Hardware::DigitalInputPin<PB8> pinROW1; .... Нardware::DigitalOutputPin<PB9> pinCOL1; ... pinCOL1.setToHigh(); if (pinROW1.isLow()) .... Где Hardware - пространство имен, которое дефайнится автоматом в зависимости от семейства камня. Сам параметр шаблонов разных типов пинов - enum: typedef enum { PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15, // 0 PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15, // 1 PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15, // 2 PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15, // 3 PE0, PE1, PE2, PE3, PE4, PE5, PE6, PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15, // 4 PF0, PF1, PF2, PF3, PF4, PF5, PF6, PF7, PF8, PF9, PF10, PF11, PF12, PF13, PF14, PF15, // 5 PG0, PG1, PG2, PG3, PG4, PG5, PG6, PG7, PG8, PG9, PG10, PG11, PG12, PG13, PG14, PG15, // 6 PH0, PH1, PH2, PH3, PH4, PH5, PH6, PH7, PH8, PH9, PH10, PH11, PH12, PH13, PH14, PH15, // 7 NONE } PinName; В конструкторе базового (абстрактного) класса пинов этот enum разбирается вот так: stm32f1::AbstractPin::AbstractPin(PinName name) { if (name == NONE) { pinMask = 0; return; } pinIndex = (name % 16); pinMask = (1 << pinIndex); .... Где pinIndex и pinMask - поля самого класса пина, которые вычисляются один раз, а потом используются в таких полностью инлайных методах (в частности): namespace stm32f1 { ... class AbstractPin { public: AbstractPin(PinName name); ... void lock(); inline void setToHigh() __attribute__((always_inline)) { port->BSRR = pinMask; } inline void setToLow() __attribute__((always_inline)) { port->BRR = pinMask; } inline bool isHigh() const __attribute__((always_inline)) { return ((port->IDR & pinMask) != 0); } inline bool isLow() const __attribute__((always_inline)) { return ((port->IDR & pinMask) == 0); } inline void toggle() __attribute__((always_inline)) { if (isLow()) setToHigh(); else setToLow(); } .... private: GPIO_TypeDef* port; uint16_t pinMask; }; .... Включение тактирования, скорости и режимы автоматом вызываются при создании экземпляра пина. Ну и куча плюшек, которые лень тут публиковать )) Итог - очень простой и понятный итоговый код, которые в принципе не зависит от семейства камня. Реализация возможно жирновата, но оверхеда по скорости почти нет, разве что небольшой по объему памяти, Поскольку, не имею привычки "экономить на спичках", то применяю эту схему уже несколько лет и весьма доволен
  4. Запись во FLASH.

    Пустяки - отряхнусь и пойду дальше
  5. Запись во FLASH.

    Повторюсь - смотрите состояние аппаратных флагов flash после каждой операции. Это можно сделать прямо из-под отладчика, открыв соотв. окошко среды. Код писать для этого не обязательно, хотя желательно.
  6. Запись во FLASH.

    Практически каждая ваша тема на этом форуме говорит совершенно об обратном ;) Решения прозвучали, как минимум одно: По флагам можно понять, что пошло не так после предыдущей операции. Это нормально. И это правильно. Неправильно - забить на флаги, тупо их сбросив, и потом упрекать посторонний народ в бездействии в поиске ВАШЕЙ же проблемы!
  7. 6.7 - архаика, установите свежий Keil, а еще предпочтительнее - скачайте свежий компилятор: https://developer.arm.com/products/software-development-tools/compilers/arm-compiler/downloads/version-6
  8. Запись во FLASH.

    Ну так и ищите, не отвлекайтесь на форум ))
  9. Запись во FLASH.

    "Подвешивание автоматов I2C EEPROM" легко лечится питанием той самой EEPROM от любой свободной ноги МК. Это чтобы уж совсем наверняка ;)
  10. Запись во FLASH.

    Имхо, тема плавно переросла в обсуждение нюансов известной поговорки: "каждый др...ит, как хочет"
  11. Запись во FLASH.

    Существуют контроллеры со встроенной EEPROM, для подобных задач, где нужно хранить изменяемые параметры, я использую именно такие. Банальный ногодрыг полностью исключает эту проблему ;) Если при старте сначала вычитать данные в ОЗУ, то этой типа "проблемы" тоже нет. Проект, в котором подразумеваются настройки, как правило ни разу не детский, и потому контроллер обычно ставится туда тоже не разу не "детский". А уж потратить на настройки от силы в сотню байт - ну, прям разорится можно, прям "пойти по миру" :D Да, конечно, существуют исключения, но очень очень очень очень очень редкий проект построен по принципу - "экономим на спичках". В таких проектах хороши все решения, в т.ч. и хранение настроек во флэш. Но это, имхо, больше как "костыль" для жадного заказчика ))) Тоже самое можно сказать и про встроенную EEPROM (например как в семействе STM32L1) ;) Но даже в таких случаях я сначала вычитываю в ОЗУ все настройки из EEPROM, проверяю контрольную сумму и уже потом работаю с этой копией настроек. При сохранении настроек переписываются только те настройки, которые изменились, ну и сама контрольная сумма. Не нужно перетирать весь сектор флэши, поскольку EEPROM позволяет писать по-байтно ;) В этом мире нет ничего действительно надежного ;) У меня и это предусмотрено, но только в серьезных проектах, где это действительно важно ;)
  12. Запись во FLASH.

    Я храню пользовательские настройки в EEPROM (встроенная или на край внешняя копеечная), всегда настройки сопровождаются контрольной суммой. Flash для этого, ихмо, плохо подходит. При каждом сбросе пользовательские настройки вычитываются и ВСЕГДА проверяется их контрольная сумма. В случае несовпадения восстанавливаются настройки по-умолчанию (хранятся во flash как const) и пытаемся обновить поврежденные настройки в EEPROM. Сама прошивка перед передачей ей управления проверяется на целостность контрольной суммой самим бутлоадером при КАЖДОМ включении. Если прошивка битая, то всегда сидим в бутлоадере, ждем новую прошивку. Битую прошивку не запускаем, рисковать не хотим )) Разумеется, что пппаратно само изделие должно притягивать все используемые внешние пины к нужным уровням, т.е. если зависли в бутлоадере в ожидании новой прошивки, то никакие моторы/агрегаты и т.п. не должны самопроизвольно включаться!
  13. Запись во FLASH.

    Грубое обнуление флагов - не есть надежное решение. Перед каждой операцией стирания/записи во флэш проверяйте ее флаги, после - тоже желательно проверять не было ли ошибок записи.
  14. Вопросы по редактору кода в Keil 5

    См. пункт Preprocessor, это относится ко всем #define, include и т..п Больше никак.