PROGCONT.RU

Форма входа







Регистрация Вход/

Пример Пример Пример


STM32 HAL SysTick(System timer) как устроен, настройка и управление.

System timer или в простонародье SysTick, системный таймер практически как базовый периферийный таймер имеющий только основу и наделен простой функцией отсчёт импульсов также генерирует прерывание.

NO

Системный таймер как и основная периферия тактируется от AHB шины, на входе имеет предделитель который может иметь два значения это входной сигнал делится на 1 и на 8(STM32F101-107). Состоит из регистра перегрузки(Reload registers) и самого счётчика(Counter registers).

Принцип работы такой же как у любого базового таймера(таймер только с базовыми функциями), регистр Counter(счетчик) считает входящие импульсы до значение которое записано в регистре Reload( регистр перегрузки) после сбрасывается и генерируется прерывание если включено, после начинается отсчёт заново.

Настройка таймера осуществляется после выполнения функции HAL_InitTick которая выполняется в функции HAL_Init(), если код программы сгенерирован в STM32CubeMX то функция задержки HAL_Delay будет работать корректно иначе вам самим придется корректировать некоторые параметры.


Функции настройки системного таймера.

void HAL_Delay(uint32_t Delay)- функция которая использует SysTick для своих нужд, предназначена для созданий пауз в программе.

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)- функция настраивает SysTick и включает его прерывание.

void HAL_SuspendTick(void)- функция отключает прерывание SysTick.

void HAL_ResumeTick(void)- функция включает прерывание SysTick.

HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)-Функция изменяет частоту срабатывания прерывания от SysTick.

SET_BIT(REG, BIT)- функция напрямую настраивает регистр SysTick_CTRL, устанавливая нужные биты.

CLEAR_BIT(REG, BIT)- функция напрямую настраивает регистр SysTick_CTRL, сбрасывает нужные биты.

WRITE_REG(REG, VAL)- Функция записывает новое значение в регистры Reload_Value и Counter.

READ_REG(REG)- функция читает данные из регистра Reload_Value и Counter.


Функция включает в коде программы задержку минимальное значение которой миллисекунда, используется функция. совместно с SysTick

void HAL_Delay(uint32_t Delay); Принимаемое значение от 1 миллисекунды до зависит от частоты /*Пример настройки задержки 1 секунда*/ HAL_Delay(1000);


Функция настраивает автоматически SysTick включает таймер и его прерывание, если настройку используете сами без STM32CubeMX то придется корректировать значение переменной библиотеки HAL SystemCoreClock( частота работы AHB шины или контроллера если предделитель AHB=1).

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority); Функция принимает приоритет прерывания для SysTick Если установлена 4 группа для прерываний функцией HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); То значение может быть от 0 до 15, устанавливается обычно 15 /*Пример настройки*/ SystemCoreClock = 8000000; HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); HAL_InitTick(15);


Функция отключает прерывание от SysTick тем самым прекращает работу прерываний таймера, функция HAL_Delay работать больше не будет.

void HAL_SuspendTick(void); /*Пример использования*/ HAL_SuspendTick();


Функция включает прерывание от SysTick тем самым возобновляет работу прерываний таймера, функцию HAL_Delay можно использовать. Данная функция используется если отключался таймер функцией HAL_SuspendTick().

void HAL_ResumeTick(void); /*Пример использования*/ HAL_ResumeTick();


Функция изменяет частоту срабатывания прерывания от SysTick, по умолчанию таймер настроен на частоту 1KHz для отработки задержки от функции HAL_Delay в 1 миллисекунду. Перед использование данной функции измените значение переменной библиотеки HAL uwTickPrio = 15; которая устанавливает приоритет прерывания.

HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq); Функция принимает значение частоты в KHz /*Пример настройки на частоту 1KHz*/ uwTickPrio = 15; HAL_SetTickFreq(1);


Функция которая устанавливает биты управления в регистре контроля SysTick.

SET_BIT(REG, BIT); Функция принимает два параметра: регистр контроля SysTick->CTRL и маски для управления SysTick_CTRL_CLKSOURCE_Msk-установит предделитель таймера в 1 SysTick_CTRL_TICKINT_Msk-включает прерывание SysTick_CTRL_ENABLE_Msk-включает таймер /*Пример*/ SET_BIT( SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);


Функция которая сбрасывает биты управления в регистре контроля SysTick.

CLEAR_BIT(REG, BIT); Функция принимает два параметра: регистр контроля SysTick->CTRL и маски для управления SysTick_CTRL_CLKSOURCE_Msk-установит предделитель таймера в 8 SysTick_CTRL_TICKINT_Msk-отключает прерывание SysTick_CTRL_ENABLE_Msk-отключает таймер /*Пример*/ CLEAR_BIT( SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);


Функция записывает новое значение в регистры Reload_Value и Counter.

WRITE_REG(REG, VAL); Функция принимает регистр REG это SysTick->LOAD-Reload Value( регистр перегрузки регистра счётчика) SysTick->VAL-Current Value( регистр счётчик) и второй параметр который принимает функция это значение VAL которое может быть от 0 до 16777215 /*Пример*/ WRITE_REG( SysTick->LOAD, 10000);


Функция читает значение из регистров Reload_Value и Counter.

READ_REG(REG); Функция принимает регистр REG это SysTick->LOAD-Reload Value( регистр перегрузки регистра счётчика) SysTick->VAL-Current Value( регистр счётчик) Возвращает значение нужного регистра /*Пример*/ uint32_t val = READ_REG(SysTick->VAL);


Прерывание SysTick как настроить.

В файле stm32f1xx_it.c вставлен функция обработки прерывания, которую можно переместить в тело вашей программы для удобства, но не забудьте тогда удалить в файле stm32f1xx_it.c.

NO

Прерывание не нужно включать в NVIC регистре просто необходимо дать приоритет данному прерыванию функцией описанной выше.


Пример программы.

В примере кода показано как самому настроить SysTick самостоятельно или использовать функцию HAL_Init() или HAL_InitTick(15U).

/*ProgCont.ru*/ #include "main.h" uint32_t count; int main(void) { // HAL_Init(); // HAL_InitTick(15U); SystemCoreClock = 8000000;//Частота контроллера uwTickFreq = 1;//Задержка в миллисекундах count = SystemCoreClock / (1000U / uwTickFreq);//Значение для регистра Reload WRITE_REG( SysTick->LOAD, count); HAL_NVIC_SetPriority(SysTick_IRQn, 15U, 0U); SET_BIT( SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk);//Устанавливаем предделитель в 1 SET_BIT( SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);//Включаем прерывание SET_BIT( SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//Включаем таймер __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_NVIC_DisableIRQ(SysTick_IRQn); while (1) { HAL_GPIO_TogglePin( GPIOC, GPIO_PIN_13); HAL_Delay(500); } } void SysTick_Handler(void) { HAL_IncTick();//Внутрения функция HAL_Delay } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line){} #endif /* USE_FULL_ASSERT */




Комментариев нет  Только зарегистрированные пользователи могут оставлять комментарии!