搜索
bottom↓
回复: 10

AVR输入捕捉精度太差

[复制链接]

出0入0汤圆

发表于 2014-10-31 16:22:04 | 显示全部楼层 |阅读模式
这是我的程序,八分频,想要采集周期是16ms脉宽是1.94ms左右的高电平时间,我采集到的数据从1.82到2.07一直在这个范围里,
误差应该没有这么大啊,不知道到底怎么搞的,求大神帮助

void port_init(void)
{
    PORTD = 0xFF;
        DDRD = 0xBF;
}
void ICEInit(void)  
{   
    port_init;
    TCCR1A=0X00;//时钟与系统相同
        TCCR1B=0XC2;//使能噪声抑制,上升降沿触发,八分频,周期为1us
        TIMSK=0X20;//使能捕获中断
}
#pragma interrupt_handler CAPT_ISP:0x0A

void CAPT_ISP(void)
{
     unsigned char sreg;
     if(TCCR1B&(1<<ICES1))//假如是上升沿中断
         {
                 TCNT1=0;//TCNT1清零
                 TCCR1B^=(1<<ICES1);//设置为下降沿中断
         }
         else //假如是下降沿中断
         {
             sreg = SREG;
                 _CLI();
             up = TCNT1;
                 up |= ((unsigned int)TCNT1H<<8);
                 down = (up/10);
                 SREG = sreg;
                 TCCR1B|=(1<<ICES1);
         }
         TIFR&=(1<<ICF1);//清除中断标志位
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2014-10-31 16:32:30 | 显示全部楼层
你应该捕捉一次上升沿然后再捕捉一次下降沿,两者的差就是脉宽。TCNT1不能清0,否则当然有很大误差了。

出0入0汤圆

 楼主| 发表于 2014-10-31 16:56:48 | 显示全部楼层
YZDREAM8 发表于 2014-10-31 16:32
你应该捕捉一次上升沿然后再捕捉一次下降沿,两者的差就是脉宽。TCNT1不能清0,否则当然有很大误差了。 ...

我设置了一下,在上升沿里面把TCNT1的值给up,然后设置下降沿中断,再把值给down,两个值相减,结果误差还是那么大,和原来的值基本没差别啊
#pragma interrupt_handler CAPT_ISP:0x0A

void CAPT_ISP(void)
{
     unsigned char sreg;
         unsigned char ssreg;
     if(TCCR1B&(1<<ICES1))//假如是上升沿中断
         {
             ssreg = SREG;
                 _CLI();
             up = TCNT1L;
                 up |= ((unsigned int)TCNT1H<<8);
                 //TCNT1=0;//TCNT1清零
                 SREG = ssreg;
                 TCCR1B^=(1<<ICES1);//设置为下降沿中断
         }
         else //假如是下降沿中断
         {
             sreg = SREG;
                 _CLI();
             down = TCNT1L;
                 down |= ((unsigned int)TCNT1H<<8);
                 down = (down - up)/10;
                 SREG = sreg;
                 TCCR1B|=(1<<ICES1);
         }
         TIFR&=(1<<ICF1);//清除中断标志位
}

出0入0汤圆

发表于 2014-10-31 17:03:56 | 显示全部楼层
本帖最后由 YZDREAM8 于 2014-10-31 17:08 编辑

你确信DOWN就必UP的值大吗?要加判断的。而且你传递的是TCNT1的值,应传递捕获寄存器的值。

出0入0汤圆

 楼主| 发表于 2014-10-31 17:09:17 | 显示全部楼层
YZDREAM8 发表于 2014-10-31 17:03
你确信DOWN就必UP的值大吗?要加判断的。

我又加了个判断语句
if(down > up)
{
        down = (down - up)/10;
  }
很不幸,结果还是在182到207跳变

出0入0汤圆

发表于 2014-10-31 17:10:32 | 显示全部楼层
要用捕获寄存器的值。不是TCNT1的值。

出0入0汤圆

 楼主| 发表于 2014-10-31 17:23:32 | 显示全部楼层
YZDREAM8 发表于 2014-10-31 17:10
要用捕获寄存器的值。不是TCNT1的值。

嗯,差不多了,但是好像在边界的地方会有错误,为什么不能读取TCNT1的数值呢?在输入捕捉的时候,ICR1寄存器中的数值不就是TCNT1送过去的呢?为什么差别会这么大?
在边界值处理的地方应该怎么去处理呢?

出90入372汤圆

发表于 2014-10-31 17:28:04 | 显示全部楼层
告别AVR 很多年   

出0入0汤圆

发表于 2014-10-31 19:15:34 | 显示全部楼层
本帖最后由 YZDREAM8 于 2014-10-31 19:17 编辑

ICR1的值对应于捕捉时刻TCNT1的值,你在中断里读TCNT1的值显然是捕捉发生后一段时间的值。你要把AVR手册里的讲解仔细地研读。边界处理你仔细想下就会了。

出0入0汤圆

 楼主| 发表于 2014-11-1 11:44:28 | 显示全部楼层
YZDREAM8 发表于 2014-10-31 19:15
ICR1的值对应于捕捉时刻TCNT1的值,你在中断里读TCNT1的值显然是捕捉发生后一段时间的值。你要把AVR手册里 ...

好的 谢谢啊

出0入0汤圆

发表于 2014-11-7 23:51:17 | 显示全部楼层
谢谢分享!!!!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 04:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表