搜索
bottom↓
回复: 14

【eBox生态圈】STM32输入捕获模式测频率、周期、占空比

[复制链接]

出0入17汤圆

发表于 2016-1-9 16:06:24 | 显示全部楼层 |阅读模式
本帖最后由 shentqlf 于 2016-1-9 16:31 编辑

时隔两个月,时间太快了!最近我将慢慢的更新这段时间对ebox的完善,一点点带大家熟悉eBox固件库的最新特点!
这段时间eBox在不断的更新内容,先上一个最新的支持!定时器输入捕获模式

基础知识:
STM32输入捕获模式,主要用于测量输入信号的周期,进而计算波形的频率。正常情况下。输入捕获模式只能测量周期,因为stm32在输入捕获模式设置为检测上升沿或者下降沿。当检测到边沿后,保存定时器的当前值到TIMx->CCR1寄存器。在中断中读取此寄存器就可以得到两个上升沿或者下降沿之间的脉冲数,然后在根据定时器的时钟去计算波形的周期。
如果要测量占空比就要在中断中重新设置边沿即可。
特点
1.支持TIM2,3,4的ch1,2,3,4.共计12个通道
2.支持测量周期、频率、高级用法支持测量占空比
3.定时器计数器最大值为0xffff,为了突破这个限制,
    在本例程中,如果使用了update溢出中断调用overflow_event_process可以将计数器
    拓展至2^32。大大提高测量范围,可以实现最高频率(1分频)测量周期低于60s的信号,如果信号长度。
    如果使用2分频,可测量周期低于120s的信号,如果信号长度。以此类推。
4.get_captur()的精度补偿值
    //此处要加一个简单的修正值,此数为测试大致测试结果
    //分频系数 | 补偿值 | TIM时钟频率 | 测试频率
    //7200分频 | 0      | 0.01M       |  1hz-100hz
    //720分频  | 1      | 0.10M       |  100-1K
    //72分频   | 2      | 1.00M       |  1K
    //64分频   | 3      | 1.125M      |  1K
    //36分频   | 5      | 2.00M       |  1K
    //32分频   | 6      | 2.25M       |  1K
    //18分频   | 11     | 4.00M       |  1K
    //16分频   | 11     | 4.50M       |  1K
    //9分频    | 18     | 8.00M       |  10K
    //8分频    | 21     | 9.00M       |  10K-50K
    //4分频    | 42     | 18.0M       |  10K-50K
    //2分频    | 84     | 36.0M       |  10K-50K
    //1分频    | 168    | 72.0M       |  10K-50K
5.关于分频系数和脉冲宽度测量的计算关系,要遵循一个原则:在不溢出的情况下尽量使用低分频系数(高TIM时钟)去检测对象
重点:
    在采用低分频系数的时候,可以保证测量精度,但是会增大定时器溢出频率,进而增大cpu开销,
    在采用高分频系数的时候,测量精度较低,但是会降低定时器溢出频率,进而降低cpu开销,
    stm32在72M主频下,最高可测160Khz的信号。如果再大,将无法测量。
测试例程1-测量周期、频率
  1. /*
  2. file   : *.cpp
  3. author : shentq
  4. version: V1.0
  5. date   : 2015/7/5

  6. Copyright 2015 shentq. All Rights Reserved.
  7. */

  8. /*
  9. 本例程为使用输入捕获模式测量一个PWM信号的周期和频率
  10. */
  11. #include "ebox.h"

  12. IN_CAPTURE ic(&PA0);//创建一个输入捕获的对象
  13. PWM pwm1(&PB8);//创建一个PWM输出对象

  14. uint32_t value1;
  15. uint32_t value2;

  16. void mesure_frq()//输入捕获中断事件
  17. {
  18.    ic.set_count(0);
  19.     value1 = ic.get_capture() + 170;
  20. }
  21. void update_event()
  22. {
  23.     ic.overflow_event_process();
  24. }
  25. uint16_t p;
  26. void setup()
  27. {
  28.         ebox_init();
  29.         uart1.begin(115200);   
  30.     p = 1;
  31.     ic.begin(p);//初始化输入捕获参数,p分频
  32.     ic.attch_ic_interrupt(mesure_frq);//绑定捕获中断事件函数
  33.     ic.attch_update_interrupt(update_event);
  34.     pwm1.begin(1000,900);
  35.     pwm1.set_oc_polarity(1);
  36.    
  37. }
  38. int main(void)
  39. {
  40.         setup();
  41.         while(1)
  42.     {

  43.         if(value1)
  44.         {
  45.             uart1.printf("overtimes = %d\r\n",ic.get_overflow_state());
  46.             uart1.printf("value1 = %d\r\n",value1);//输出PWM周期
  47.             uart1.printf("frq = %0.0f\r\n",(72000000.0/p)/(value1));//输出PWM频率
  48.             value1 = 0;
  49.         }
  50.         }
  51. }
复制代码

测试例程2-测量占空比
  1. #include "ebox.h"

  2. IN_CAPTURE ic(&PA0);//创建一个输入捕获的对象
  3. PWM pwm1(&PB8);//创建一个PWM输出对象

  4. uint32_t value1;
  5. uint32_t value2;

  6. void mesure_frq()//输入捕获中断事件
  7. {
  8.     ic.set_count(0);
  9.     if(ic.polarity == TIM_ICPOLARITY_FALLING)//测量高电平时间完成
  10.     {
  11.         value1 = ic.get_capture() + 170;//校正值,查表可得
  12.         ic.set_polarity_rising();//切换至测量低电平时间完成
  13.     }
  14.     else//测量低电平时间完成
  15.     {
  16.          value2 = ic.get_capture() + 170;//校正值,查表可得
  17.         ic.set_polarity_falling();//切换至测量高电平时间完成
  18.    }
  19. }
  20. void update_event()
  21. {
  22.     ic.overflow_event_process();
  23. }
  24. uint16_t p;
  25. void setup()
  26. {
  27.         ebox_init();
  28.         uart1.begin(115200);   
  29.     p = 1;
  30.     ic.begin(p);//初始化输入捕获参数,p分频
  31.     ic.attch_ic_interrupt(mesure_frq);//绑定捕获中断事件函数
  32.     ic.attch_update_interrupt(update_event);
  33.     pwm1.begin(1000,900);
  34.     pwm1.set_oc_polarity(1);
  35.    
  36. }
  37. int main(void)
  38. {
  39.         setup();
  40.         while(1)
  41.     {

  42.         if(value1 && value2)
  43.         {
  44.             uart1.printf("value1 = %d\r\n",value1);
  45.             uart1.printf("value2 = %d\r\n",value2);
  46.             uart1.printf("frq = %0.0f\r\n",(72000000.0/p)/(value1+value2));
  47.             uart1.printf("pluse = %0.2f\r\n",value1*100.0/(value1+value2));
  48.             value1 = 0;
  49.             value2 = 0;
  50.         }
  51.         }
  52. }
复制代码

工程代码

上个小链接:
https://item.taobao.com/item.htm ... ;abbucket=14#detail
望大家支持!嘿嘿

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-1-9 16:27:42 | 显示全部楼层

出0入0汤圆

发表于 2016-1-9 16:58:04 | 显示全部楼层
牛逼



出425入0汤圆

发表于 2016-1-9 17:00:18 | 显示全部楼层
本帖最后由 guolun 于 2016-1-9 17:12 编辑

程序很简洁易读。一直追求这样的效果。
修改过错别字。

出0入17汤圆

 楼主| 发表于 2016-1-9 17:02:06 | 显示全部楼层
guolun 发表于 2016-1-9 17:00
程序很简介易读。一直追求这样的效果。

谢谢夸奖!

出20入0汤圆

发表于 2016-1-9 20:35:54 | 显示全部楼层
  谢谢分享

出20入0汤圆

发表于 2016-1-9 20:36:59 | 显示全部楼层
  谢谢分享

出0入4汤圆

发表于 2016-1-9 20:55:43 | 显示全部楼层
不错,以后需要可以到这里找

出0入0汤圆

发表于 2016-1-9 23:59:58 来自手机 | 显示全部楼层
mark,明天早上醒来再看看

出0入0汤圆

发表于 2016-1-10 10:58:37 来自手机 | 显示全部楼层
不错不错

出0入46汤圆

发表于 2016-1-13 09:32:40 | 显示全部楼层
不错,顶楼主

出0入17汤圆

 楼主| 发表于 2016-1-13 18:08:07 | 显示全部楼层

谢谢支持!希望大家能多多关注!

出0入0汤圆

发表于 2017-3-27 20:39:07 | 显示全部楼层
不错,顶一下!正准备在测试设备上用

出0入0汤圆

发表于 2018-7-19 00:41:09 | 显示全部楼层
MARK!

出675入8汤圆

发表于 2020-7-10 12:54:30 来自手机 | 显示全部楼层
以后需要可以到这里找
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 03:34

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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