打印
[AVR单片机]

M16 T/C1 输入捕获问题

[复制链接]
2466|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
d5252yh0307|  楼主 | 2013-6-23 11:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在做个项目,刚好用到T/C1输入捕获这个功能,但在看一些输入捕获的例程有些不明白。

程序是这样的:

interrupt[TIMI_CAPT] void timer1_isr(void)
{
  a_temp=a;
  a_L=ICR1L;
  a_H=ICR1H;
  a=a_H*256+a_L;
  if(a<a_temp)
    {
      count=0xffff-a_temp+1+a;    //这个部分分怎么理解?
     }
   else
     {
       count=a-a_temp;                 //这个计算电平时间
    }
   TIFR=0x20;
}红色部分的不理解,请高手帮忙分析分析下。




相关帖子

沙发
qin552011373| | 2013-6-23 22:13 | 只看该作者
有什么不理解  

使用特权

评论回复
板凳
d5252yh0307|  楼主 | 2013-6-24 00:00 | 只看该作者
qin552011373 发表于 2013-6-23 22:13
有什么不理解

count=0xffff-a_temp+1+a这条是什么意思?不明白。能讲解下嘛?

使用特权

评论回复
地板
qin552011373| | 2013-6-24 10:42 | 只看该作者
d5252yh0307 发表于 2013-6-24 00:00
count=0xffff-a_temp+1+a这条是什么意思?不明白。能讲解下嘛?

贴完整的程序

使用特权

评论回复
5
d5252yh0307|  楼主 | 2013-6-24 13:13 | 只看该作者
这是个超声波测距的程序,太长了。我就贴出相关的程序出来。其中红色的部分不是很理解。为什么是65536-(ICP_lastValue+1+ICP_value )。


//==========================定时器1初始化子程序=============================
void timer1_init(void)
{
TCNT1 = 0x00;          //定时0ms的初始值
TCCR1A = 0x00;
TCCR1B = 0x42;             //上升沿捕获,时钟8预分频
}
//============================设备初始化子程序==============================
void init_devices(void)
{
timer1_init();
InitLcd();                     //LCD初始化
TIMSK = 0x20;                 //使能T/C1的捕获中断
SREG = 0x80;                 //使能总中断
}
//=============启动超声波发送==================
void send(void)
{
  unsigned char k;
  Trig = 1;               //触发口拉高电平
  for(k=0;k<50;k++);            //延时大于10us
  Trig = 0;               //触发口拉低电平
}
//==================主函数=====================
void main(void)   
{
  DDRA=0xff;PORTA=0x00;
  DDRB=0xff;PORTB=0x00;
  DDRC=0xff;PORTC=0xff;
  DDRD=0x00;PORTD=0xff;         //初始化I/O口,其中ICP1口(PD6)必须设置成输入形式
  init_devices();                                 //设备初始化
  ePutstr(0,0,str0);    //第一行显示红外数据宽度(格式)
  while(1)
  {
    send();             //启动一次超声波发送
    delay_nms(10);
    DisplayOneChar(12,0,times%10+0x30);   //显示距离的个位
    delay_nms(10);
    DisplayOneChar(11,0,(times/10)%10+0x30);   //显示距离的十位
    delay_nms(10);
    DisplayOneChar(10,0,times/100+0x30);   //显示距离的百位
    delay_nms(50);
  }
}
//===================中断函数(定时器1输入捕获中断)=============================
#pragma vector = TIMER1_CAPT_vect
__interrupt void TIMER1_CAPT_Server(void)
{
  if(TCCR1B_Bit6==1)            //若捕获的是上升沿
    {
      ICP_lastValue=ICR1;       //读取ICP输入捕捉上升沿的发生时刻
      TCCR1B_Bit6 = 0;             //改为下降沿捕获
    }
  else                        //若捕获的是下降沿
    {
      ICP_value=ICR1;       //读取ICP输入捕捉下降沿的发生时刻
      TCCR1B_Bit6 = 1;             //改为上升沿捕获
      if(ICP_lastValue>ICP_value)
        times=0xffff-ICP_lastValue+1+ICP_value;
      else
        times=ICP_value-ICP_lastValue;          //计算高电平的宽度

      times=times/58;                         //把us换算成cm
    }
}



使用特权

评论回复
6
d5252yh0307|  楼主 | 2013-6-24 13:36 | 只看该作者
qin552011373 发表于 2013-6-24 10:42
贴完整的程序

这个问题我已经解决了。知道是怎么回事了。一下子没转过来。:P  谢谢咯。

使用特权

评论回复
7
qin552011373| | 2013-6-24 13:37 | 只看该作者
d5252yh0307 发表于 2013-6-24 13:36
这个问题我已经解决了。知道是怎么回事了。一下子没转过来。  谢谢咯。 ...

恭喜

使用特权

评论回复
8
d5252yh0307|  楼主 | 2013-6-24 20:26 | 只看该作者
方便以后给遇到相关问题的朋友们借鉴下:times=0xffff-ICP_lastValue+1+ICP_value; 这条语句的含义是,当捕获到的上升沿在第一周期,而下降沿捕获在第二周期的时候,times=最大值65536-上升沿(第一周期)+下降沿(第二周期)就是整个电平的时间。而第二条语句是上升沿和下降沿都是同一周期的时,相减就是电平的时间。

使用特权

评论回复
9
英子04802| | 2015-5-13 10:17 | 只看该作者
第一条语句是溢出处理,第二条语句是没有溢出的处理。

使用特权

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

本版积分规则

8

主题

32

帖子

0

粉丝