打印
[AVR单片机]

如何使用avr实现较精确延时

[复制链接]
2861|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qiannengneng|  楼主 | 2014-7-28 12:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我使用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个指令周期
也就是说每次 ...

不仅包含你写的语句,实际使用的时钟数你可以看看汇编代码啊,很多的

使用特权

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

额,汇编目前还不会

使用特权

评论回复
6
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        ;
        增加这些指令来调节时间,或改为一个循环
}

使用特权

评论回复
7
qiannengneng|  楼主 | 2014-8-2 11:32 | 只看该作者
fp123123 发表于 2014-7-30 21:46
用汇编指令,在中断里用指令来定时,这样很准确,不会汇编也没关系,会改就行,下面这个是用MEGA644做的VGA ...

在中断函数内,人为的延时来修正进入中断前的误差?可是这样的话,原本定的10us一次中断就没意义了吧?比如如果要精确10us的时间,计数器就应该以9us一次中断来初始化,然后剩下1us在中断函数内部通过适当的延时来得到?这样的话还是得要看汇编来计算时钟周期吧?
我还是先去学习一下汇编吧。
谢谢指导

使用特权

评论回复
8
fp123123| | 2014-8-2 23:17 | 只看该作者
8M的AVR,10us可以执行80条指令,计数器设置为10us一次中断,前面才几条修正指令,离80条指令远着呢,完全可以做到10us精确输出;其实也可以直接设置计数器硬件输出精确脉冲,不需要中断函数方法

使用特权

评论回复
9
zhaoyu2005| | 2014-8-14 14:22 | 只看该作者
不知道有自动重装计数值的定时器没,如果有的话,用这种类型的定时器,精度很高的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

6

帖子

0

粉丝