STM32 измерение частоты.

STM32 измерение частоты.

В одной из прошлых статей рассказывал про режим захвата у STM32 и приводил пример как с его помощью измерить период сигнала. Но таким способом не получится ТОЧНО измерить период высокочастотного сигнала.(дальше станет понятно какой сигнал считать высокочастотным)
Предположим, что частота исcледуемого сигнала 1MНz, а наш таймер работает с частотой 72MНz. Переведем значения частоты в период.

1MHz = 1/10^6 = 1 uS
72MHz = 1/72*10^6 = 0,0138 uS
Посчитаем сколько тактов сделает таймер за 1uS,
1/0,0138 = 72,46 такта
округлим до 73. Итого ошибка составляет 0,54 такта, что меньше 1 процента.

А теперь увеличим частоту исследуемого сигнала в 10 раз и произведем те же расчеты.
10MHz = 1/10^7 = 0.1 uS
72MHz = 1/72*10^6 = 0.0138 uS
Посчитаем сколько тактов сделает таймер за 1uS,
0,1/0,0138 = 7,246 такта
округлим до 8 тактов, теперь ошибка составляет почти 10%, то есть вместо 10МHz мы получим 11MHz.

Понятно, что такая точность ни куда не годится, а причина заключается в том, что мы измеряли длительность импульса, а для получения более точного результата надо измерять количество импульсов в секунду(то есть частоту) и потом вычислять период.

Количество импульсов в секунду можно получить двумя способами.

Первый способ в лоб, настраиваем один из выводов МК на внешнее прерывание(на который будет подаваться исследуемый сигнал) и запускаем таймер, который отсчитает одну секунду. При каждом попадании в прерывание увеличиваем значение переменной на единицу и через секунду мы получим частоту исследуемого сигнала.

Второй способ, реализуется с помощью вывода ETR(external trigger input). Тут все проще, достаточно правильно инициализировать этот вывод и он сам будет считать количество импульсов, по заданному фронту. Как его настроить опишу ниже.

STM32 измерение частоты.

Для начала надо настроить фильтр в регистре TIMx_SMCR, битовое поле ETF[3:0](N — количество событий)
STM32 измерение частоты.


В том же регистре установить значение предделителя
ETPS[1:0]: External trigger prescaler
  • 00 — выключен
  • 01 — на 2
  • 10 — на 4
  • 11 — на 8


Там же выбрать фронт срабатывания
ETP: External trigger polarity
  • 0 — возрастающий
  • 1 — убывающий


И настроить пин в режим ETR
  • ECE = 1

Включить таймер установив CEN = 1 в регистре CR1.

Так как регистр CNT 16-разрядный максимальная частота, которую мы можем измерить 65536 Hz. Я подал с генератора сигналов 50 КНz и запустил код, представленный ниже, на чипе STM32F103VE.

#include "stm32f10x.h"

volatile uint16_t tic = 0;

void TIM6_IRQHandler(void)
{
	TIM2->CR1 &= ~TIM_CR1_CEN;//останавливаем счет
	
	tic = TIM2->CNT;
	
	TIM2->CNT = 0;
	TIM6->CNT = 0;
	TIM6->SR &= ~TIM_SR_UIF; //сбрасываем флаг прерывания
	
	TIM2->CR1 |= TIM_CR1_CEN;//запускаем таймер
	TIM6->CR1 |= TIM_CR1_CEN;//запускаем таймер
}	

void ETR_Input_Init(void)
{
	// Тактирование  TIM2 и GPIOA, PA0 input-float
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
        RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
	
	//базовые настройки таймера ни кто не отменял
	TIM2->PSC = 1 - 1;
	TIM2->CNT = 0;
	TIM2->ARR = 60000 - 1;	
	TIM2->CR1 &= ~TIM_CR1_DIR;//считаем вверх
	
	TIM2->SMCR &= ~TIM_SMCR_ETF;//настраиваем фильтр
	TIM2->SMCR &= ~TIM_SMCR_ETPS;//предделитель 0
	TIM2->SMCR &= ~TIM_SMCR_ETP;//возрастающий
	TIM2->SMCR |= TIM_SMCR_ECE; //внешнее тактирование

}

void Tim6_Init(void)
{		
    RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
		
    TIM6->PSC  = 7200 -1;//новая частота = 10kHz
    TIM6->ARR  = 10000;//период = 1sec
    TIM6->CR1 &= ~TIM_CR1_DIR;//считаем вверх
    TIM6->CR1 |= TIM_CR1_OPM; //достчитав до конца таймер выключается  
    TIM6->DIER  |= TIM_DIER_UIE; //разрешить прерывания 
    NVIC->ISER[1] = NVIC_ISER_SETENA_22;
}

int main(void)
{
	ETR_Input_Init();
	Tim6_Init();
	
	TIM2->CR1 |= TIM_CR1_CEN;//запускаем таймер
	TIM6->CR1 |= TIM_CR1_CEN;//запускаем таймер
	
	while(1){}
}	 



Результат порадовал, скрин можно увеличить кликнув по нему.
STM32 измерение частоты.


А как же все таки измерить 10 MHz ?
Для этого надо использовать два таймера, один будет считать импульсы на выводе ETR, а второй считать сколько раз первый переполнился.
комментарии
0