STM32F103C8 — переполнение таймера (Arduino IDE)

В микроконтроллере 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 = 72001;

Регистр TIMx_PSC

Так как предделитель равен 7200, а частота ядра микроконтроллера 72 МГц, то с выхода предделителя мы получаем частоту 10000 Гц.

Что бы еще уменьшить частоту прерываний таймера используем регистр TIMx_ARR.

TIMx_ARR — это 16-и битный регистр переполнения, который начинает считать с 0 до значения переполнения, после чего обнуляться и начнет считать заново.

 TIMER2_BASE>ARR = 100001;

Регистр 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 – флаг прерывания по переполнению.

Форум — http://forum.rcl-radio.ru/viewtopic.php?id=424

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

Войти с помощью: