STM32F091. Система тактирования

Система тактирования у STM32F091 немного отличается от системы тактирования у STM32F030.

Ко множеству задающих генераторов добавился ещё один на 48 МГц. Наименование генератора — HSI48. Точность настройки частоты 3% для температуры 25°С («… each device is factory calibrated by ST for ~3% accuracy at TA = 25°C», Reference manual RM0091 страница 101.) Для сравнения, точность настройки частоты HSI в три раза лучше — 3% для той же температуры.

Таким образом, для не очень чувствительных к тактовой частоте приложений можно работать и от этого генератора (, а не от HSE с кварцевым резонатором).

Как известно, при старте микроконтроллер начинает работать от HSI (8 МГц), при это все другие его задающие генераторы выключены. Чтобы перейти на тактирование ядра от HSI48 нужно сначала включить этот генератор, дождаться поднятия флага RCC_CR2_HSI48RDY по установлению стабильных колебаний, затем переключить мультиплексор выбора источника тактирования на HSI48, и, наконец, выключить уже ставший ненужным генератор HSI.

Беспокоиться о том, что если вдруг сорвутся колебания у HSI48, то микроконтроллер подвиснет, не надо. HSI48 и HSI почти одинаковые. И если в природе существует такая сила, которая может остановить работу HSI48, то с таким же успехом она сможет остановить и HSI. Это что-то типа маленького Конца Света в отдельно взятой вселенной. Тут уже ничто не поможет. Да и кому помогать, всё остальное скорее всего тоже уже «накроется медным тазом».

Ниже рабочий код для настройки тактирования ядра от HSI48 для STM32F091:

  // Прежде всего разрешим работу буфера и назначим один такт ожидания
  FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;

  // Установка тактирования от HSI48
  RCC->CFGR &= ~RCC_CFGR_SW;    // Временное тактирование от HSI (8 MHz)

  RCC->CR2 |= RCC_CR2_HSI48ON;  // Включаем HSI48
  while (!(RCC->CR2 & RCC_CR2_HSI48RDY))
    ;  // Ожидаем стабилизации колебаний

  RCC->CFGR |= RCC_CFGR_SW_HSI48;  // Переключаемся на тактирование от HSI48 (48 MHz)
  while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSI48)
    ;  // Ожидаем окончания процесса переключения

  RCC->CR &= ~RCC_CR_HSION;  // Выключаем HSI

В самом начале фрагмента кода присутствует команда для конфигурирования работы FLASH. Конфигурирование флешь-памяти на систему тактирования не влияет, но в некоторой степени зависит от неё. Если так окажется, что тактирование ядра будет осуществляться на высокой частоте (48 МГц — это высокая частота, а 8 МГц — это относительно низкая), то флешь не будет успевать поставлять коды команд ядру, и всё рухнет. Чтобы такого не случилось, необходимо добавить один такт ожидания при работе на высокой частоте. В общем-то, ничего нового, просто иногда сосредоточившись над кодом задачи можно забыть об этом важном моменте. Поэтому я оставил строку конфигурации флешь-памяти.

Программные конструкции типа RCC->CFGR и RCC->CR2 — это, понятно, наименование подсистемы (RCC — Reset and clock control) и навания конкретных регистров (CFGR, CR, CR2, …). А вот откуда узнать как правильно писать названия битов в этих регистрах? Ведь наименования в исходных кодах программы и наименования в документации (RM0091) зачастую не совпадают. Похожи, но иногда не полностью совпадают.

Не беда! Имеется такой файл stm32f091xc.h, и в нём можно найти правильно наименование регистров и их битов.

Для бита HSI48ON в регистре CR2 имеется вот такая запись (строка 8656):

#define RCC_CR2_HSI48ON_Pos  (16U)                         
#define RCC_CR2_HSI48ON_Msk  (0x1U << RCC_CR2_HSI48ON_Pos) /*!< 0x00010000 */
#define RCC_CR2_HSI48ON      RCC_CR2_HSI48ON_Msk           /*!< Internal High Speed 48MHz clock enable */

Для битов назначения источника тактирования HSI48 в регистре CFGR имеется вот такая запись (строка 7993):

/*!< SW configuration */
#define RCC_CFGR_SW_Pos      (0U)                          
#define RCC_CFGR_SW_Msk      (0x3U << RCC_CFGR_SW_Pos)     /*!< 0x00000003 */
#define RCC_CFGR_SW          RCC_CFGR_SW_Msk               /*!< SW[1:0] bits (System clock Switch) */
#define RCC_CFGR_SW_0        (0x1U << RCC_CFGR_SW_Pos)     /*!< 0x00000001 */
#define RCC_CFGR_SW_1        (0x2U << RCC_CFGR_SW_Pos)     /*!< 0x00000002 */

#define RCC_CFGR_SW_HSI      (0x00000000U)                 /*!< HSI selected as system clock */
#define RCC_CFGR_SW_HSE      (0x00000001U)                 /*!< HSE selected as system clock */
#define RCC_CFGR_SW_PLL      (0x00000002U)                 /*!< PLL selected as system clock */
#define RCC_CFGR_SW_HSI48    (0x00000003U)                 /*!< HSI48 selected as system clock */

и чуть ниже (строка 8005):

/*!< SWS configuration */
#define RCC_CFGR_SWS_Pos     (2U)                          
#define RCC_CFGR_SWS_Msk     (0x3U << RCC_CFGR_SWS_Pos)    /*!< 0x0000000C */
#define RCC_CFGR_SWS         RCC_CFGR_SWS_Msk              /*!< SWS[1:0] bits (System Clock Switch Status) */
#define RCC_CFGR_SWS_0       (0x1U << RCC_CFGR_SWS_Pos)    /*!< 0x00000004 */
#define RCC_CFGR_SWS_1       (0x2U << RCC_CFGR_SWS_Pos)    /*!< 0x00000008 */

#define RCC_CFGR_SWS_HSI     (0x00000000U)                 /*!< HSI oscillator used as system clock */
#define RCC_CFGR_SWS_HSE     (0x00000004U)                 /*!< HSE oscillator used as system clock */
#define RCC_CFGR_SWS_PLL     (0x00000008U)                 /*!< PLL used as system clock */
#define RCC_CFGR_SWS_HSI48   (0x0000000CU)                 /*!< HSI48 oscillator used as system clock */

В общем, нет никакой магии. Всё доступно и всё понятно как на рентгеновском снимке. Вопросов нет, как этот чёртов двигатель устроен и как он вообще работает. В случае чего, мы сами можем его и починить. А кроме того, мы можем его так тонко настроить, как нам это надо, а не так «толсто», как это нам предоставляют библиотеки, скрывающие от нас его физическую сущность.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s