查看: 46|回复: 0

【连载】基于AVR XMEGA-A3BU Xplained控制器的Wifi小车制作(8)

[复制链接]

主题

好友

2

积分

白丁

  • TA的每日心情

    2014-8-28 17:09
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2014-8-23 01:11:40 |显示全部楼层
    本文将研究下小车电机转速测量的方法。
            以前都木有这方面的经验,上午耐心地看了看,发现懂了。       
            上面的图片就是我买的测速模块,它的电路图超级简单:       
            一对红外发射和接收,
             
    • 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);用定时计数器比较匹配的方法产生: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);//这里设定的值要大于比较值,也就是要大于60000tc_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秒}
    回复

    使用道具 举报

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

    关闭

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

    手机版|电路城

    GMT+8, 2019-7-20 01:32 , Processed in 0.107587 second(s), 15 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz!

    返回顶部