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);
   }
	
}
	

 这样即可达到目的。道友再会。

作者:“全剧终”

物联沃分享整理
物联沃-IOTWORD物联网 » STM32测频法详解:频率测量技术与实现

发表回复