找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5204|回复: 2
收起左侧

关于stm32f103代码的分析测频

[复制链接]
ID:263355 发表于 2017-12-18 20:50 | 显示全部楼层 |阅读模式
最近电子设计竞赛使用stm32测频,最高可以测到72M时钟的一半,故来分享

【教程】使用STM32测量频率和占空比的几种方法(申请置酷!)
——倾夜·陨灭星尘

这几天在论坛上面解答了好几个询问 STM32 测量频率的贴子,觉得这种需求还是存在的(示波器、电机控制等等)。而简单搜索了一下论坛,这方面的贴子有但是不全。正好今年参加比赛做过这方面的题目(最后是一等奖嘿嘿) ,所以把我们当时尝试过的各种方案都列出来,方便以后大家使用,也是作为一个长期在论坛的潜水党对论坛的回报。

PS:由于我们当时的题目除了测量频率之外,更麻烦的是测量占空比。而这两个的测量方法联系比较紧密,所以也一并把测量占空比的方法写出来。因为时间有限,所以并不能把所有思路都一一测试,只是写在下面作为参考,敬请谅解。

使用平台:官方 STM32F429DISCOVERY 开发板,180MHz 的主频,定时器频率 90MHz。  
相关题目:
(1)测量脉冲信号频率 f_O,频率范围为10Hz~2MHz,测量误差的绝对值不大于 0.1%。
(15 分)
(2)测量脉冲信号占空比 D,测量范围为10%~90%,测量误差的绝对值不大于2%。
(15 分)

思路一:外部中断
思路:这种方法是很容易想到的,而且对几乎所有MCU都适用(连 51 都可以)。方法也很简单,声明一个计数变量 TIM_cnt,每次一个上升沿/下降沿就进入一次中断,对TIM_cnt++,然后定时统计即可。如果需要占空比,那么就另外用一个定时器统计上升沿、
下降沿之间的时间即可。
缺点:缺陷显而易见,当频率提高,将会频繁进入中断,占用大量时间。而当频率超过100kHz 时,中断程序时间甚至将超过脉冲周期,产生巨大误差。同时更重要的是,想要测量的占空比由于受到中断程序影响,误差将越来越大。
总结:我们当时第一时间就把这个方案 PASS 了,没有相关代码(这个代码也很简单) 。
不过,该方法在频率较低(10K 以下)时,可以拿来测量频率。在频率更低的情况下,可以拿来测占空比。

思路二:PWM输入模式
思路:翻遍ST 的参考手册,在定时器当中有这样一种模式:
0.png 0.png
完整的pdf格式文档51黑下载地址(共17页):
使用STM32测量频率和占空比的几种方法 (1).pdf (897.55 KB, 下载次数: 50)


单片机源程序如下:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "key.h"
  5. #include "usart.h"
  6. #include "exti.h"
  7. #include "timer.h"
  8. #include "lcd.h"
  9. //ALIENTEK Mini STM32开发板范例代码4
  10. //外部中断实验   
  11. //技术支持:www.openedv.com
  12. //广州市星翼电子科技有限公司
  13. long unsigned int red,blue,green=0;
  14. unsigned int count=0;


  15. int main(void)
  16. {        

  17.         delay_init();                     //延时函数初始化        
  18.                  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
  19.   uart_init(9600);         //串口初始化为9600,必须要有,不然复位后不显示
  20.         LED_Init();
  21.         LCD_Init();
  22.   TIM1_Int_Init();
  23.         TIM3_Int_Init(99,7199);//10Khz的计数频率,计数到5000为0.5s
  24.          POINT_COLOR=RED;
  25.         TIM_Cmd(TIM1, ENABLE);
  26.   while(1)
  27.         {
  28.           LCD_ShowString(0,0,200,24,24,"frenqucy");        
  29.                 LCD_ShowNum(30,70,red,10,24);//语句执行时间长,放在主函数里 不然定时器定时不准
  30.                 LCD_ShowNum(30,90,blue,10,24);//语句执行时间长,放在主函数里 不然定时器定时不准
  31.                 LCD_ShowNum(30,110,green,10,24);//语句执行时间长,放在主函数里 不然定时器定时不准
  32.         }
  33. }
  34. void TIM3_IRQHandler(void)   //TIM3中断
  35. {
  36.         if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
  37.         {
  38.                
  39.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源         
  40.                 switch (count)
  41.                 {
  42.                   case 0:         
  43.             green=TIM_GetCounter(TIM1);
  44.             TIM_SetCounter(TIM1,0);count++;PAout(3)=0;PAout(4)=0;        break;
  45.                         case 1:
  46.             red=TIM_GetCounter(TIM1);
  47.             TIM_SetCounter(TIM1,0);count++;PAout(3)=0;PAout(4)=1;        break;
  48. ……………………

  49. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
0-131k.rar (496.23 KB, 下载次数: 62)


回复

使用道具 举报

ID:25162 发表于 2018-7-5 21:25 | 显示全部楼层
希望可以运行,谢谢
回复

使用道具 举报

ID:592413 发表于 2020-1-15 21:34 | 显示全部楼层
谢谢分享,测试一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表