查看: 3205|回复: 2

基于AVR XMEGA-A3BU Xplained控制器的Wifi小车制作(12)---测速模块

[复制链接]
  • TA的每日心情
    擦汗
    2024-9-30 02:33
  • 签到天数: 444 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2013-4-20 10:31:11 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 木子鱼 于 2013-5-8 20:52 编辑

              今日上午突然就想研究下小车电机转速测量的方法;以前都木有这方面的经验,上午耐心地看了看,发现懂了。
    cesu1.jpg cesu2.jpg
    上面的图片就是我买的测速模块,它的电路图超级简单:
                                     cesu3.jpg
    一对红外发射和接收,
    1.工作电压:DC 3.3V-5.5V(最佳电压为 5V)
    2.输出接口:3 线制接口(S 为信号输出端,+为正电源,-为负电源也就是地线)
    3.输出信号:TTL 电平(可直接连接单片机 I/0 号,有挡碍物时,指示灯亮,输出高电平;无挡碍物时,指示灯不亮,输出底电平。)
    4.测量转速-----X转每分钟。根据码盘齿数为20齿,可以理解为码盘每转一周,就会产生20个脉冲,也就会有20个上升沿、或20个下降沿。当我设个定时60  在这段时间里去检测一个I/O口它的下降沿的次数n,然后就可以得出码盘的转速为:n/20 (/)
    至此看来得研究下  XMEGA 256的定时器中断,因为要产生一个60秒的定时。
    ·············································································································· ·   好吧,我来说说我是怎么理解ASF 中关于定时/计数器的定义和操作运用的。还是不得不赞一下,ASF 是不错的开发平台,简单易懂,便于学习,快速掌握。
        还是在以前建的工程中打开 ASF Wizard .
    然后在里面找到Timer Counter  资源包,大致能想象到用定时器时一般都会用到中断的操作,看到这里也有Interrupt Management 也把它添加进去。

    然后展开ASF Explorer
    双击TC 的Quick Start Guide
    可以看到官方给出了  定时计数器的3种用法
    1定时计数器的溢出中断  2定时计数器的比较匹配中断   3定时计数器的PWM应用
    现在我需要产生一个计数到60秒,然后让它再清0重新计时,这样就相当于一个60秒的定时器。
    用溢出中断的方法:
    pmic_init();//使能中断控制器
    sysclk_init();
    tc_enable(&TCC0);//使能TC0定时计数器    这里选择的是TC0 定时计数器  也可以选择TC1 TD0  TD1
    //tc_set_overflow_interrupt_callback(&TCC0, my_callback);//溢出中断回调函数 溢出时执行该函数    由于定时计数器工作在溢出模式时 会自动reset  所以该语句不用编写可行  
    tc_set_wgm(&TCC0, TC_WG_NORMAL);
    tc_write_period(&TCC0, 60000);//这条语句就是设定溢出值,60000表示60秒=1分钟tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO);
    cpu_irq_enable();
    tc_write_clock_source(&TCC0, TC_CLKSEL_DIV1_gc);
    上面这几行语句就可以产生一个60秒的定时。


    用定时计数器比较匹配的方法产生:
    pmic_init();//使能中断控制器
    sysclk_init();
    cpu_irq_enable();
    tc_enable(&TCC0);//使能TC0定时计数器
    tc_set_cca_interrupt_callback(&TCC0, my_cca_callback);//比较中断回调函数声明
    tc_set_wgm(&TCC0, TC_WG_NORMAL);
    tc_write_period(&TCC0, 100000);//这里设定的值要大于比较值,也就是要大于60000
    tc_write_cc(&TCC0, TC_CCA, 60000);//这条语句就是设定比较值,60000表示60秒
    tc_enable_cc_channels(&TCC0,TC_CCAEN);
    tc_set_cca_interrupt_level(&TCC0, TC_INT_LVL_LO);
    tc_write_clock_source(&TCC0, TC_CLKSEL_DIV1_gc);
    由于比较中断方法,当达到比较值时定时计数器不会自动reset,会产生一个比较中断,然后会执行该中断回调函数里的语句   同时定时计数器会继续累加到设定的最大tc_write_period
    我们要想产生一个60秒的定时,就可以在它定时计数到达60000时,产生了中断,我们在中断回调函数里给它编写reset 的语句,就可以了,这样定时计数器就会被reset.从0开始计数,也就相当于一个60秒的定时器。
    static void my_cca_callback(void)
    {
         pmic_init();//使能中断控制器
        sysclk_init();
        cpu_irq_enable();
        tc_enable(&TCC0);//使能TC0定时计数器
        tc_set_wgm(&TCC0, TC_WG_NORMAL);
        tc_write_period(&TCC0, 100000);//这里设定的值要大于比较值,也就是要大于60000
       tc_write_cc(&TCC0, TC_CCA, 60000);//这条语句就是设定比较值,60000表示60秒
    }
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-1-19 22:39
  • 签到天数: 303 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2013-4-21 22:42:23 | 显示全部楼层
    学习参考了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-9-30 02:33
  • 签到天数: 444 天

    连续签到: 1 天

    [LV.9]以坛为家II

     楼主| 发表于 2013-4-22 09:18:35 | 显示全部楼层
    jwdxu2009 发表于 2013-4-21 22:42
    学习参考了

    互相学习,共同进步!
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-12-21 00:41 , Processed in 0.138287 second(s), 21 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.