HSI (High-Speed Internal) генератор представляет из себя встроенный RC-генератор на 8 МГц калиброванный в процессе производства с точностью ±1%. При запуске микроконтроллера заводское калибровочное значение автоматически заносится в биты HSICAL[7:0] регистра RCC_CR. Для компенсации воздействия окружающей температуры и изменений питающего напряжения имеется возможность дополнять калибровочное значение записью битов HSITRIM[4:0] указанного регистра. Генератор может быть использован для системного тактирования непосредственно или через блок PLL с предварительным делением частоты на два. Генератор HSE способен работать с кварцевыми и керамическими резонаторами на частотах от 4 до 24 МГц или c внешним источником тактовых импульсов частотой до 24 МГц и скважностью 50% подключенным к выводу OSC_IN. При работе генератора с внешним сигналом необходимо установить бит HSEBYP регистра RCC_CR.
После запуска и сброса микроконтроллер тактируется от встроенного RC-генератора HSI. Далее в процессе работы возможно переключение источника тактовых импульсов записью комбинации битов SW (System clock switch) регистра
RCC_CFGR:
RCC_CFGR[1:0] - SW[1:0].
SW[1:0] = 00: тактирование от HSI;
SW[1:0] = 01: HSE;
SW[1:0] = 10: PLL;
SW[1:0] = 11: зарезервировано.
Определить какой из генераторов в данный момент времени используется в качестве тактового можно по состоянию битов SWS (System clock switch status):
RCC_CFGR[3:2] - SWS[1:0].
SWS[1:0] = 00: используется генератор HSI;
SWS[1:0] = 01: используется генератор HSE;
SWS[1:0] = 10: тактирование от блока PLL
SWS[1:0] = 11: зарезервировано.
Перед выбором тактового источника необходимо предварительно произвести его запуск и удостовериться в его готовности к работе. Включение генераторов HSI, HSE и PLL производится установкой битов HSION, HSEON и PLLON регистра RCC_CR. После чего готовность генераторов к работе можно проследить по установке флагов HSERDY, HSERDY или PLLRDY того же регистра:
RCC->CR|=RCC_CR_HSEON; // Включить генератор HSE.
while (!(RCC->CR & RCC_CR_HSERDY)) {}; // Ожидание готовности HSE.
RCC->CFGR &=~RCC_CFGR_SW; // Очистить биты SW0, SW1.
RCC->CFGR |= RCC_CFGR_SW_HSE; // Выбрать HSE для тактирования SW0=1.
Бит включения генератора HSION также может быть установлен аппаратно при входе в режимы "Stop” или "Standby”, при этом бит HSEON будет сброшен. В случае определения защитной системой сбоев в работе генератора HSE, настроенного в качестве системного напрямую или через PLL будет автоматически установлен бит HSION. Для снижения энергопотребления, генератор, который в данный момент не используется как тактовый, может быть выключен сбросом битов HSION, HSEON.
Встроенная система контроля CSS блока тактирования микроконтроллеров STM32 способна отслеживать отказ или нестабильную работу генератора HSE, осуществлять автоматическое переключение тактирования на встроенный генератор HSI с автоматическим вызовом немаскируемого прерывания NMI.
Для включения в работу системы CSS необходимо установить бит CSSON регистра RCC_CR:
RCC->CR|=RCC_CR_CSSON; // Разрешить работу системы защиты HSE.
Для исключения повторных вызовов в обработчике NMI необходимо сбросить флаг системы CSS:
void NMI_Handler(void) // Обработчик NMI вызывается при сбое HSE.
{
/* Сбросить флаг системы контроля CSS */
if (RCC->CIR & RCC_CIR_CSSF) RCC->CIR|=RCC_CIR_CSSC;
}
Описание системы тактирования до этого момента применимо к любым микроконтроллерам семейства STM32. Далее особенности присущие конкретному подсемейству микроконтроллеров будут оговариваться отдельно или сопровождаться пометками:
*VLD – для Value Line Devices (STM32F100);
*L, M, H, XL -D – Low-, Medium-, High- и XL-density микроконтроллеров STM32F101/STM32F102/STM32F103.
*CLD – Connectivity Line Devices (STM32F105/STM32F107);
До того как PLL будет выбран для тактирования микроконтроллера установкой битов SW[1:0] = 10 регистра RCC_CFGR, необходимо выбрать источник входной частоты блока, а также проинициализировать параметры входных источников и самого модуля PLL.
Выбор входного источника для PLL осуществляется записью бита PLLSRC конфигурационного регистра системы тактирования RCC_CFGR:
RCC_CFGR[16] – PLLSRC:
PLLSRC=0: HSI/2, выбран генератор HSI с делением частоты на 2;
PLLSRC=1: генератор HSE/PREDIV1 (для всех кроме *L,M,H,XLD);
PLLSRC=1: генератор HSE (для *L,M,H,XLD);
Биты PREDIV1 регистра RCC_CFGR2 всех устройств, кроме *L,M,H,XLD, задают коэффициент предварительного деления частоты генератора HSE от 1 до 16 перед его подачей на вход PLL по формуле
n = PREDIV1[3:0] + 1:
PREDIV1[3:0] = 0000 ( 0): нет деления;
PREDIV1[3:0] = 0001 ( 1): деление на 2;
PREDIV1[3:0] = 0010 ( 2): /3;
...
PREDIV1[3:0] = 1110 (14): /15;
PREDIV1[3:0] = 1111 (15): деление на 16.
Блок PLL всех микроконтроллеров осуществляет умножение входной частоты в соответствии со значением комбинации битов PLLMUL регистра RCC_CFGR по формуле
m = PLLMUL[3:0] + 2, но не более чем в 16 раз:
RCC_CFGR[21:18] - PLLMUL[3:0]:
PLLMUL[3:0] = 0000 ( 0): умножение на 2;
PLLMUL[3:0] = 0001 ( 1): *3;
PLLMUL[3:0] = 0010 ( 2): *4;
...
PLLMUL[3:0] = 1101 (13): *15;
PLLMUL[3:0] = 1110 (14): *16;
PLLMUL[3:0] = 1111 (15): тоже *16.
Пример инициализации, запуска и выбора PLL для тактирования STM32F100 (VLD):
char PLL_MUL=12; // Коэффициент умножения PLL.
RCC->CFGR2 &=~(RCC_CFGR2_PREDIV1); // Предочистка делителя HSE.
RCC->CFGR2|= RCC_CFGR2_PREDIV1_DIV4; // Делить частоту HSE на 4.
RCC->CFGR &=~((RCC_CFGR_PLLSRC|RCC_CFGR_PLLXTPRE|R CC_CFGR_PLLMULL)); // Предочистка.
RCC->CFGR |= RCC_CFGR_PLLSRC_PREDIV1; // Тактировать PLL от HSE/PREDIV1.
RCC->CFGR|=((PLL_MUL - 2)<<18); // Умножать частоту на PLL_MUL.
RCC->CR |= RCC_CR_PLLON; // Запустить PLL.
while ((RCC->CR & RCC_CR_PLLRDY)==0) {} // Ожидание готовности PLL.
RCC->CFGR &=~RCC_CFGR_SW; // Очистить биты SW0, SW1.
RCC->CFGR |= RCC_CFGR_SW_PLL; // Тактирование с выхода PLL.
while ((RCC->CFGR&RCC_CFGR_SWS)!=0x08) {} // Ожидание переключения на PLL.
Пример для STM32F103RC (256K Flash → HD):
RCC->CFGR &=~((RCC_CFGR_PLLSRC|RCC_CFGR_PLLXTPRE|R CC_CFGR_PLLMULL)); // Предочистка.
RCC->CFGR|=RCC_CFGR_PLLSRC_HSE; // Тактировать PLL от HSE (8 MHz).
RCC->CFGR|=RCC_CFGR_PLLMULL9; // Умножать частоту на 9 (8*9=72 MHz).
RCC->CR |= RCC_CR_PLLON; // Запустить PLL.
while ((RCC->CR & RCC_CR_PLLRDY)==0) {} // Ожидание готовности PLL.
RCC->CFGR &=~RCC_CFGR_SW; // Очистить биты SW0, SW1.
RCC->CFGR |= RCC_CFGR_SW_PLL; // Тактирование с выхода PLL.
while ((RCC->CFGR&RCC_CFGR_SWS)!=0x08) {} // Ожидание переключения на PLL.
Для работы на частотах выше 24МГц (кроме LDV) необходимо разрешить буфер предварительной выборки Prefetch buffer установкой бита PRFTBE в регистре FLASH_ACR (Flash access control register):
FLASH->ACR |= FLASH_ACR_PRFTBE; // Enable Prefetch Buffer.
А также, в зависимости от частоты задать количество пропусков тактов буфера при чтении Flash:
FLASH->ACR &= ~FLASH_ACR_LATENCY); // Предочистка.
FLASH->ACR |= FLASH_ACR_LATENCY_0; // Если SystemCoreClock <= 24 МГц, без пропусков.
FLASH->ACR |= FLASH_ACR_LATENCY_1; // Если 24< SystemCoreClock <= 48, пропускать 1 такт.
FLASH->ACR |= FLASH_ACR_LATENCY_2; // Если 48< SystemCoreClock <= 72, пропускать 2 такта.
Комментариев нет:
Отправить комментарий
ваше мнение...