测品娱乐
您的当前位置:首页STM32F103频率测量方法

STM32F103频率测量方法

来源:测品娱乐


频率测量可以用测周法和测频法:

1.测周法:通过一个方波的两个上升沿或下降沿触发中断,然后定时器计数,计数的总个数乘以计数单位时间即该方波的周期。实际程序如下:

void TIM3_Encoder_IN_Init(u16 arr,u16 psc)

{

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_ICInitTypeDef TIM_ICInitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_6|GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

//时钟配置

GPIO_Init(GPIOA,&GPIO_InitStructure);

TIM_TimeBaseStructure.TIM_Prescaler=psc; 100kHz,10us//56M//24M

//TIM时钟频率

//TIM_TimeBaseStructure.TIM_Period //ENCODER_TIM_PERIOD=(u16)(65000)

= ENCODER_TIM_PERIOD-1;

TIM_TimeBaseStructure.TIM_Period=arr; //测频范围在1.6Hz到100kHz

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //计数模式向上

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//定时器初始化

//通道1

TIM_ICInitStructure.TIM_Channel =TIM_Channel_1; //通道选择

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿触发

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //管脚与寄存器对应关系

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入预分频。意思是控制在多少个输入周期做一次捕获,如果

//输入的信号频率没有变,测得的周期也不会变。比如选择4分频,则每四个输入周期才做一次捕获,这样在输入信号变化不频繁的情况下,

//可以减少软件被不断中断的次数。

TIM_ICInitStructure.TIM_ICFilter = 0x0; 置,经历几个周期跳变认定波形稳定0x0~0xF

TIM_ICInit(TIM3, &TIM_ICInitStructure);

//通道2

TIM_ICInitStructure.TIM_Channel =TIM_Channel_2; 选择

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; 发

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 存器对应关系

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; 频。意思是控制在多少个输入周期做一次捕获,如果

//滤波设 //通道//上升沿触//管脚与寄//输入预分

//输入的信号频率没有变,测得的周期也不会变。比如选择4分频,则每四个输入周期才做一次捕获,这样在输入信号变化不频繁的情况下,

//可以减少软件被不断中断的次数。

TIM_ICInitStructure.TIM_ICFilter = 0x0; //滤波设置,经历几个周期跳变认定波形稳定0x0~0xF

TIM_ICInit(TIM3, &TIM_ICInitStructure);

NVIC_InitStructure.NVIC_IRQChannel = //NVIC配置

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); //打开中断

TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE); //打开中断

TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);

TIM3_IRQn;

TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

TIM_Cmd(TIM3, ENABLE); //定时器使能

}

void TIM3_IRQHandler(void)

{//PWM_IN2通道采集

if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)

{TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

count1++;

}

if(TIM_GetITStatus(TIM3,TIM_IT_CC1)!=RESET)//TIM3CH2

{

TIM_ClearITPendingBit(TIM3,TIM_IT_CC1);//清除中断标志

if(capture1_loop==0)

{TIM_ITConfig(TIM3, TIM_IT_Update,ENABLE);

Ic1readvalue1=TIM_GetCapture1(TIM3);//得到第一次计数值

capture1_loop=1;}

else{

if(capture1_loop==1)

{Ic1readvalue2=TIM_GetCapture1(TIM3);

TIM_ITConfig(TIM3, TIM_IT_Update,DISABLE);

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

ch1freq=100000/(65536*count1+Ic1readvalue2-Ic1readvalue1);

capture1_loop=0;

count1=0;

}

usRegInputBuf[17]=ch1freq;//PWM_IN2通道采集

}

}

实际测试结果是频率在600-1000HZ时,有其他的非频率数据,不准确。这里采用了定时器溢出中断来计算65535溢出的次数。

另外,还可以不采用溢出中断,直接比较计数值的大小来实现,程序如下:

void TIM3_IRQHandler(void)

{//PWM_IN2通道采集

if(TIM_GetITStatus(TIM3,TIM_IT_CC1)!=RESET)//TIM3CH2

{

TIM_ClearITPendingBit(TIM3,TIM_IT_CC1);//清除中断标志

if(capture1_loop==0)

{Ic1readvalue1=TIM_GetCapture1(TIM3);//得到第一次计数值

capture1_loop=1;}

else{

if(capture1_loop==1)

{Ic1readvalue2=TIM_GetCapture1(TIM3);

if(Ic1readvalue2>Ic1readvalue1)

{Capture1=(Ic1readvalue2-Ic1readvalue1);}

else{Capture1=((0XFFFF-Ic1readvalue1)+Ic1readvalue2);}

ch1freq=1000000/Capture1;//861HZ-21000HZ

capture1_loop=0;

}

usRegInputBuf[17]=ch1freq;//PWM_IN2通道采集

}

}

测试结果是频率在频率100-800HZ,有其他的非频率数据,不准确。

2.测频法:通过定时器定时1S,计算方波上升沿或者下降沿的个数,频率数据较准确,特别是高频信号测量准确,程序代码简单,程序如下:

void TIM3_IRQHandler(void)

{

if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) //定时器1S溢出

{TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除溢出标志位

usRegInputBuf[17]=count1; //PWM_IN2通道采集

usRegInputBuf[16]=count2; //PWM_IN1通道采集

count1=0;

count2=0;

}

if(TIM_GetITStatus(TIM3,TIM_IT_CC1)!=RESET)//TIM3CH2

{

TIM_ClearITPendingBit(TIM3,TIM_IT_CC1);//清除中断标志

count1++;

}

if(TIM_GetITStatus(TIM3,TIM_IT_CC2)!=RESET)//TIM3CH1

{

TIM_ClearITPendingBit(TIM3,TIM_IT_CC2);//清除中断标志

count2++;

}

}

因篇幅问题不能全部显示,请点此查看更多更全内容