В микроконтроллере STM32F103C8 имеются 4 таймера, таймер TIM1 работает на шине APB2, частота которой равна частоте системной шины SYSCLK и является более продвинутым таймером, TIM2, TIM2 и TIM4 простые таймеры общего назначения, работают от шины APB1 частота которой равна половине частоте системной шины SYSCLK (для периферийных уст-в).
В этой статье будет рассмотрен пример работы таймера в режиме прерывания по переполнению. Ниже показан пример кода, который позволяет мигать светодиодом в такт работы таймера:
volatile bool LED = 0; void setup() { pinMode(PA1, OUTPUT); timer_attach_interrupt(TIMER2, TIMER_UPDATE_INTERRUPT, led); // прерывание по переполнению RCC_BASE->APB1ENR|= (1<<0); // TIM2EN > включить тактирование tim_2 TIMER2_BASE->CR1=0; // TIMx_CR1 > стоп таймер TIMER2_BASE->PSC = 7200-1; // TIMx_PSC > значение пред делителя 72 === F = 72 000 000 / 7 200 = 10 000 Hz TIMER2_BASE->ARR = 10000-1; // TIMx_ARR > считать до установленного числа и обнулить === F = 10 000 / 10 000 = 1 Hz TIMER2_BASE->DIER |= (1<<0); // TIMx_DIER > разрешить прерывание по переполнению TIMER2_BASE->CR1|=(1<<0); // TIMx_CR1 > старт } void loop() {} void led(){ //обработчик прерывания digitalWrite(PA1, (LED = !LED)); //меняем состояние порта на противоположное TIMER2_BASE->SR &=~(1<<0); // TIMx_SR > сбрасываем флаг прерывания }
Для работы таймера на него нужно подать тактирование, делается это в регистре RCC->APB1ENR установкой бита TIM2EN.
RCC_BASE—>APB1ENR|= (1<<0);
Регистр RCC_APB1ENR
Перед настройкой таймера рекомендуется его отключить (остановить):
TIMER2_BASE—>CR1=0;
Регистр TIMx_CR1
Все таймеры микроконтроллера STM32F103C8 16 бит (0…65535), каждый таймер имеет предделитель за который отвечает регистр TIMx_PSC. Значение этого регистра определяет коэффициент деления частоты поступающего на счетчик CK_CNT.
f(CK_CNT) = f(CK_PSC) / (PSC+1)
Так как нам необходимо чтобы таймер переполнялся через определенный интервал времени, то установим для начала предделитель на 7200.
TIMER2_BASE—>PSC = 7200—1;
Регистр TIMx_PSC
Так как предделитель равен 7200, а частота ядра микроконтроллера 72 МГц, то с выхода предделителя мы получаем частоту 10000 Гц.
Что бы еще уменьшить частоту прерываний таймера используем регистр TIMx_ARR.
TIMx_ARR — это 16-и битный регистр переполнения, который начинает считать с 0 до значения переполнения, после чего обнуляться и начнет считать заново.
TIMER2_BASE—>ARR = 10000—1;
Регистр TIMx_ARR
Так как после предделителя частота работы таймера 10 кГц, а значения прерывания по переполнению в регистре ARR равно 10000, то прерывания таймера TIM2 будут происходить с интервалом 1 секунда.
Далее необходимо разрешить прерывания по переполнению, делается это при помощи регистра TIMx_DIER.
TIMx_DIER — регистр разрешения прерываний. При при записи в бит UIE единицы, прерывание разрешено.
После настройки таймера его можно запустить:
TIMER2_BASE—>CR1=1;
Чтобы исполнять различный код по времени прерывания необходимо использовать обработчик прерывания:
timer_attach_interrupt(TIMER2, TIMER_UPDATE_INTERRUPT, led);
где:
- TIMER2 — номер таймера
- TIMER_UPDATE_INTERRUPT — режим таймера (автоматическое обновление и вызов прерывания)
- led — имя функции с исполняемым кодом
Функция led содержит код управления светодиодом, при каждом прерывании таймера светодиод сначала загорается, а потом гаснет.
После каждого прерывания необходимо сбросить флаг прерывания:
TIMER2_BASE->SR &=~(1<<0);
Регистр TIMx_SR
TIMx_SR — регистр состояния, содержит флаги прерываний. UIF – флаг прерывания по переполнению.