21ic电子技术开发论坛

标题: 如何使用avr实现较精确延时 [打印本页]

作者: qiannengneng    时间: 2014-7-28 12:00
标题: 如何使用avr实现较精确延时
我使用t1计时器每隔10us溢出中断,定义一个全局变量count,每次中断中count+1,根据count的值确定延时时间。原以为这样较为精确,实际用示波器观察的时候,大概count值为45时,示波器显示的波形长大概在560us左右(相差100多us),还是不够精确,请问avr可以实现更精确的延时么?该怎么做呢?
作者: huangxz    时间: 2014-7-28 13:41
定时时间太短了,肯定没那么精确,使用任何器件应该首先了解它的性能
作者: qiannengneng    时间: 2014-7-28 23:14
huangxz 发表于 2014-7-28 13:41
定时时间太短了,肯定没那么精确,使用任何器件应该首先了解它的性能

哦哦,8m的晶振,10us的中断,每次进入中断加上两句对计时器的初始化就要消耗4+2个指令周期
也就是说每次中断都会有0.75us的误差,所以误差很大吗
作者: huangxz    时间: 2014-7-29 09:44
qiannengneng 发表于 2014-7-28 23:14
哦哦,8m的晶振,10us的中断,每次进入中断加上两句对计时器的初始化就要消耗4+2个指令周期
也就是说每次 ...

不仅包含你写的语句,实际使用的时钟数你可以看看汇编代码啊,很多的
作者: qiannengneng    时间: 2014-7-30 20:04
huangxz 发表于 2014-7-29 09:44
不仅包含你写的语句,实际使用的时钟数你可以看看汇编代码啊,很多的

额,汇编目前还不会
作者: fp123123    时间: 2014-7-30 21:46
用汇编指令,在中断里用指令来定时,这样很准确,不会汇编也没关系,会改就行,下面这个是用MEGA644做的VGA信号发生器的行扫描中断程序,时间要求很精确。这里要特别提一下AVR的中断进入时间,AVR大部分指令是1个时钟,还有2,3,4个时钟的,只有执行完当前指令,才进中断,所以在中断开头哪里,读取定时器值来做修正,保证任何情况下,都在定时器达到计数值后的同一个延迟开始运行中断

SIGNAL(TIMER1_COMPA_vect)
{
__asm__                 \
    ( "lds r24,TCNT1L" "\n\t"        \
            "cpi r24,27" "\n\t" \
            "brlo LATFIX1" "\n\t" \
                        "LATFIX1:" "\n\t" \
                        "cpi r24,28" "\n\t" \
                        "brlo LATFIX2" "\n\t" \
                        "LATFIX2:" "\n\t" \
                        "cpi r24,29" "\n\t" \
                        "brlo LATFIX3" "\n\t" \
                        "LATFIX3:" "\n\t" \
                        "cpi r24,30" "\n\t" \
                        "brlo LATFIX4" "\n\t" \
                        "LATFIX4:" \
          );

        PORTC=        1        ;
        PORTC=        2        ;
        PORTC=        3        ;
        PORTC=        4        ;
        PORTC=        5        ;
        增加这些指令来调节时间,或改为一个循环
}
作者: qiannengneng    时间: 2014-8-2 11:32
fp123123 发表于 2014-7-30 21:46
用汇编指令,在中断里用指令来定时,这样很准确,不会汇编也没关系,会改就行,下面这个是用MEGA644做的VGA ...

在中断函数内,人为的延时来修正进入中断前的误差?可是这样的话,原本定的10us一次中断就没意义了吧?比如如果要精确10us的时间,计数器就应该以9us一次中断来初始化,然后剩下1us在中断函数内部通过适当的延时来得到?这样的话还是得要看汇编来计算时钟周期吧?
我还是先去学习一下汇编吧。
谢谢指导
作者: fp123123    时间: 2014-8-2 23:17
8M的AVR,10us可以执行80条指令,计数器设置为10us一次中断,前面才几条修正指令,离80条指令远着呢,完全可以做到10us精确输出;其实也可以直接设置计数器硬件输出精确脉冲,不需要中断函数方法
作者: zhaoyu2005    时间: 2014-8-14 14:22
不知道有自动重装计数值的定时器没,如果有的话,用这种类型的定时器,精度很高的。




欢迎光临 21ic电子技术开发论坛 (https://bbs.21ic.com/) Powered by Discuz! X3.5