概述
STM32定时器使用外部输入模式测量频率
最近项目忙,发现好久没有更新了,有些预期要去写的博客也被搁置了。今天睡前写个简单的做个随笔。
-
硬件原理
关于使用定时器测量电信号频率的方法有很多,这里主要介绍:
(1)普通的外部输入(外部时钟源模式1);
(2)ETR外部触发输入(外部时钟源模式2)。
这里的这两种都是将外部信号作为定时器的时钟源,因此使用这种方法去进行频率测量之后就会限定了该定时器的用法,所以在使用该方法之前务必排除该定时器没有做其他的用途。
在测量的精确度而言,ETR外部触发输入的精度要比普通的外部输入高。但是由于项目中硬件工程师设计使用了只能作为定时器外设通道的PB6(Timer-CH1)。所以只能使用普通外部输入计数的方式去计算频率。 -
软件实现
在程序中,开启了定时器3的计数模式,定时10ms进一次中断。定时器4设置为外部时钟源模式1。代码如下:
timer.c文件
(1)定时器3初始化函数
//=========================================================================
// 通用定时器3中断初始化
// arr:自动重装值。
// psc:时钟预分频数
// 定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
// Ft=定时器工作频率,单位:Mhz
// 这里使用的是定时器3!
//=========================================================================
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能TIM3时钟
TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频 只要此值不为1,则APBx=PLCKx*2再除以psc
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); //初始化TIM3
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
TIM_Cmd(TIM3,ENABLE); //使能定时器3
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
(2)定时器4初始化函数
//=========================================================================
// 定时器4
// 通道1
// 外部信号引脚脉冲检测
//=========================================================================
void TIM4_Cap_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能TIM4时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PB6 清除之前设置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //gpio模式设置为复用模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //设置为推挽
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不上下拉
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4); //设置GPIO复用为中断定时器输入
//初始化定时器4 TIM4
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //设定计数器自动重装值
TIM_TimeBaseStructure.TIM_Prescaler =0; //预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_TIxExternalClockConfig(TIM4,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Falling,03); //设置为外部计数
TIM_SetCounter(TIM4, 0);
TIM_Cmd(TIM4,ENABLE ); //使能定时器4
}
(3)定时器3中断服务函数
u16 CNT;
u16 Realy_CNT;
//=========================================================================
//
// 定时器3中断服务函数
//
//=========================================================================
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
CNT=TIM4->CNT;
Frequency.Fre_100_ms_Flag = 1;
Realy_CNT = (CNT);
Frequency.Frequency_Sum = ((float)Realy_CNT)/10; //khz f=CNT/T(timer)(S) / 1000
TIM4->CNT = 0;
printf("脉冲频率为:%.2f KHzrn",Frequency.Frequency_Sum);
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}
}
通过定时器3每10ms读取一次定时器4的计数值,然后算出频率,计算公式为:
f=Realy_CNT/T(timer)(S) / 1000 (khz)
注:Realy_CNT:定时器4的计数器的值
T(timer)(S):定时器3的定时器值,转换成单位“s”
Written in:2022.06.12-00.59
最后
以上就是稳重冰淇淋为你收集整理的STM32定时器使用外部输入模式测量频率的全部内容,希望文章能够帮你解决STM32定时器使用外部输入模式测量频率所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复