PROGCONT.RU

Форма входа







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

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


STM32F101-107 HAL TIM2-TIM5 основа таймера и его настройка.


Схема для таймеров TIM2-TIM5.

NO


Для настройки таймера в режиме счётчика(тактов контроллера или времени) нам понадобятся его регистры которые выделены в схеме выше.

Это следующие регистры:

PSC prescaler-делитель входящих импульсов для счётчика CNT counter;

Auto-reload register-регистр отвечает за сброс регистра счетчика CNT counter;

CNT counter-основной регистр таймера или его счётчик.


Регистры настройки таймера.

__HAL_RCC_TIMx_CLK_ENABLE()- включение тактирования соответствующего таймера.

__HAL_RCC_TIMx_CLK_DISABLE()- выключение тактирования нужного таймера.

TIM_HandleTypeDef- структура для настройки таймера.

HAL_TIM_Base_Init( TIM_HandleTypeDef *htim)- функция настраивает нужный таймер.

HAL_TIM_Base_DeInit( TIM_HandleTypeDef *htim)- сброс настроек таймера.

HAL_TIM_Base_Start( TIM_HandleTypeDef *htim)-функция запускает таймер.

HAL_TIM_Base_Stop( TIM_HandleTypeDef *htim)-функция останавливает таймер.

__HAL_TIM_GET_FLAG( TIM_HandleTypeDef *htim, TIM_FLAG)-функция проверяет флаг прерывания.

__HAL_TIM_CLEAR_FLAG( TIM_HandleTypeDef *htim, TIM_FLAG)- функция сбрасывает флаг нужного прерывания.

__HAL_TIM_SET_AUTORELOAD( TIM_HandleTypeDef *htim, data)- функция изменяет значение регистра Auto-reload register.

__HAL_TIM_GET_AUTORELOAD( TIM_HandleTypeDef *htim)- функция читает значение из Auto-reload register.

__HAL_TIM_SET_PRESCALER( TIM_HandleTypeDef *htim, data)- функция изменяет предделитель таймера PSC prescaler.


Для активации нужного таймера необходимо включить его тактирование следующей функцией.

__HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_TIM3_CLK_ENABLE(); __HAL_RCC_TIM4_CLK_ENABLE(); __HAL_RCC_TIM5_CLK_ENABLE();


Для деактивации тактирования таймера необходимо выполнить следующие функции.

__HAL_RCC_TIM2_CLK_DISABLE() __HAL_RCC_TIM3_CLK_DISABLE() __HAL_RCC_TIM4_CLK_DISABLE() __HAL_RCC_TIM5_CLK_DISABLE()


Структура для настройки таймера

TIM_HandleTypeDef; Настраиваемые параметры структуры: /*Выбор нужного таймера для настройки*/ .Instance = TIM2 TIM3 TIM4 TIM5 /*Настройка перезаписи Auto-reload register*/ .Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE изменение значения Auto-reload register напрямую TIM_AUTORELOAD_PRELOAD_ENABLE перезапись значения Auto-reload register происходит через его теневой регистр, будет изменён только после сброса CNT counter(сброс происходит когда CNT counter равен Auto-reload register) /*Делитель для входных фильтров ETR и TIx входов, в ШИМ режиме не используется*/ .Init.ClockDivision = TIM_CLOCKDIVISION_DIV1 TIM_CLOCKDIVISION_DIV2 TIM_CLOCKDIVISION_DIV4 /*Режимы работы CNT counter*/ .Init.CounterMode = TIM_COUNTERMODE_UP счёт ведется от 0 до 65535 или до значения в Auto-reload register потом сброс в 0 TIM_COUNTERMODE_DOWN счёт ведётся от 65535 до 0 или до значения в Auto-reload register потом сброс в 65535 TIM_COUNTERMODE_CENTERALIGNED1 счёт ведётся от 0 до значения в Auto-reload register потом от значения в Auto-reload register до 0 и так по кругу, прерывание срабатывает при отсчёте в низ TIM_COUNTERMODE_CENTERALIGNED2 тоже, что предыдущий только прерывание срабатывает при отсчёте вверх TIM_COUNTERMODE_CENTERALIGNED3 тоже, что предыдущий только прерывание срабатывает при отсчёте вниз и вверх /*Период или значение в Auto-reload register, CNT counter сбрасывается доходя до этого значения*/ .Init.Period = значение от 0 до 65535 /*Предделитель таймера, делит входные импульсы*/ .Init.Prescaler = значение от 0 до 65535 /*Делитель для прерывания от сброса CNT counter(сброс происходит когда CNT counter равен Auto-reload register)*/ .Init.RepetitionCounter = значение от 0 до 255 возможно 65535 в зависимости от таймера /*Пример настройки*/ TIM_HandleTypeDef TIM2_InitStruct; TIM2_InitStruct.Instance = TIM2; TIM2_InitStruct.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; TIM2_InitStruct.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TIM2_InitStruct.Init.CounterMode = TIM_COUNTERMODE_UP; TIM2_InitStruct.Init.Period = 65535; TIM2_InitStruct.Init.Prescaler = 20; TIM2_InitStruct.Init.RepetitionCounter = 0;


Функция настраивает нужный таймер.

HAL_TIM_Base_Init(TIM_HandleTypeDef *htim); /*Функция принимает структуру для настройки таймера*/ /*Пример настройки*/ HAL_TIM_Base_Init( &TIM2_InitStruct);


Функция сбрасывает настройки таймера.

HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim); /*Функция принимает структуру для настройки таймера*/ /*Пример использования*/ HAL_TIM_Base_DeInit( &TIM2_InitStruct);


Функция включает нужный таймер.

HAL_TIM_Base_Start(TIM_HandleTypeDef *htim); /*Функция принимает структуру для настройки таймера*/ /*Пример*/ HAL_TIM_Base_Start( &TIM2_InitStruct);


Функция отключает нужный таймер.

HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim); /*Функция принимает структуру для настройки таймера*/ /*Пример*/ HAL_TIM_Base_Stop( &TIM2_InitStruct);


Функция проверяет состояние флага нужного прерывания, если прерывание было то функция вернёт SET или в противном случае RESET.

__HAL_TIM_GET_FLAG( TIM_HandleTypeDef *htim, TIM_FLAG); /*Функция принимает структуру для настройки таймера*/ TIM_HandleTypeDef *htim /*И название проверяемого флага*/ TIM_FLAG_UPDATE Update TIM_FLAG_CC1 Capture/Compare 1 TIM_FLAG_CC2 Capture/Compare 2 TIM_FLAG_CC3 Capture/Compare 3 TIM_FLAG_CC4 Capture/Compare 4 TIM_FLAG_COM Commutation TIM_FLAG_TRIGGER Trigger TIM_FLAG_BREAK Break TIM_FLAG_CC1OF Capture/Compare 1 TIM_FLAG_CC2OF Capture/Compare 2 TIM_FLAG_CC3OF Capture/Compare 3 TIM_FLAG_CC4OF Capture/Compare 4 /*Пример*/ if(__HAL_TIM_GET_FLAG( &TIM2_InitStruct, TIM_IT_UPDATE) != RESET){}


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

__HAL_TIM_CLEAR_FLAG( TIM_HandleTypeDef *htim, TIM_FLAG); /*Функция принимает структуру для настройки таймера*/ TIM_HandleTypeDef *htim /*И название проверяемого флага*/ TIM_FLAG_UPDATE Update TIM_FLAG_CC1 Capture/Compare 1 TIM_FLAG_CC2 Capture/Compare 2 TIM_FLAG_CC3 Capture/Compare 3 TIM_FLAG_CC4 Capture/Compare 4 TIM_FLAG_COM Commutation TIM_FLAG_TRIGGER Trigger TIM_FLAG_BREAK Break TIM_FLAG_CC1OF Capture/Compare 1 TIM_FLAG_CC2OF Capture/Compare 2 TIM_FLAG_CC3OF Capture/Compare 3 TIM_FLAG_CC4OF Capture/Compare 4 /*Пимер*/ __HAL_TIM_CLEAR_FLAG( &TIM2_InitStruct, TIM_IT_UPDATE);


Функция переписывает значения регистра Auto-reload register который отвечает за период и заставляет сбрасываться CNT counter.

__HAL_TIM_SET_AUTORELOAD(TIM_HandleTypeDef *htim, data); /*Функция принимает структуру настройки таймера*/ TIM_HandleTypeDef *htim /*И значение*/ от 0 до 65535 /*Пример*/ __HAL_TIM_SET_AUTORELOAD( &TIM2_InitStruct, 1000);


Функция читает значение из регистра Auto-reload register и возвращает его.

__HAL_TIM_GET_AUTORELOAD( TIM_HandleTypeDef *htim); /*Функция принимает структуру настройки таймера*/ TIM_HandleTypeDef *htim /*Пример*/ uint16_t DataARR = __HAL_TIM_GET_AUTORELOAD( &TIM2_InitStruct);


Функция изменяет значение предделителя таймера PSC prescaler.

__HAL_TIM_SET_PRESCALER( TIM_HandleTypeDef *htim, data); /*Функция принимает структуру настройки таймера*/ TIM_HandleTypeDef *htim /*И значение*/ от 0 до 65535 /*Пример*/ __HAL_TIM_SET_PRESCALER( &TIM2_InitStruct, 20);

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

Настраиваем таймер(TIM2) и в коде проверяем переполнение его счётчика через флаг прерывания TIM_FLAG_UPDATE, если было переполнение то сбрасываем флаг и изменяем состояние вывода порта GPIOC вывод 13 на противоположное.

/*ProgCont.ru*/ #include "main.h" int main(void) { HAL_Init(); /*Настраиваем вывод для контроля, подключен светодиод*/ __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.Speed = GPIO_SPEED_FREQ_MEDIUM; HAL_GPIO_Init( GPIOC, &GPIO_InitStruct); /*Настраиваем таймер*/ __HAL_RCC_TIM2_CLK_ENABLE(); TIM_HandleTypeDef TIM2_InitStruct; TIM2_InitStruct.Instance = TIM2; TIM2_InitStruct.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; TIM2_InitStruct.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TIM2_InitStruct.Init.CounterMode = TIM_COUNTERMODE_UP; TIM2_InitStruct.Init.Period = 65535; TIM2_InitStruct.Init.Prescaler = 20; TIM2_InitStruct.Init.RepetitionCounter = 0; HAL_TIM_Base_Init( &TIM2_InitStruct); HAL_TIM_Base_Start( &TIM2_InitStruct); /*Проверяем флаг и меняем состояние вывода*/ while (1){ if(__HAL_TIM_GET_FLAG( &TIM2_InitStruct, TIM_IT_UPDATE) != RESET){ __HAL_TIM_CLEAR_FLAG( &TIM2_InitStruct, TIM_IT_UPDATE); HAL_GPIO_TogglePin( GPIOC, GPIO_PIN_13); } } } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line){} #endif /* USE_FULL_ASSERT */

Тут показана работа основы таймера или его счетчика(CNT counter) и регистра сравнения(Auto-reload register) который ограничивает счётчик и заставляет его сбрасываться.

Можете по экспериментировать с регистрами с помощью функций __HAL_TIM_SET_AUTORELOAD(TIM_HandleTypeDef *htim, data) и __HAL_TIM_SET_PRESCALER( TIM_HandleTypeDef *htim, data) которые буду изменять время периода таймера и соответственно время изменения состояния вывода.




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