各位大神,Atmega16当中如何实现精准的微秒级延时

2019-03-24 20:25发布

本人正在使用Atmega16a-au芯片,利用它的中断0来获取PD2的19位输入信号,由于输入信号有着严格的周期。因此在程序里使用了延时函数进行处理,但CVAVR里面的延时函数精度不是很高,因而造成在获取信号时,越到后面的位数时间差距越大,以至于最后一位完全无法正确获取,不知哪位大神有CVavr下的atmega16a芯片的精确延时处理方法,请赐教 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
16条回答
ltwsq
2019-03-25 16:33
本帖最后由 ltwsq 于 2015-4-15 11:39 编辑
dcexpert 发表于 2015-4-15 10:21
你把程序放上来,大家讨论一下。



如果是调用函数方式,因为调用函数时,也需要指令,也会占用时间。如果精度要求不高,当然没有关系;如果你需要us级精度,就需要仔细调试,甚至用汇编了。


使用的是atmega16a芯片,晶振8M
time0的初始化代码:
void TC0_init(void)
{
    TCCR0=0x00; //定时器停止
    TCNT0=0x36; //计数初值计算为48(调试修改为54)     计数初值=最大计数值-[t(计时时间)*工作频率]/分频数 ,本例中=256-(208us*8MHz)/8=48
    OCR0= 0xD0; //比较值 =最大计数值-计数初值=256-48 = 208   
}
time0的中断服务代码:
interrupt [TIM0_OVF] void timer0_isr(void)
{
    TCNT0=0x36;//重置计数初值--调试之后修改为54
    i_count++; //每计时208us,计数器自加1
}
自己的delay函数,该函数定时是以208us为基数的定时(输入参数为定时208us的次数)
void mydelay(int times)
{
   TCCR0=0x02; //定时器开始,8分频
    while(1)
    {  
        if (times==i_count)
        {
            TCCR0=0x00;//到达计时时间,Time0停止工作
            i_count = 0; //计时计数器归0,为下次计数做准备
            break; //跳出循环
        };
    };
}
上面的三个结果是连续执行三次出现的,唉!

一周热门 更多>