В микроконтроллерах STM32 существует системный таймер Systick, который является 24-х разрядным дектементируемым счетчиком. Этот таймер затактирован системной тактовой частотой SYSCLK/8.
Данный таймер умеет выходить в функцию прерывания (генерировать прерывание) в заданным промежутком времени. Используются при работе с RTOS с высоком приоритетом.
Работает он следующим образом: после настройки его в определенное значение и старта программы происходит обратный отсчет до нуля, после чего генерируется прерывание и процесс продолжается заново.
Пример настройки Systick в среде разработке Keil Uvision5.
#include "stm32f10x.h"
static __IO uint32_t TimingDelay;
void Delay_ms(__IO uint32_t nTime);
GPIO_InitTypeDef GPIO_InitStruct;
int main()
{
/*Вызов функции конфигурации системного таймера SysTick.
Эта функция находится в файле core_cm3.h и:
--Задает источник тактирования системного таймера (по умолчанию это SYSCLK = 24 МГц,
другой возможный вариант - SysTick тактируется от SYSCLK/8);
--Задает уровень приоритета прерывания;
--Сбрасывает флаг ожидания прерывания, если он выставлен;
--Заносит в нужный регистр перезагружаемое значение для декрементирующего счетчика,
которое вычисляется по формуле:
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s),
для базовой задержки длительностью 1 мс получим величину
Reload Value = 24 000 000 Гц х 0,001 с = 24 000
(Необходимо самостоятельно посчитать эту величину и вставить в качестве
параметра при вызове функции);
--Обнуляет счетчик
--Запускает счет системного таймера*/
SysTick_Config(24000);
//Включаем тактирование порта GPIOC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
//Конфигурируем выводы, к которым подключены светодиоды платы
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //Выбираем выводы PC8, PC9
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //Максимальная скорость работы
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //Выход Push-Pull
GPIO_Init(GPIOC, &GPIO_InitStruct); //Заносим заданные настройки в регистры порта
while(1)
{
GPIO_ResetBits(GPIOC, GPIO_Pin_9); //Гасим зеленый LED
GPIO_SetBits(GPIOC, GPIO_Pin_8); //Зажигаем синий LED
Delay_ms(1000); //Временная задержка на 1 с
GPIO_ResetBits(GPIOC, GPIO_Pin_8); //Гасим синий LED
GPIO_SetBits(GPIOC, GPIO_Pin_9); //Зажигаем зеленый LED
Delay_ms(1000); //Временная задержка на 1 с
}
}
//Функция временной задержки
void Delay_ms(__IO uint32_t nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
//Обработчик прерывания системного таймера
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}
Настройка временного интервала осуществляется при помощи функции
SysTick_Config(24000);
Где 24000 количество "тиков" который совершит таймер, при частоте в 24 МГц, таймер протикает это значения за 24000/24МГц = 0,001с или 1 миллисекунду.
С периодом в 1 мс наш таймер будет выходить в обработчик прерываний, в котором мы также как и таймер декрементируем значение переменное TimingDelay равное 1000мс.
Видеоурок настройки таймера SysTick