STM32 Режим захвата.

STM32 Режим захвата.

Режим захвата — это особый режим работы таймера, суть которого в следующем, при изменении логического уровня на определённом выводе микроконтроллера, значение счётного регистра записывается в другой регистр, который именуют регистром захвата.

Для чего это надо?
С помощью этого режима можно измерить длительность импульса или период сигнала.

Режим захвата у STM32 обладает некоторыми особенностями:

  • возможность выбрать какой фронт будет активным
  • возможность изменить частоту входного сигнала с помощью предделителя (1,2,4,8)
  • каждый канал захвата оснащён встроенным входным фильтром
  • источником сигнала захвата может служить другой таймер
  • для каждого канала предусмотрено по два флага, первый выставляется если произошёл захват, второй если произошёл захват при установленном первом флаге


Для настройки режима захвата предназначены регистры CCMR1(для 1 и 2 канала) и CCMR2(для 3 и 4), а также регистры CCER, DIER.

Давайте рассмотрим подробнее битовые поля регистра CCMR2, отвечающие за настройку 4 канала таймера, именно его мы будем настраивать в примере. Ещё хотелось бы отметить, что в этом же регистре находятся битовые поля, которые используются при настройке таймера в режиме сравнения.
STM32 Режим захвата.

CC4S — определяет направление работы четвёртого канала(вход или выход). При настройке канала как вход сопоставляет ему сигнал захвата

  • 00 — канал работает как выход
  • 01 — канал работает как вход, сигнал захвата — TI4
  • 10 — канал работает как вход, сигнал захвата — TI3
  • 11 — канал работает как вход, сигнал захвата — TRC

IC4PSC – определяют коэффициент деления, для сигнала захвата

  • 00 — делитель не используется, сигнал захвата IC1PS формируется по каждому событию
  • 01 — сигнал захвата формируется по каждому второму событию
  • 10 — сигнал захвата формируется по каждому четвёртому событию
  • 11 — сигнал захвата формируется по каждому восьмому событию

IC4F — предназначен для настройки входного фильтра, кроме количества выборок, в течение которых микроконтроллер не будет реагировать на входные сигналы, также можно настроить частоту выборок. По сути мы настраиваем время задержки с момента прихода фронта до "подтверждающей" выборки.
STM32 Режим захвата.


Теперь давайте рассмотрим регистр CCER.
STM32 Режим захвата.

CC4E — включает/выключает режим захвата.
CC4P — определяет фронт по которому будет производиться захват, 0 — передний, 1 — задний.


И регистр DIER.
STM32 Режим захвата.

CC4DE — разрешает формировать запрос к DMA.
CC4IE — разрешает прерывание по захвату.


После того как произошёл захват формируется событие захвата, которое устанавливает соответствующий флаг. Это может привести к генерации прерывания и запросу DMA, если они разрешены в регистре DIER. Кроме того, событие захвата может быть сформировано программно, установкой битового поля в регистре генерации событий EGR:
STM32 Режим захвата.

Битовые поля CC1G, CC2G, CC3G и CC4G позволяют генерировать событие в соответствующем канале захвата/сравнения.

Кстати, CCR1, CCR2, CCR3 и CCR4 — регистры захвата, в которых сохраняется значение таймера по сигналу захвата.

Для того чтобы контролировать формирование сигнала захвата, в регистре SR для каждого канала выделено по два флага.
STM32 Режим захвата.

CC4IF — устанавливается когда формируется сигнал захвата, сбрасываются эти флаги программно или чтением соответствующего регистра захвата/сравнения.
CC4OF — устанавливается если флаг CC4IF не был очищен, а пришёл очередной сигнал захвата. Этот флаг очищается программно записью нуля.

Теперь давайте применим полученные знания на практике, с генератора сигналов на вход TIM5_CH4 подадим синусоиду с частотой 50Гц и попробуем измерить её период. Для того чтобы ускорить процесс предлагаю использовать DMA. Какой вывод МК соответствует 4 каналу TIM5 можно найти в даташите на МК в разделе Pinouts and pin description.
STM32 Режим захвата.


Для DMA необходим адрес регистра CCR4, вот как его найти. Открываем RM0008 и в таблице Register boundary addresses находим начальный адрес TIM5.
STM32 Режим захвата.

смещение для регистра CCR4 можно найти в том же документе в разделе register map.
STM32 Режим захвата.



#include "stm32f10x.h" 

#define TIM5_CCR4_Address    ((u32)0x40000C00+0x40)
#define DMA_BUFF_SIZE 				2				

uint16_t buff[DMA_BUFF_SIZE];//Буфер
uint16_t volatile T;

void DMA2_Channel1_IRQHandler (void) 
{
	T = (buff[1] > buff[0]) ? (buff[1] - buff[0]) : (65535+ buff[1] - buff[0]);
	
  DMA2->IFCR |= DMA_IFCR_CGIF1;
}	


void Init_DMA(void)
{
	RCC->AHBENR |= RCC_AHBENR_DMA2EN; //Разрешаем тактирование первого DMA модуля
	DMA2_Channel1->CPAR = TIM5_CCR4_Address; //Указываем адрес периферии - регистр результата преобразования АЦП для регулярных каналов
	DMA2_Channel1->CMAR = (uint32_t)buff; //Задаем адрес памяти - базовый адрес массива в RAM
	DMA2_Channel1->CCR &= ~DMA_CCR1_DIR; //Указываем направление передачи данных, из периферии в память
	DMA2_Channel1->CNDTR = DMA_BUFF_SIZE; //Количество пересылаемых значений
	DMA2_Channel1->CCR &= ~DMA_CCR1_PINC; //Адрес периферии не инкрементируем после каждой пересылки
	DMA2_Channel1->CCR |= DMA_CCR1_MINC; //Адрес памяти инкрементируем после каждой пересылки.
	DMA2_Channel1->CCR |= DMA_CCR1_PSIZE_0; //Размерность данных периферии - 16 бит
	DMA2_Channel1->CCR |= DMA_CCR1_MSIZE_0; //Размерность данных памяти - 16 бит
	DMA2_Channel1->CCR |= DMA_CCR1_PL; //Приоритет - очень высокий 
	DMA2_Channel1->CCR |= DMA_CCR1_CIRC; //Разрешаем работу DMA в циклическом режиме
	DMA2_Channel1->CCR |= DMA_CCR1_TCIE;//Разрешаем прерывание по окончанию передачи
	DMA2_Channel1->CCR |= DMA_CCR1_EN; //Разрешаем работу 1-го канала DMA
}

int main(void)
{
   Init_DMA();
  //включаем тактирование порта А, альтернативных функций и таймера
  RCC->APB2ENR |=	RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
  RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; 
	
  TIM5->PSC = 56000-1;//новая частота 1Khz

  TIM5->CCMR2 |= TIM_CCMR2_CC4S_0;//выбираем TI4 для TIM5_CH4
  TIM5->CCMR2 &= ~(TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC);//не фильтруем и делитель не используем
	
  TIM5->CCER &= ~TIM_CCER_CC4P;//выбираем захват по переднему фронту
  TIM5->CCER |= TIM_CCER_CC4E;//включаем режим захвата для 4-го канала         

  TIM5->DIER |= TIM_DIER_CC4DE;//разрешаем формировать запрос к DMA
  //TIM5->DIER |= TIM_DIER_CC4IE; //разрешаем прерывание по захвату
	
  TIM5->CR1 |= TIM_CR1_CEN; //включаем счётчик
	
  //NVIC->ISER[1] |= NVIC_ISER_SETENA_18; //TIM5 Interrupt
  NVIC->ISER[1] |= NVIC_ISER_SETENA_24;   //DMA Interrupt
	
  while(1)
	{
	
	}

}

STM32 Режим захвата.

На скриншоте видно, что период сигнала равен 20мс, что соответствует действительности. В следующей статье опишу, как измерить частоту сигнала.
Похожие статьи
комментарии
6