STM32. Урок 4. Basic timers

Речь в сегодняшнем уроке пойдет о таймерах в микроконтроллерах STM32. Таймер – одна из самых полезных вещей в микроконтроллере и основная его задача – отсчитывание точных интервалов времени. На отладочной плате STM32F4 Discovery установлен микроконтроллер STM32F407VG, который имеет следующие таймеры:
Basic timers (TIM6, TIM7) – самый простой таймер, который умеет лишь генерировать прерывания в заданный промежуток времени, но при этом очень легко настраивается и управляется.
General-purpose timers (TIM2-TIM5, TIM9-TIM14) – более продвинутый таймер, позволяющий генерировать ШИМ, считывать состояние ног, обрабатывать данные от энкодера и т.д.
The advanced-control timers (TIM1, TIM8) – самый продвинутый таймер, может использоваться как 3-хфазный ШИМ генератор, например для управления 3-хфазными электродвигателями.

Как понятно из названия, в данной статье будет описываться работа с Basic timers. Следует отметить, что данные таймеры привязаны к шине APB1, поэтому при изменении частоты тактирования данной шины будет меняться скорость работы таймера. По умолчанию частота тактирования составляет 4fкварца, следовательно для STM32F4 Discover с частотой кварца 8МГц частота шины по умолчанию будет 24МГц.

Практическая задача будет следующая: с помощью Basic timers с интервалом в 1 секунду зажечь все светодиоды на отладочной плате, после чего одновременно потушить их.

Начнем. Первое что нам нужно сделать — инициализировать таймер(TIM6):

/*——————Инициализация TIM6——————*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
//По умолчанию частота шины 24 МГц при использовании кварца 8 МГц
TIM6->PSC = 24000 — 1; //Настройка делителя на 1000 «тиков» в секунду
TIM6->ARR = 1000; //Отработка прерывания раз в секунду
TIM6->DIER |= TIM_DIER_UIE; //Разрешения прерывание от таймера
TIM6->CR1 |= TIM_CR1_CEN; //Запуск таймера
NVIC_EnableIRQ(TIM6_DAC_IRQn); //Разрешение TIM6_DAC_IRQn прерывания
/*——————————————————*/

Следующий этап – инициализация портов микроконтроллера, к которым подключены светодиоды:

/*——————Инициализация портов светодиодов——————*/
GPIO_InitTypeDef GPIO_InitStructure; //Структура содержащая настройки порта
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //Включаем тактирование порта D
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; //Выбираем нужные выводы
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //Включаем режим выхода
GPIO_Init(GPIOD, &GPIO_InitStructure); //вызов функции инициализации
/*———————————————————————*/

Теперь все готово для написания событий, происходящих при срабатывании прерывания по таймеру:

void TIM6_DAC_IRQHandler(void)
{
TIM6->SR &= ~TIM_SR_UIF; //Сбрасываем флаг прерывания
if(i==0) GPIO_SetBits(GPIOD, GPIO_Pin_12); //Подаем «1» на PD12
else if(i==1) GPIO_SetBits(GPIOD, GPIO_Pin_13); //Подаем «1» на PD13
else if(i==2) GPIO_SetBits(GPIOD, GPIO_Pin_14); //Подаем «1» на PD14
else if(i==3) GPIO_SetBits(GPIOD, GPIO_Pin_15); //Подаем «1» на PD15
else if(i==4)GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //Сбрасываем все пины в «0»
i++; //Наращиваем счетчик
if(i==5) i=0; //Если i=5, сбрасываем счетчик в «0»
}

Вот и все, теперь можно компилировать проект и прошивать плату. Проект CooCox прикреплен к статье.

Добавлю, что в теле таймера можно добавить обработку кнопок, реализовать временные задержки (если включить прерывание не раз в секунду а раз в миллисекунду) и многое другое. Основное требование – время выполнение кода в цикле таймера не должно превышать время его срабатывания.

На все вопросы отвечу в комментариях. Буду благодарен с пожеланиями тем для будущих уроков.

Прикрепленные файлы:

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

Ваш адрес email не будет опубликован.