В микроконтроллерах 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