完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
基于stm32f103单片机对信号频率、占空比的测量。
最近开始仪器仪表方面的学习了,计划后期做一个示波器。所以这周就在stm32f103上面做了一个测量频率、占空比的小设计。总体上精度还是比较高的,测量频率量程在35Hz—190KHz。频率可以精确到小数点后四位,占空比测量的精度也比较高,可以到小数点后两位。 说到用stm32测频率,都会想到用定时器的输入捕获模式,只需要一个定时器和一个IO口即可,前几天在论坛上看到还有一种是用两个定时器测频率,一个定时器用来检测信号跳变沿,另外一个用来精准定时,比如说用TIM1检测跳变沿(假设为上升沿),TIM2开一个1s的定时器中断,这个1s就比较准确,在1s内TM1检测到了多少个上升沿改信号的频率就是多少。这种方法我本周二试过,精度比输入捕获模式下的高,而且还比较稳定,缺点是用到了两个定时器,占用的cpu资源较多。考虑到我后面任务需要,定时器可能会不够用,故还是用的输入捕获模式。 实验平台:stm32f103zet6 定时器及通道:TIM2的通道2 IO口:PA1 定时器及输入捕获模式的配置: u8 Edge_Flag; ==GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Speed=&==TIM_CounterMode_Up; TIM_InitStruct.TIM_Period==; TIM_TimeBaseInit(TIM2,&==; TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising; TIM_ICInitStruct.TIM_ICPrescaler==TIM_ICSelection_DirectTI; TIM_ICInit(TIM2,&===; NVIC_InitStruct.NVIC_IRQChannelSubPriority=; NVIC_Init(& void TIM2_IRQHandler(void){ if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!=RESET) //捕获到上升沿 { if(Edge_Flag==1) { Rising=TIM2->CCR2; //第一次检测到下降沿 TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising); //再次改为上升沿触发 Edge_Flag++; } else if(Edge_Flag==2) { Rising_Last=TIM2->CCR2; TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising); Edge_Flag=0; //标志位清0 TIM_SetCounter(TIM2,0); //定时器清0 } else { Falling=TIM2->CCR2; //第一次检测到上升沿 TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Falling); //将上升沿触发改为下降沿触发 Edge_Flag++; } } TIM_ClearITPendingBit(TIM2,TIM_IT_CC2); //清除标志位} 输入捕获模式下,中断服务函数里面处理的内容要尽量少,所以在记录定时器捕获到值时,直接将TIM2的CCR2寄存器里面的值赋值给相应变量。 主函数: int main(void) { delay_init(); //延时函数初始化 OLED_Init(); //oled屏幕初始化 OLED_On(); OLED_Clear(); TIM2_Cap_Init(); //定时器初始化 while(1) { OLED_ShowString(0,0,"Freq:",16); OLED_ShowString(100,0,"Hz",16); OLED_ShowNum(50,0,72000000/(Rising_Last-Falling),6,16); OLED_ShowString(0,2,"Duty:",16); OLED_ShowString(95,2,"%",16); OLED_Showdecimal(50,2,(float)(Rising-Falling)/(float)(Rising_Last-Falling)*100,2,3,16); delay_ms(100); } } 变量Rising_Last为第二次检测到上升沿捕获到的值,Falling为第一次捕获到的值,两者之差为定时器计数的数值差,根据TIM_Prescaler=0(即不分频),主频为72M,频率f=72M/(Rising_Last-Falling)。而Rising-Falling为高电平的时间,除以一个周期就是占空比了。 实验现象 频率10K,占空比60% 频率102.56K,占空比33% 可见效果还是挺不错的,但是这种办法包括上面讲到的双定时器法都有一个缺点,那就是当信号幅度小于2v时,单片机就检测不到跳变沿。外部还需要硬件对信号进行适当放大。也是前几天,在论坛上看到有人提出一个测频率的叫过零检测法,用ADC读信号电压值,ADC值为0时进行记录,再次为0就相当于经过了半个周期。计算两次ADC为0的时间差,就可以计算出信号的频率,这种方法不会受限于信号幅度大小。原理也比较简单,相关程序我也正在写,等测试没问题后我再发出来和大家分享! |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1760 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1613 浏览 1 评论
1058 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1670 浏览 2 评论
1932浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
724浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
564浏览 3评论
590浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
548浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 17:33 , Processed in 0.700563 second(s), Total 46, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号