STM32测频法详解:频率测量技术与实现
作为纯新手在跟随江协学习单片机的过程中,到使用输入捕获测量频率时,对测频法只是讲了原理,并未展示相关代码。到这里检索后也只看到了视频中展示的测周法测频率。故在这里对相应代码进行补充,供大家交流讨论。
对于测频法原理详细可见@江协科技
这里直接展示代码部分
TIM2(定一个1s的频率,执行中断,读取频率后,清0计数)
#include "stm32f10x.h" // Device header
extern uint16_t Freq_Count; //来源于sensor,(没有改名字了)
uint16_t Freq_count;
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period =10000-1;//都要在0-65535之间(记录一万次)
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;//这是计数频率
TIM_TimeBaseInitStructure.TIM_RepetitionCounter =0;//高级计数器才用,不用直接0
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM2,TIM_FLAG_Update );
TIM_ITConfig(TIM2,TIM_IT_Update ,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2 );
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel =TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority =1;
NVIC_Init (&NVIC_InitStruct);
TIM_Cmd(TIM2,ENABLE);
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
Freq_count=Freq_Count;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
Freq_Count =0;
}
}
uint16_t Timer_Get(void)
{
return Freq_count;
}
也是让自己输出自己测(TIM2被占用故选择TIM3输出PWM)
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//这里进行重映射试一下
//
// GPIO_PinRemapConfig (GPIO_PartialRemap1_TIM2 ,ENABLE);//这里映射到了PIN15,但有其他复用,需要关闭
// GPIO_PinRemapConfig (GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure. GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure. GPIO_Pin = GPIO_Pin_6;//Pin15
GPIO_InitStructure. GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA ,&GPIO_InitStructure );
TIM_InternalClockConfig(TIM3);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period =100-1;//都要在0-65535之间(记录一万次)ARR
TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;//这是计数频率PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter =0;//高级计数器才用,不用直接0
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructre;
TIM_OCStructInit(&TIM_OCInitStructre);
TIM_OCInitStructre.TIM_OCMode =TIM_OCMode_PWM1 ;//输出比较模式,冻结模式,置有效电平。
TIM_OCInitStructre.TIM_OCNPolarity =TIM_OCPolarity_High;//输出比较极性,有效电平是高电平
TIM_OCInitStructre.TIM_OutputState = TIM_OutputState_Enable ;//输出状态,输出使能
TIM_OCInitStructre.TIM_Pulse =50;//用来设置CCR寄存器的值的
TIM_OC1Init(TIM3 ,&TIM_OCInitStructre);
TIM_Cmd(TIM3,ENABLE);
}
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(TIM3,Compare);
}
void PWM_SetPrescaler(uint16_t Prescaler)
{
TIM_PrescalerConfig(TIM3,Prescaler,TIM_PSCReloadMode_Immediate);
}
就继续借用Countsenor进行编程(名字没有进行修改)
#include "stm32f10x.h" // Device header
uint16_t Freq_Count;
void CountSenor_Init(void)
{
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE );//优先级配置 GPIO 只用使能时钟
RCC_APB2PeriphClockCmd (RCC_APB2Periph_AFIO,ENABLE );//优先级配置AFIO
//中断->AFIO->EXTI->NVIC
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure. GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure. GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure. GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB ,&GPIO_InitStructure );
GPIO_EXTILineConfig (GPIO_PortSourceGPIOB,GPIO_PinSource14);//中断配置 EXIT 进行中断的线路B 14
//外部中断配置,中断要进入NVIC需要有一个输入线 EXTI 10,14等是外部中断对应资源
//监测指定的GPIO口的电平信号
EXTI_InitTypeDef EXTI_structure;
EXTI_structure. EXTI_Line =EXTI_Line14;
EXTI_structure.EXTI_LineCmd =ENABLE;
EXTI_structure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_structure.EXTI_Trigger =EXTI_Trigger_Falling;
EXTI_Init ( &EXTI_structure);
//优先级配置 NVIC(只有一个输出,通过优先级比较后输出,有抢占优先级与响应优先级(可插队,不同分组会产生影响
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//选择中断分组AIRCR
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel =EXTI15_10_IRQn ;//选择中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init (&NVIC_InitStructure);
}
uint16_t CountSensor_Get(void)
{
return Freq_Count;
}
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetFlagStatus(EXTI_Line14)== SET )
{
Freq_Count ++;
EXTI_ClearFlag(EXTI_Line14);
}
}
这样即可达到目的。道友再会。
作者:“全剧终”