STM32 STM32VL Discovery STM32F100RBT6 (урок 3) RCC, тактирование
Восстановленные материалы удаленного сайта www.doneathome.ru
По многочисленным просьбам пользователей попробую восстановить
Система тактирования микроконтроллера является основным функциональным блоком, синхронизирующим все процессы и определяющим скорость их выполнения. От правильной настройки данного блока зависит эффективность работы микроконтроллера, успешное выполнение возлагаемой на него задачи. Поэтому важно уделить рассмотрению системы тактирования особое внимание, поняв её архитектуру и назначение всех составляющих элементов.
Для формирования основной системной частоты (SYSCLK) могут использоваться три различных источника:
1) HSI oscillator clock (внутренний источник тактов)
2) HSE oscillator clock (внешний источник тактов)
3) PLL clock (внутренний блок умножения частоты)
Устройство системы тактирования RCC
Набор разных сведений про тактирование
1) Независимое включение/выключение источников тактирования
Каждый источник тактового сигнала может быть независимо включен или выключен, если он не используется, чтобы оптимизировать потребляемую мощность.
2) Для периферийных устройств.
Все периферийные тактовые сигналы являются производными от системного тактового сигнала (SYSCLK).
3) Система защиты от нестабильной работы и отказов генератора HSE.
Встроенная система контроля CSS блока тактирования микроконтроллеров STM32 способна отслеживать отказ или нестабильную работу генератора HSE, осуществлять автоматическое переключение тактирования на встроенный генератор HSI с автоматическим вызовом немаскируемого прерывания NMI. Для активации данной функции блок CSS необходимо программно включить с помощью установки бита CSSON в регистре RCC_CR.
4) Есть возможность тактировать сторонние устройства через ножку МК.
Сигналы тактовой частоты SYSCLK, HSE, HSI и PLLCLK, поделённой на два, могут быть подключены к выходному сигналу MCO (Microcontroller Clock Output) микроконтроллера через мультиплексор.
5) После запуска и сброса микроконтроллер тактируется от встроенного RC-генератора HSI.
Блок HSI (High Speed Internal) представляет собой встроенный RC генератор с частотой 8 МГц. При включении микроконтроллер автоматически запускается от тактовой частоты HSI. Генератор HSI начинает работать при появлении питающего напряжения VCC и после выхода в нормальный устойчивый режим работы устанавливает битовый флаг HSIRDY в регистре RCC_CR. Производитель гарантирует стабильность частоты от –1,9 до +1,3% при изменении температуры микроконтроллера от 0 до 70°C соответственно.
6) Вариант тактирования от стороннего источника импульсов такта.
Допускается также подключение внешнего источника тактовых импульсов частотой от 1 до 24 МГц и скважностью 50% к входу OSC_IN.
Регистры
RCC_CR [0x0000 XX83]
Описание: Регистр управления тактовыми.
Биты:
Bit 25 PLLRDY: PLL clock ready flag
Описание: Флаг готовности сигнала от PLL(ставится аппаратно). Этот флаг необходим для опроса, чтобы убедиться в готовности сигнала с блока PLL.
Bit 24 PLLON: PLL enable
Описание: Ставится и очищается программно, чтобы разрешить работу PLL.
Bit 19 CSSON: Clock security system enable
Описание: Ставится и очищается программно, чтобы разрешить детектор тактового сигнала(от внешнего источника).
Bit 18 HSEBYP: External high-speed clock bypass
Описание: Ставится и очищается программой отладчика, чтобы обойти генератор с внешним резонатором.
Bit 17 HSERDY: External high-speed clock ready flag
Описание: Ставится аппаратно и показывает, что внешний 3-25 МГц генератор стабилизировался.
Bit 16 HSEON: External high-speed clock ready flag
Описание: Ставится и очищается программно, чтобы принудительно включить внешний 3-25 МГц генератор.
Bits 15:8 HSICAL[7:0]: Internal high-speed clock calibration
Описание: Эти биты инициируются автоматически, при запуске.
Bits 7:3 HSITRIM[4:0]: Internal high-speed clock trimming
Описание: Эти биты обеспечивают дополнительное, программируемое пользователем значение подстройки частоты, которое добавляется к битам HSICAL[7:0]. Это значение можно запрограммировать, чтобы скорректировать влияние изменения напряжения и температуры на частоту внутреннего HSI RC. Шаг подстройки, между двумя последовательными шагами HSICAL, составляет приблизительно 40 кГц.
Bit 1 HSIRDY: Internal high-speed clock ready flag
Описание: Ставится аппаратно и показывает, что внутренний 8 МГц RC генератор стабилизировался.
Bit 0 HSION: Internal high-speed clock enable
Описание: Ставится и очищается программно, чтобы принудительно включить внутренний генератор 8 МГц.
RCC_CFGR [0x0000 0000]
Описание: Это регистр конфигурации тактового сигнала.
Биты:
Bits 26:24 MCO[2:0]: Microcontroller clock output
Описание: Определяем работу ножки MCO. Можно к этой ножке подключить разные источники частоты.
Bits 21:18 PLLMUL[3:0]: PLL multiplication factor
Описание: Определяет коэффициент умножения для PLL.
Bit 17 PLLXTPRE: LSB of division factor PREDIV1
Описание: Ставится и очищается программно, чтобы выбрать младший бит коэффициента деления PREDIV1. Это тот же самый бит, что и bit(0) в регистре RCC_CFGR2, поэтому, изменение bit(0) в регистре RCC_CFGR2 изменяет и этот бит соответственно.
Bit 16 PLLSRC: PLL entry clock source
Описание: Ставится и очищается программно, чтобы выбрать источник входного сигнала для PLL.
Bits 15:14 ADCPRE[1:0]: ADC prescaler
Описание: Определяем делитель для тактовой частоты АЦП.
Bits 13:11 PPRE2[2:0]: APB high-speed prescaler (APB2)
Описание: Определяем делитель для тактовой частоты APB2.
Bits 7:4 HPRE[3:0]: AHB prescaler
Описание: Определяем делитель для тактовой частоты AHB.
Bits 3:2 SWS[1:0]: System clock switch status
Описание: Ставится и очищается аппаратно, чтобы показать, какой из источников используется в качестве системного тактового сигнала.
Bits 1:0 SW[1:0]: System clock Switch
Описание: Ставится и очищается программно, чтобы выбрать источник для SYSCLK.
RCC_CIR [0x0000 0000]
Описание: Есть набор битов сброса флагов от прерываний. Это регистр содержит биты (разрешения/запрета) прерывания от источников тактирования. И конечно сами флаги прерываний. (разрешается единицей).(произошло = единица).
Биты:
Bits 23 CSSC: Clock security system interrupt clear
Описание: Этот бит ставится программно, чтобы очистить флаг CSSF.
Bits 20 PLLRDYC: PLL ready interrupt clear
Описание: Этот бит ставится программно, чтобы очистить флаг PLLRDYF.
Bits 19 HSERDYC: HSE ready interrupt clear
Описание: Этот бит ставится программно, чтобы очистить флаг HSERDYF.
Bits 18 HSIRDYC: HSI ready interrupt clear
Описание: Этот бит ставится программно, чтобы очистить флаг HSIRDYF.
Bits 17 LSERDYC: LSE ready interrupt clear
Описание: Этот бит ставится программно, чтобы очистить флаг LSERDYF.
Bits 16 LSIRDYC: LSI ready interrupt clear
Описание: Этот бит ставится программно, чтобы очистить флаг LSIRDYF.
Bits 12 PLLRDYIE: PLL ready interrupt enable
Описание: Ставится и очищается программно, чтобы разрешить/запретить прерывание от PLL.
Bits 11 HSERDYIE: HSE ready interrupt enable
Описание: Ставится и очищается программно, чтобы разрешить/запретить прерывание от HSE.
Bits 10 HSIRDYIE: HSI ready interrupt enable
Описание: Ставится и очищается программно, чтобы разрешить/запретить прерывание от HSI.
Bits 9 LSERDYIE: LSE ready interrupt enable
Описание: Ставится и очищается программно, чтобы разрешить/запретить прерывание от LSE.
Bits 8 LSIRDYIE: LSI ready interrupt enable
Описание: Ставится и очищается программно, чтобы разрешить/запретить прерывание от LSI.
Bits 7 CSSF: Clock security system interrupt flag
Описание: Ставится аппаратно, когда обнаружен отказ HSE.
Bits 4 PLLRDYF: PLL ready interrupt flag
Описание: Ставится аппаратно, когда есть сцепление с PLL.
Bits 3 HSERDYF: HSE ready interrupt flag
Описание: Ставится аппаратно, когда частота от HSE генератора становится стабильной.
Bits 2 HSIRDYF: HSI ready interrupt flag
Описание: Ставится аппаратно, когда частота от HSI генератора становится стабильной.
Bits 1 LSERDYF: LSE ready interrupt flag
Описание: Ставится аппаратно, когда частота от LSE генератора становится стабильной.
Bits 0 LSIRDYF: LSI ready interrupt flag
Описание: Ставится аппаратно, когда частота от LSI генератора становится стабильной.
RCC_APB2RSTR [0x0000 0000]
Описание: Этот регистр содержит биты для сброса периферии APB2. Собственно, записываем единицу тогда соответствующее периферийное устройство сбросится. Сброс устройства обеспечивает установку значений в регистры блока в значения по умолчанию.
RCC_APB1RSTR [0x0000 0000]
Описание: Этот регистр содержит биты для сброса периферии APB1. Собственно, записываем единицу тогда соответствующее периферийное устройство сбросится. Сброс устройства обеспечивает установку значений в регистры блока в значения по умолчанию.
RCC_AHBENR [0x0000 0014]
Описание: Этот регистр содержит биты для разрешения тактирования периферии AHB. Собственно, записываем единицу тогда соответствующее периферийное устройство становится рабочим. Только после разрешения тактирования блока можно с ним работать (чтение/запись регистров).
RCC_APB2ENR [0x0000 0000]
Описание: Этот регистр содержит биты для разрешения тактирования периферии APB2. Собственно, записываем единицу тогда соответствующее периферийное устройство становится рабочим. Только после разрешения тактирования блока можно с ним работать (чтение/запись регистров).
RCC_APB1ENR [0x0000 0000]
Описание: Этот регистр содержит биты для разрешения тактирования периферии APB1. Собственно, записываем единицу тогда соответствующее периферийное устройство становится рабочим. Только после разрешения тактирования блока можно с ним работать (чтение/запись регистров).
RCC_BDCR [0x0000 0000]
Описание: Регистр управления доменом BKP
Биты:
Bit 16 BDRST: Backup domain software reset
Описание: Программный сброс домена BKP (1 = сбрасываем).
Bit 15 RTCEN: RTC clock enable
Описание: Разрешение подачи тактового сигнала на RTC.
Bits 9:8 RTCSEL[1:0]: RTC clock source selection
Описание: Ставится программно, чтобы выбрать источник тактового сигнала для RTC.
Bit 2 LSEBYP: External Low Speed oscillator bypass
Описание: Ставится и очищается программно, чтобы обойти LSE генератор в режиме отладки.
Bit 1 LSERDY: External Low Speed oscillator ready
Описание: Ставится аппаратно и показывает, что внешний 32 кГц генератор стабилизировался.
Bit 0 LSEON: External Low Speed oscillator enable
Описание: Ставится и очищается программно. Разрешение работы внешнего низко-частотного генератора.(разрешается единицей)
RCC_CSR [0x0000 0000]
Описание: Регистр управления/статуса. (произошло = единица).(разрешается единицей).
Биты:
Bit 31 LPWRRSTF: Low-power reset flag
Описание: Ставится аппаратно, когда случается сброс от контроллера пониженного потребления.
Bit 30 WWDGRSTF: RTC clock enable
Описание: Ставится аппаратно, когда случается сброс от оконного WatchDog.
Bits 29 IWDGRSTF: Independent watchdog reset flag
Описание: Ставится аппаратно, когда случается сброс от независимого WatchDog.
Bit 28 SFTRSTF: Software reset flag
Описание: Ставится аппаратно, когда случается “Программный сброс”.
Bit 27 PORRSTF: POR/PDR reset flag
Описание: Ставится аппаратно, когда случается от “Подачи/Снятия питания”.
Bit 26 PINRSTF: PIN reset flag
Описание: Ставится аппаратно, когда случается от вывода NRST.
Bit 24 RMVF: Remove reset flag
Описание: Ставится программно, что бы сбросить флаг NRST.
Bit 1 LSIRDY: Internal low speed oscillator ready
Описание: Ставится и очищается аппаратно, чтобы показать, что внутренний 40 кГц RC генератор стабилизировался.
Bit 0 LSION: Internal low speed oscillator enable
Описание: Разрешение работы внутреннего низко-частотного генератора.
RCC_CFGR2 [0x0000 0000]
Описание: Регистр конфигурации тактовых 2
Биты:
Bit 3:0 PREDIV1[3;0]: PREDIV1 division factor
Описание: Ставится и очищаются программно, чтобы управлять коэффициентом деления PREDIV1.
Практика
Инициализацию системы тактирования следует производить после того, как будут определены необходимые источники генерации и диапазоны значений тактовых частот для всех блоков.
Система тактирования предоставляет также возможность проверять работу некоторых важных блоков с по мощью битовых флагов готовности, что позволяет осуществлять проверку активации инициируемых блоков в процессе самой инициализации. После включения или сброса микроконтроллер тактируется от встроенного RC генератора HSI. В процессе работы возможно переключение источника тактовых импульсов при помощи установки соответствующей комбинации двух младших битов SW (System clock switch) регистра RCC_CFGR.
Определить, какой из генераторов в данный момент используется в качестве тактового, можно по состоянию битов SWS (System clock switch status).
Перед выбором источника тактового сигнала необходимо предварительно произвести его запуск и удостовериться в его готовности к работе.
Библиотека
/**************************************************************************//**
Done At Home
библиотека для настройки тактовой частоты нашего МК !!
*
******************************************************************************/
#ifndef __Set_SYSCLKH
#define __Set_SYSCLKH
//-----------------------------------------------------------------------------
//-------- ИНКЛУДУШКИ ---------------------------------------------------------
//-----------------------------------------------------------------------------
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-------- ПРОТОТИПУШКИ -------------------------------------------------------
//-----------------------------------------------------------------------------
// Функция реализация тактирования от HSI (8 MHz)
void init_HSI (void);
// Функция реализация тактирования от PLL
void init_PLL (char PLLMUL,char HSE_PREDIV,char HSI_OR_HSE);
// Функция реализация тактирования от HSE
void init_HSE (void);
//-----------------------------------------------------------------------------
//-------- ДЕФАЙНУШКИ ---------------------------------------------------------
//-----------------------------------------------------------------------------
// возможн значения HSI_OR_HSE (0[HSI] или 1[HSE])
#define init_PLL_HSI 0
#define init_PLL_HSE 1
// возможн значения PREDIV1 1.2.3.4....16
#define init_PLL_HSE_PREDIV_d1 0x00
#define init_PLL_HSE_PREDIV_d2 0x01
#define init_PLL_HSE_PREDIV_d3 0x02
#define init_PLL_HSE_PREDIV_d4 0x03
#define init_PLL_HSE_PREDIV_d5 0x04
#define init_PLL_HSE_PREDIV_d6 0x05
#define init_PLL_HSE_PREDIV_d7 0x06
#define init_PLL_HSE_PREDIV_d8 0x07
#define init_PLL_HSE_PREDIV_d9 0x08
#define init_PLL_HSE_PREDIV_d10 0x09
#define init_PLL_HSE_PREDIV_d11 0x0A
#define init_PLL_HSE_PREDIV_d12 0x0B
#define init_PLL_HSE_PREDIV_d13 0x0C
#define init_PLL_HSE_PREDIV_d14 0x0D
#define init_PLL_HSE_PREDIV_d15 0x0E
#define init_PLL_HSE_PREDIV_d16 0x0F
// возможн значения PLLMUL 2.3.4.5....16
#define init_PLL_PLLMUL_x2 0x00
#define init_PLL_PLLMUL_x3 0x01
#define init_PLL_PLLMUL_x4 0x02
#define init_PLL_PLLMUL_x5 0x03
#define init_PLL_PLLMUL_x6 0x04
#define init_PLL_PLLMUL_x7 0x05
#define init_PLL_PLLMUL_x8 0x06
#define init_PLL_PLLMUL_x9 0x07
#define init_PLL_PLLMUL_x10 0x08
#define init_PLL_PLLMUL_x11 0x09
#define init_PLL_PLLMUL_x12 0x0A
#define init_PLL_PLLMUL_x13 0x0B
#define init_PLL_PLLMUL_x14 0x0C
#define init_PLL_PLLMUL_x15 0x0D
#define init_PLL_PLLMUL_x16 0x0E
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-------- Функции ------------------------------------------------------------
//-----------------------------------------------------------------------------
// Функция реализация тактирования от HSI (8 MHz)
void init_HSI (void)
{
// Проверяем тактируемся ли мы от HSI ()
//если мы уже сцеплины с HSI тогда можно начать подготовку
// двух других блоков HSE и PLL
if((RCC->CFGR&RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)// МК тактируется не от HSI
{
// Ошибка !!! исправлена 05.05.2015 спасибо (Fao xis)
// RCC->CIR |= RCC_CIR_HSIRDYIE; // сброс флага RCC_CR_HSIRDY (это бит разрешения прерывания)
RCC->CIR |= RCC_CIR_HSIRDYC; // сброс флага RCC_CR_HSIRDY
RCC->CR |= RCC_CR_HSION; // Запуск HSI
while ((RCC->CR & RCC_CR_HSIRDY)!=RCC_CR_HSIRDY);// Ожидание готовности HSI.
//(определяют источник для SYSCLK)
RCC->CFGR &= ~(RCC_CFGR_SW_0|RCC_CFGR_SW_1); // Переключаем на HSI
while ((RCC->CFGR&RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI); // Ожидание переключения на HSI.
}
}
//-----------------------------------------------------------------------------
// Функция реализация тактирования от PLL
void init_PLL (char PLLMUL,char HSE_PREDIV,char HSI_OR_HSE)
{
uint32_t buf;
if((RCC->CFGR&RCC_CFGR_SWS) == RCC_CFGR_SWS_PLL)// МК тактируется от PLL
// тогда мы заставим тактироваться от HSI
init_HSI();
RCC->CR &= ~RCC_CR_PLLON; // ВЫКЛЮЧАЕМ PLL. Малоли работал блок
if(HSI_OR_HSE){ //определяем что заводить в PLL
RCC->CFGR |= RCC_CFGR_PLLSRC_PREDIV1; // заводить в блок PLL HSE
RCC->CFGR2 = HSE_PREDIV; //заносим делитель
}
else
RCC->CFGR &= ~RCC_CFGR_PLLSRC_PREDIV1; // заводить в блок PLL HSI
RCC->CFGR&= ~RCC_CFGR_PLLMULL; //очищаем биты
RCC->CFGR|=((PLLMUL)<<18); // Умножать частоту на PLLMUL (Эти биты начинвются с 18 ого)
// Ошибка !!! исправлена 05.05.2015 спасибо (Fao xis)
// RCC->CIR |= RCC_CIR_PLLRDYF; // сброс флага RCC_CR_PLLRDY (это бит собственно флаг прерывания)
RCC->CIR |= RCC_CIR_PLLRDYC; // сброс флага RCC_CR_PLLRDY
RCC->CR |= RCC_CR_PLLON; // Запустить PLL.
while ((RCC->CR & RCC_CR_PLLRDY)!=RCC_CR_PLLRDY);// Ожидание готовности PLL.
buf = RCC->CFGR;
buf &=~RCC_CFGR_SW; // Очистить биты SW0 и SW1
buf |= RCC_CFGR_SW_PLL;
//(определяют источник для SYSCLK)
RCC->CFGR = buf; // Тактирование с выхода PLL.
while ((RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_PLL); // Ожидание переключения на PLL.
}
//-----------------------------------------------------------------------------
// Функция реализация тактирования от HSE
void init_HSE (void)
{
uint32_t buf;
if((RCC->CFGR&RCC_CFGR_SWS) == RCC_CFGR_SWS_HSE)// МК тактируется от HSE
// тогда мы заставим тактироваться от HSI
init_HSI();
RCC->CR &= ~RCC_CR_HSEON; // ВЫКЛЮЧАЕМ HSE. Малоли работал блок
// Ошибка !!! исправлена 05.05.2015 спасибо (Fao xis)
//RCC->CIR |= RCC_CIR_HSERDYF; // сброс флага RCC_CR_HSERDY (это бит собственно флаг прерывания)
RCC->CIR |= RCC_CIR_HSERDYC; // сброс флага RCC_CR_HSERDY
RCC->CR |= RCC_CR_HSEON; // Запустить HSE.
while ((RCC->CR & RCC_CR_HSERDY)!=RCC_CR_HSERDY);// Ожидание готовности HSE.
buf = RCC->CFGR;
buf &=~RCC_CFGR_SW; // Очистить биты SW0 и SW1
buf |= RCC_CFGR_SW_HSE;
//(определяют источник для SYSCLK)
RCC->CFGR = buf; // Тактирование с выхода PLL.
while ((RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_HSE); // Ожидание переключения на PLL.
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#endif
Пример
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "Set_SYSCLK.h"
void Delay (unsigned int t) // функция задержки
{
unsigned int i;
for (i = 0;i<t; i++);
}
int main(void) {
Delay(0xFFFFF);
init_HSI();
Delay(0xFFFFF);
init_PLL (init_PLL_PLLMUL_x3,init_PLL_HSE_PREDIV_d3,init_PLL_HSE);
Delay(0xFFFFF);
init_HSE();
Delay(0xFFFFF);
while (1);
return 0;
}