注册 登录
查看: 7133|回复: 52

又发现一个测脉冲方法(输入捕捉测脉冲周期)

[复制链接]
发表于 2014-11-1 12:53:57 | 显示全部楼层 |阅读模式
之前用的测脉冲方法是:定时一段时间,统计这段时间的脉冲数目,从而求出脉冲周期。

实际上,完全可以利用输入捕捉,直接测脉冲的周期。


如果是查询法测脉冲:
500线编码器,1米的速度估计10圈左右,就 500*10 = 5k。即周期为0.2ms。
那么最恶劣的测编码器速度的时间(2个周期)就为0.4ms。

如果用中断,那就更省时间。不过中断的处理稍微复杂一些。

现在继续调试一下,后续再补充代码。

代码在 21楼


5.2版本已经有集成进去!!

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2016-2-22 12:20:46 | 显示全部楼层
这个脉冲周期是指脉冲的高低电平整个周期吧,那假如我只要测脉冲的高电平时间呢?@山外哥
回复 支持 1 反对 0

使用道具 举报

发表于 2014-11-7 23:31:10 | 显示全部楼层
aytc100 发表于 2014-11-7 00:08
相比较来说,T法测量慢速比较准确,M法测量快速比较准确。
T法有个较大的误差来源是码盘/编码器的抖动。 ...

T法有个较大的误差来源是码盘/编码器的抖动。

原来如此,学到了。

慢速的,抖动和加工误差可忽略,所以比较准确。
快速的,统计学的角度,取平均,所以比较准确。
回复 支持 1 反对 0

使用道具 举报

发表于 2014-11-1 21:11:50 | 显示全部楼层
我用外部中断
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-1 21:16:37 | 显示全部楼层

外部中断 + 定时器计时?那就多用一个定时器,不过K60的定时器比较多。
回复 支持 反对

使用道具 举报

发表于 2014-11-1 21:46:27 | 显示全部楼层
我觉得我还是用正交解码的好
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-1 21:47:37 | 显示全部楼层
1200 发表于 2014-11-1 21:46
我觉得我还是用正交解码的好

正交解码确实是好用。不过例如KL26 就没有正交解码功能。
回复 支持 反对

使用道具 举报

发表于 2014-11-1 21:49:04 | 显示全部楼层
山外メ雲ジ 发表于 2014-11-1 21:47
正交解码确实是好用。不过例如KL26 就没有正交解码功能。

KL26如果需要鉴相怎么办
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-1 21:56:39 | 显示全部楼层
1200 发表于 2014-11-1 21:49
KL26如果需要鉴相怎么办

用D触发器,我们的编码器淘宝描述有写:
http://item.taobao.com/item.htm? ... &id=41243840665

回复 支持 反对

使用道具 举报

发表于 2014-11-1 22:40:19 | 显示全部楼层
学习了,顶一个
回复 支持 反对

使用道具 举报

发表于 2014-11-2 10:03:27 | 显示全部楼层
@山外メ雲ジ山外哥,我要发个帖子,字数太多了,怎么解决
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-2 11:45:37 | 显示全部楼层
gsc617 发表于 2014-11-2 10:03
@山外メ雲ジ山外哥,我要发个帖子,字数太多了,怎么解决

可以在2楼继续发帖的。
回复 支持 反对

使用道具 举报

发表于 2014-11-2 22:06:56 | 显示全部楼层
山外メ雲ジ 发表于 2014-11-1 21:16
外部中断 + 定时器计时?那就多用一个定时器,不过K60的定时器比较多。

恩恩   想用FTM正交解码   多少FTM不够
回复 支持 反对

使用道具 举报

发表于 2014-11-4 11:19:45 | 显示全部楼层
正交解码怎么用....
回复 支持 反对

使用道具 举报

发表于 2014-11-4 11:28:20 | 显示全部楼层
791026701 发表于 2014-11-4 11:19
正交解码怎么用....

看K60视频,里面用讲的
回复 支持 反对

使用道具 举报

发表于 2014-11-6 23:50:42 | 显示全部楼层
定时一段时间,统计这段时间的脉冲数目是M法
直接测脉冲的周期是T法
二者结合,各测一遍按预设值取较准确的为准是M-T法
还有更高级的状态观测器(类似卡尔曼滤波的思想)
欢迎大家各种探索。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-6 23:52:34 | 显示全部楼层
aytc100 发表于 2014-11-6 23:50
定时一段时间,统计这段时间的脉冲数目是M法
直接测脉冲的周期是T法
二者结合,各测一遍按预设值取较准确 ...

直接测周期,这个应该是最准吧,比较接近实时速度。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-6 23:52:52 | 显示全部楼层
aytc100 发表于 1415289042
定时一段时间,统计这段时间的脉冲数目是M法
直接测脉冲的周期是T法
二者结合,各测一遍按预设值取较准确的为准是M-T法
还有更高级的状态观测器(类似卡尔曼滤波的思想)
欢迎大家各种探索。
直接测周期,这个应该是最准吧,比较接近实时速度。
来自PC客户端 来自PC客户端
回复 支持 反对

使用道具 举报

发表于 2014-11-7 00:08:08 | 显示全部楼层
山外メ雲ジ 发表于 2014-11-6 23:52
直接测周期,这个应该是最准吧,比较接近实时速度。

相比较来说,T法测量慢速比较准确,M法测量快速比较准确。
T法有个较大的误差来源是码盘/编码器的抖动。例如码盘的缝隙分布有加工误差、测量时码盘的抖动、对射管电压波动造成的亮度变化等等。
回复 支持 反对

使用道具 举报

发表于 2014-11-10 18:18:37 | 显示全部楼层
没做过捕捉脉冲,我以为都是用中断触发的
来自安卓客户端来自安卓客户端
回复 支持 反对

使用道具 举报

发表于 2014-11-24 15:26:28 | 显示全部楼层
山外メ雲ジ 发表于 2014-11-6 23:52
直接测周期,这个应该是最准吧,比较接近实时速度。

山外哥,输入捕捉,直接测脉冲的周期的程序例程可以参考一下吗?谢谢呀
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-11-24 15:29:42 | 显示全部楼层
3119459734 发表于 2014-11-24 15:26
山外哥,输入捕捉,直接测脉冲的周期的程序例程可以参考一下吗?谢谢呀

用5.1版本的 K60 代码可以测试。

  1. //全局变量定义
  2. volatile uint32 cnvtime = 0;                //输入捕捉值

  3. //函数声明
  4. void FTM0_INPUT_IRQHandler(void);        //FTM0中断服务函数

  5. /*!
  6. *  @brief      main函数
  7. *  @since      v5.0
  8. *  @note       FTM 输入捕捉 测脉冲宽度 测试
  9. */
  10. void main()
  11. {
  12.     ftm_input_init(FTM0, FTM_CH6, FTM_Falling,FTM_PS_2);     //初始化FTM输入捕捉模式,下降沿捕捉(FTM0_CH6 为 PTD6)
  13.     set_vector_handler(FTM0_VECTORn ,FTM0_INPUT_IRQHandler);    //设置FTM0的中断服务函数为 FTM0_INPUT_IRQHandler
  14.     enable_irq (FTM0_IRQn);                                     //使能FTM0中断

  15.     ftm_pwm_init(FTM1, FTM_CH1,10*1000,50);

  16.     while(1)
  17.     {
  18.         if(cnvtime != 0)
  19.         {
  20.             //捕捉频率 = bus 时钟 / (分频系数) / cnvtime
  21.             //分频系数 是 由 初始化时传递进去的分频因子FTM_PS_e 决定,分频系数 = 1<<FTM_PS_e
  22.             //最大支持频率为 bus 时钟 四分之一
  23.             printf("\n捕捉到频率为:%d",bus_clk_khz*1000/(1<<FTM_PS_2)/cnvtime);
  24.             cnvtime = 0;
  25.         }
  26.         else
  27.         {
  28.             printf("\n没有捕捉到频率");
  29.         }

  30.         DELAY_MS(500);      //这里 的延时 ,仅仅是 避免 过于频繁打印数据到串口
  31.     }
  32. }

  33. void FTM0_INPUT_IRQHandler(void)
  34. {
  35.     uint8 s = FTM0_STATUS;          //读取捕捉和比较状态  All CHnF bits can be checked using only one read of STATUS.
  36.     uint8 CHn;

  37.     FTM0_STATUS = 0x00;             //清中断标志位    All CHnF bits can be cleared by reading STATUS followed by writing 0x00 to STATUS.

  38.     CHn = 6;
  39.     if( s & (1 << CHn) )
  40.     {
  41.         /*     用户任务       */
  42.         cnvtime = ftm_input_get(FTM0,(FTM_CHn_e)CHn);     //保存
  43.         ftm_input_clean(FTM0);                 //清 计数器计数值

  44.         /*********************/
  45.     }
  46. }

底层代码,需要修改一下:
  1. /*!
  2. *  @brief      输入捕捉初始化函数
  3. *  @param      FTMn_e          模块号(FTM0、  FTM1、  FTM2)
  4. *  @param      FTM_CHn_e       通道号(CH0~CH7)
  5. *  @param      FTM_Input_cfg   输入捕捉触发条件配置
  6. *  @param      FTM_PS_e        分频因子
  7. *  @since      v5.0
  8. *  @note       同一个FTM,只能干一个活,用于输入捕捉后就不要再用于其他功能,例如PWM。
  9. *  Sample usage:       ftm_input_init(FTM0, FTM_CH0, FTM_Rising,FTM_PS_2);    //设置 FTM0_CH0上升沿触发输入捕捉,二分频
  10. */
  11. void ftm_input_init(FTMn_e ftmn, FTM_CHn_e ch, FTM_Input_cfg cfg,FTM_PS_e ps)
  12. {
  13.     ASSERT( (ftmn == FTM0) || ( (ftmn == FTM1 || ftmn == FTM2 ) && (ch <= FTM_CH1))
  14. #ifdef MK60F15
  15.             || (ftmn == FTM3)       //FX  有FTM3
  16. #endif
  17.            );  //检查传递进来的通道是否正确

  18.     /******************* 开启时钟 和 复用IO口*******************/
  19.     FTM_port_mux(ftmn,ch);

  20.     /******************* 设置为输入捕捉功能 *******************/
  21.     switch(cfg)
  22.     {
  23.         //输入捕捉模式下:DECAPEN = 0 , DECAPEN = 0 ,CPWMS = 0, MSnB:MSnA = 0

  24.         // ELSnB:ELSnA         1          10          11
  25.         // 配置             上升沿      下降沿      跳变沿

  26.     case FTM_Rising:    //上升沿触发
  27.         FTM_CnSC_REG(FTMN[ftmn], ch) |=  ( FTM_CnSC_ELSA_MASK  | FTM_CnSC_CHIE_MASK );                   //置1
  28.         FTM_CnSC_REG(FTMN[ftmn], ch) &= ~( FTM_CnSC_ELSB_MASK  | FTM_CnSC_MSB_MASK | FTM_CnSC_MSA_MASK); //清0
  29.         break;

  30.     case FTM_Falling:   //下降沿触发
  31.         FTM_CnSC_REG(FTMN[ftmn], ch) |= (FTM_CnSC_ELSB_MASK  | FTM_CnSC_CHIE_MASK );                    //置1
  32.         FTM_CnSC_REG(FTMN[ftmn], ch) &= ~( FTM_CnSC_ELSA_MASK | FTM_CnSC_MSB_MASK | FTM_CnSC_MSA_MASK); //清0
  33.         break;

  34.     case FTM_Rising_or_Falling: //上升沿、下降沿都触发
  35.         FTM_CnSC_REG(FTMN[ftmn], ch) |=  ( FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK  | FTM_CnSC_CHIE_MASK ); //置1
  36.         FTM_CnSC_REG(FTMN[ftmn], ch) &= ~( FTM_CnSC_MSB_MASK  | FTM_CnSC_MSA_MASK); //清0
  37.         break;
  38.     }

  39.     FTM_SC_REG(FTMN[ftmn]) = ( 0
  40.                               | FTM_SC_CLKS(0x1)       //选择 bus 时钟
  41.                               | FTM_SC_PS(ps)          //选择 分频系数
  42.                              );
  43.     FTM_MODE_REG(FTMN[ftmn])    |= FTM_MODE_WPDIS_MASK; //禁止写保护
  44.     FTM_COMBINE_REG(FTMN[ftmn]) = 0;
  45.     FTM_MODE_REG(FTMN[ftmn])    &= ~FTM_MODE_FTMEN_MASK;    //使能FTM
  46.     FTM_CNTIN_REG(FTMN[ftmn])   = 0;

  47.     FTM_STATUS_REG(FTMN[ftmn])  = 0x00;               //清中断标志位

  48.     //开启输入捕捉中断
  49.     //enable_irq(FTM0_IRQn + ftmn);
  50. }

  51. /*!
  52. *  @brief      获取捕捉时间发生时的计数值
  53. *  @param      FTMn_e          模块号(FTM0、  FTM1、  FTM2)
  54. *  @param      FTM_CHn_e       通道号(CH0~CH7)
  55. *  @return     获取捕捉时间发生时的计数值
  56. *  @since      v5.0
  57. *  Sample usage:       uint16 data = ftm_input_get (FTM0, FTM_CH0) ;   // 获取FTM0_CH0输入捕捉事件触发时的计数值
  58. */
  59. uint16   ftm_input_get (FTMn_e ftmn, FTM_CHn_e ch)
  60. {
  61.         ASSERT( (ftmn == FTM0) || ( (ftmn == FTM1 || ftmn == FTM2 ) && (ch <= FTM_CH1))
  62. #ifdef MK60F15
  63.                 || (ftmn == FTM3)       //FX  有FTM3
  64. #endif
  65.                );  //检查传递进来的通道是否正确

  66.     return (uint16)FTM_CnV_REG(FTMN[ftmn],ch);    //保存
  67. }

  68. void     ftm_input_clean (FTMn_e ftmn)
  69. {
  70.     ASSERT( ftmn < FTM_MAX);     //检查传递进来的通道是否正确

  71.     FTM_CNT_REG(FTMN[ftmn]) = 0;               //清 计数器计数值
  72. }



回复 支持 反对

使用道具 举报

发表于 2014-11-24 15:38:47 | 显示全部楼层
谢谢山外哥呀
回复 支持 反对

使用道具 举报

发表于 2014-11-24 17:50:14 | 显示全部楼层
gsc617 发表于 2014-11-2 10:03
@山外メ雲ジ山外哥,我要发个帖子,字数太多了,怎么解决

期待神贴。。。。。
回复 支持 反对

使用道具 举报

发表于 2014-11-24 17:50:40 | 显示全部楼层
期待啊  山外哥加油
回复 支持 反对

使用道具 举报

发表于 2014-11-24 19:18:14 | 显示全部楼层
板正的 发表于 2014-11-24 17:50
期待神贴。。。。。

帖子早发表了,你可以看看
回复 支持 反对

使用道具 举报

发表于 2014-11-24 20:00:47 | 显示全部楼层
山外メ雲ジ 发表于 2014-11-24 15:29
用5.1版本的 K60 代码可以测试。

  • ftm_input_get(FTM0,(FTM_CHn_e)CHn);     //保存
  •         ftm_input_clean(FTM0);  
  • 山外哥这个貌似底层没定义吗,编译有错误


回复 支持 反对

使用道具 举报

发表于 2014-11-24 20:49:52 | 显示全部楼层
回复 支持 反对

使用道具 举报

发表于 2014-11-24 21:57:50 | 显示全部楼层
板正的 发表于 2014-11-24 20:49
http://www.vcan123.com/forum.php?mod=viewthread&tid=6495
是这个吧

这个是最近发表的帖子,当然还可以看看我别的主题。
回复 支持 反对

使用道具 举报

发表于 2014-11-24 22:04:06 | 显示全部楼层
gsc617 发表于 2014-11-24 21:57
这个是最近发表的帖子,当然还可以看看我别的主题。

恩恩  一定认真看。。。
麻烦大神帮忙看看这个
http://www.vcan123.com/forum.php?mod=viewthread&tid=6790
回复 支持 反对

使用道具 举报

发表于 2014-11-25 13:32:20 | 显示全部楼层
山外メ雲ジ 发表于 2014-11-24 15:29
用5.1版本的 K60 代码可以测试。

  • ftm_input_get(FTM0,(FTM_CHn_e)CHn);           ftm_input_clean(FTM0);  山外哥这两个K60V5.1有这底层吗?我找不到呀。。程序编译错这两条语句。。求解释。。

回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-12-1 14:21:39 | 显示全部楼层
3119459734 发表于 2014-11-25 13:32
  • ftm_input_get(FTM0,(FTM_CHn_e)CHn);           ftm_input_clean(FTM0);  山外哥这两个K60V5.1有这 ...

  • 建议你自己发帖来咨询。跟帖,帖子太多,容易忽略。
    回复 支持 反对

    使用道具 举报

    发表于 2014-12-2 13:08:35 | 显示全部楼层
    恩恩,以后知道咯。谢啦,顶~~~~

    回复 支持 反对

    使用道具 举报

    发表于 2015-2-25 21:54:14 | 显示全部楼层
    山外メ雲ジ 发表于 2014-11-24 15:29
    用5.1版本的 K60 代码可以测试。

    改动的是哪里?
    回复 支持 反对

    使用道具 举报

    发表于 2015-3-12 09:06:32 | 显示全部楼层
    还有DMA测速的底层吗?
    回复 支持 反对

    使用道具 举报

    发表于 2015-3-16 23:54:00 | 显示全部楼层
    山外メ雲ジ 发表于 2014-11-24 15:29
    用5.1版本的 K60 代码可以测试。

    山外哥 我用的模板没有set_vector_handler()这个函数怎么办。。。。。。。。初学不怎么会处理这种问题。不同人出的库函数里函数有多有少,这个问题怎么办呢
    回复 支持 反对

    使用道具 举报

     楼主| 发表于 2015-3-17 08:19:44 | 显示全部楼层
    山内菜鸟 发表于 2015-3-16 23:54
    山外哥 我用的模板没有set_vector_handler()这个函数怎么办。。。。。。。。初学不怎么会处理这种问题 ...

    你用5.0之后的版本就会有。


    来自安卓客户端来自安卓客户端
    回复 支持 反对

    使用道具 举报

     楼主| 发表于 2015-3-17 08:43:44 | 显示全部楼层
    山内菜鸟 发表于 2015-3-16 23:54
    山外哥 我用的模板没有set_vector_handler()这个函数怎么办。。。。。。。。初学不怎么会处理这种问题 ...

    你直接用我们例程吧,书后例程都是完整库。
    来自安卓客户端来自安卓客户端
    回复 支持 反对

    使用道具 举报

    发表于 2015-3-17 16:52:23 | 显示全部楼层
    山外メ雲ジ 发表于 2015-3-17 08:19
    你用5.0之后的版本就会有。

    最新版本是什么哪个,有下载链接吗,或可以发邮箱1449653855@qq.com
    回复 支持 反对

    使用道具 举报

    发表于 2015-3-23 23:46:53 | 显示全部楼层
    山外メ雲ジ 发表于 2014-11-1 21:56
    用D触发器,我们的编码器淘宝描述有写:
    http://item.taobao.com/item.htm?spm=a1z10.1.w4004-852304965 ...

    那个  陀螺仪的z轴应该   垂直地面   放置   换是水平放置

    回复 支持 反对

    使用道具 举报

    发表于 2015-4-12 21:34:27 | 显示全部楼层
    请问对应于200线的编码器,速度怎么转换呢?大概获得多少的频率,速度为1m\s?
    回复 支持 反对

    使用道具 举报

    发表于 2015-4-14 19:49:08 | 显示全部楼层
    山外哥 分频因子在初始化里的会发生变化吗
    回复 支持 反对

    使用道具 举报

    发表于 2015-4-15 11:28:22 | 显示全部楼层
    KL26用的DMA 挺稳定的
    回复 支持 反对

    使用道具 举报

    发表于 2015-4-21 17:59:02 | 显示全部楼层
    山外哥,底层代码去哪里修改?
    回复 支持 反对

    使用道具 举报

    发表于 2015-5-26 17:46:07 | 显示全部楼层
    1200 发表于 2014-11-1 21:46
    我觉得我还是用正交解码的好

    正交解码的话FTM貌似不够用了、、、、、、
    回复 支持 反对

    使用道具 举报

    发表于 2015-12-10 23:56:06 | 显示全部楼层
    这个需要特定的引脚吗
    回复 支持 反对

    使用道具 举报

    发表于 2016-2-22 11:11:13 | 显示全部楼层
    谢谢分享
    回复 支持 反对

    使用道具 举报

    发表于 2016-2-27 21:12:56 | 显示全部楼层
    山外哥真棒
    回复 支持 反对

    使用道具 举报

    发表于 2016-2-29 19:26:41 | 显示全部楼层
    Whatarewords 发表于 2016-2-22 12:20
    这个脉冲周期是指脉冲的高低电平整个周期吧,那假如我只要测脉冲的高电平时间呢?@山外哥

    兄弟  这个问题你解决了吗?  我现在也遇到这个问题   能分享一下你的成果吗?  小弟谢谢了  跪谢  
    回复 支持 反对

    使用道具 举报

    发表于 2016-2-29 22:36:56 | 显示全部楼层
    zxd961202 发表于 2016-2-29 19:26
    兄弟  这个问题你解决了吗?  我现在也遇到这个问题   能分享一下你的成果吗?  小弟谢谢了  跪谢

    中断里面加中断
    来自安卓客户端来自安卓客户端
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

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