- Лоботрясы

Поиск
Перейти к контенту

Главное меню:

Статьи по STM32

Читать в Яндекс.Подписках



    STM32. Таймеры общего назначения на микроконтроллерах Cortex-M0. Часть 3
Просмотров: 6270
     Обзор библиотеки TIM среды CooCox.

     Можно не заморачиваться прямым доступом к регистрам таймеров, рассмотренным в предыдущей части, можно воспользоваться уже готовыми функциями, предложенными в Репозитории! Для работы с таймерами в программе CooCox, в Репозитории (Repository) нужно выбрать в предлагаемых библиотеках периферии библиотеку TIM, после чего в ваш проект автоматически подключатся два файла библиотеки – stm32f0xx_tim.и stm32f0xx_tim.c, работу с которыми сейчас подробно и рассмотрим (правда, из-за обилия функций, рассмотрим только те, которые применимы к данной части небольшого цикла статей)!
     Данные библиотеки позволяют особо не думать о куче регистров управления, т.к. дают пользователю быструю и удобную возможность выполнить нужные настройки таймера. Правда, перед тем как перейти к рассмотрению библиотечных функций, нужно узнать, как через них будет осуществляться настройка регистров таймеров.
     В начале программы пользователь должен создать структуру по типу (шаблону) TIM_TimeBaseInitTypeDef, через которую и будут передаваться необходимые для установки параметры (значение делителя, режим счёта и т.д.) в библиотечные функции, а там уже – записываться непосредственно в регистры.
     Сам шаблон структуры имеет такой вид:
 
typedef struct 
  uint16_t  TIM_Prescaler/* Указывается значение предделителя, используемое для деления тактовой частоты таймера TIM. Этот параметр может содержать число между 0x0000 и 0xFFFF */
  uint16_t  TIM_CounterMode/* Указывается режим счётчика. Этот параметр может принимать следующие значения: TIM_CounterMode_Up – направление вверх, TIM_CounterMode_Down – направление вниз, есть ещё TIM_CounterMode_CenterAligned1, TIM_CounterMode_CenterAligned2 и TIM_CounterMode_CenterAligned3, но это – отдельная история… */
  uint32_t  TIM_Period/* Указывается значение для загрузки в регистр ARR */
  uint16_t  TIM_ClockDivision/* Указывается деление тактового сигнала (clock division). Этот параметр может принимать следующие значения: TIM_CKD_DIV1TIM_CKD_DIVи TIM_CKD_DIV(смотрите настройки бита CKD в регистре TIMx_CR1). Этот параметр важен при тактировании таймера от внешнего входа и от входа внешнего тактирования, поэтому пока он нам не особо интересен… */
  uint8_t  TIM_RepetitionCounter/* Задаётся значение счётчика повторений. Каждый раз, когда декрементный счётчик RCR достигает нуля, генерируется событие обновления и отсчёт перезапускается со значения в регистре RCR (N). Этот параметр нужен только для работы расширенного таймера TIM1, поэтому рассматриваться пока не будет :-( */
}  TIM_TimeBaseInitTypeDef
 
     Библиотека достаточна обширна, и охватывает помимо простейших настроек таймера также и режимы захвата/сравнения. Сейчас рассмотрим только режим обычной работы таймера.
void TIM_DeInit (TIM_TypeDef *  TIMx) – Сброс регистров периферии TIMx к их значениям по умолчанию, а попросту – отключение таймера (где x – номер таймера);
 
void TIM_TimeBaseInit (TIM_TypeDef *  TIMx, TIM_TimeBaseInitTypeDef *  TIM_TimeBaseInitStruct) – Инициализация периферии TIMx в соответствии с заданными параметрами, указанными в TIM_TimeBaseInitStruct (в функции объявляется указатель TIM_TimeBaseInitStruct на структуру типа TIM_TimeBaseInitTypeDef);
 
     Инициализация данной структуры значениями по умолчанию происходит вызовом функции
void TIM_TimeBaseStructInit (TIM_TimeBaseInitTypeDef *   TIM_TimeBaseInitStruct)
По умолчанию значения составляют:
TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF;
TIM_TimeBaseInitStruct-> TIM_Prescaler = 0x0000; // Без предделителя
TIM_TimeBaseInitStruct-> TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct-> TIM_CounterMode = TIM_CounterMode_Up; // Счёт вверх
TIM_TimeBaseInitStruct-> TIM_RepetitionCounter = 0x0000;
 
void TIM_PrescalerConfig (TIM_TypeDef*  TIMx, uint16_t   Prescaler, uint16_t   TIM_PSCReloadMode) – Функция установки значения предделителя (число между 0x0000 и 0xFFFF (0 … 65536)). Это число передается параметру Prescaler, а TIM_PSCReloadMode отвечает за режим загрузки передаваемого нового значения предделителя: или оно будет установлено по событию обновления UEV таймера (нужно передать функции параметр TIM_PSCReloadMode_Update), или же значение Prescaler будет загружено незамедлительно (параметр TIM_PSCReloadMode_Immediate);
 
void TIM_CounterModeConfig (TIM_TypeDef *   TIMx, uint16_t    TIM_CounterMode) – Установка режима счётчика (через аргумент TIM_CounterMode). Из пяти возможных значений для нас интерес представляют пока что два: TIM_CounterMode_Up – режим счета вверх и TIM Down Counting Mode – режим счёта вниз;
 
void TIM_SetCounter (TIM_TypeDef *   TIMx, uint32_t   Counter) – Установка значения счётного регистра TIMx_CNT (через аргумент Counter), а попросту – операция TIMx->CNT = Counter;
 
void TIM_SetAutoreload (TIM_TypeDef *  TIMx, uint32_t    Autoreload) – Обновление регистра автоперезагрузки TIMx_ARR, функция содержит операцию TIMx->ARR = Autoreload;
 
uint32_t  TIM_GetCounter (TIM_TypeDef *  TIMx) – Получение текущего значения счётного регистра (а попросту функция возвращает TIMx->CNT);
 
uint16_t  TIM_GetPrescaler (TIM_TypeDef *  TIMx) – Получение текущего значения регистра предделителя TIMx_PSC (а попросту возврат TIMx->PSC);
 
void TIM_UpdateDisableConfig (TIM_TypeDef *  TIMx, FunctionalState   NewState) – Разрешение (или запрет) генерации события обновления UEV. Параметру NewState можно передать значения ENABLE или DISABLE (если забыли – по умолчанию генерация UEVразрешена!);
 
void TIM_UpdateRequestConfig (TIM_TypeDef *  TIMx, uint16_t   TIM_UpdateSource) – Настройка источника запроса обновления (выбор источника события UEV). Если параметру TIM_UpdateSource передать значение TIM_UpdateSource_Regular, то источником генерации UEV может быть переполнение/обнуление счётчика, установка бита UG регистра TIMx_EGR а также генерация обновления контроллером в подчинённом режиме. Если передать параметр TIM_UpdateSource_Global, то источником обновления является только переполнение/обнуление счётчика;
 
void TIM_ARRPreloadConfig (TIM_TypeDef *  TIMx, FunctionalState   NewState) – Включение/выключение предварительной загрузки в регистр TIMx_ARR (манипуляции с битом APRE). Параметру NewState можно передать значения ENABLE или DISABLE;
 
void TIM_Cmd (TIM_TypeDef *  TIMx, FunctionalState   NewState) – Разрешение/запрет тактирования счетчика. Параметру NewState можно передать значения ENABLE или DISABLE;
 
void TIM_ITConfig (TIM_TypeDef *  TIMx, uint16_t   TIM_IT, FunctionalState   NewState) – Включение/выключение указанных прерываний (происходит конфигурация регистра разрешения прерываний TIMx_DIER). Параметр TIM_IT может принимать 8 значений, но нас пока интересует прерывание по обновлению - TIM_IT_Update. Параметру NewState можно передать значения ENABLE или DISABLE;
 
void TIM_GenerateEvent (TIM_TypeDef *  TIMx, uint16_t   TIM_EventSource) – Установка событий таймера, генерируемых программно. Параметр TIM_EventSource может принимать 8 значений (этой функцией конфигурируется регистр генерации событий TIMx_EGR), но наш интерес пока вызывает только программная генерация обновления UEV IM_EventSource_Update (установкой бита UG);
 
FlagStatus  TIM_GetFlagStatus (TIM_TypeDef *  TIMx, uint16_t   TIM_FLAG) – Функция проверяет, установлен ли интересующий нас флаг или нет. Имеется возможность проверять до 12 флагов (битов) регистра статуса TIMx_SR. Для проверки флага прерывания по событию обновления UIF нужно передать параметру TIM_FLAG значение TIM_FLAG_Update. В случае установки флага, функция вернёт SET (иначе – RESET);
 
void TIM_ClearFlag (TIM_TypeDef *   TIMx, uint16_t   TIM_FLAG) – Очистка выбранных флагов. Для сброса флага прерывания по обновлению UIF, параметру TIM_FLAG нужно передать значение TIM_FLAG_Update;
 
ITStatus  TIM_GetITStatus (TIM_TypeDef*   TIMx, uint16_t   TIM_IT) – Функция проверяет, произошло прерывание или нет. В качестве параметра TIM_IT могут быть переданы 8 значений, но для проверки прерывания по обновлению нужно передать TIM_IT_Update. Функция возвращает значения RESET и SET.
     Пример работы с этими функциями (пример инициализации таймера TIM2 из предыдущей части):
TIM_TimeBaseInitTypeDef   TIM_TimeBaseStruct; // Объявляем структуру по шаблону
  
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //Включение тактирования таймера TIM2 (подключение к системе тактирования)
 
//Конфигурация таймера
TIM_TimeBaseStruct.TIM_Period = 1000;
TIM_TimeBaseStruct.TIM_Prescaler = 0;
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
// Инициализация периферии таймера
TIM_TimeBaseInit (TIM2, &TIM_TimeBaseStruct);
 
// Устанавливаем новую конфигурацию предделителя (47999)
TIM_PrescalerConfig (TIM2, 48000-1, TIM_PSCReloadMode_Immediate);
// Включение прерывания от TIM2 
NVIC_EnableIRQ(TIM2_IRQn);
//Разрешение прерывания TIM2
TIM_ITConfig (TIM2, TIM_IT_UpdateENABLE); 
// Включение тактирования TIM2 
TIM_Cmd (TIM2, ENABLE);
 
 
// Обработчик прерывания для таймера:
void TIM2_IRQHandler (void)
{
     TIM_ClearFlag (TIM2, TIM_FLAG_Update); 
    
     что-то там важное и необходимое :-)
}
  
     Как видите, библиотечные функции достаточно замороченные, поэтому для простой настройки и работы таймера иногда проще работать с регистрами настройки напрямую! Но вот для работы с функциями захват/сравнение и генерации ШИМ, функционал библиотеки достаточно удобен, но его рассмотрю чуть позже, как буду подробно разбираться с данными режимами работы…

 
 
Назад к содержимому | Назад к главному меню