|
只用了一个定时器,不用外部中断。红外一体管信号脚接PB1,使用MEGA16
由于实际测量信号电平有干扰,不得不多加个行代码鉴定开始位
点击此处打开armok0168768.pdf
请高手指教
#include <iom16v.h>
#include <macros.h>
#pragma interrupt_handler timer1_ovf_isr:9
#pragma interrupt_handler timer1_compa:7
unsigned char IRstate=0;//红外接收状态
void timer1_compa(void);
void timer1_ovf_isr(void);
void gotonom(void);
void timer1_ovf_isr(void)//第一次得到低电平
{ OCR1A=3360; //隔0.42毫秒后进入第一个电平检测中间检查
TCCR1B=0x09; //使用比较中断较精确
TIMSK=0x10;
}
void timer1_compa(void) //红外接收状态1~29(检测27次电平状态)
{unsigned char i,j;
static unsigned char IRcode[24],code,e=0;//IRcode[24]:记录电平;code:数据码;e:错误标记
switch(IRstate)
{
case 0:
if((PINB&0x02)==0)//第一次电平为低
{IRstate=1;
OCR1A=6760; //0.845毫秒后进入第二个电平中间检查
code=0;
e=0;
}
else //否则回到正常等待状态
gotonom();
break;
case 1:
if((PINB&0x02)!=0)//第二次电平为高
{IRstate=2; //0.845毫秒后进入第三个电平中间检查
}
else
gotonom(); //否则回到正常等待状态
break;
case 2:
if((PINB&0x02)==0)//第三次电平为高
{IRstate=3; //0.845毫秒后进入第四个电平中间检查
}
else
gotonom(); //否则回到正常等待状态
break;
default: //第4到第27个电平检测
IRstate++;
if(IRstate<28)
IRcode[IRstate-4]=((PINB&0x02)!=0); //贮存第4到第27个电平
else //state=28 or 29
{//2
if(IRstate==28)//state=28
{//1
IRstate=29;//212毫秒内不接收
OCR1A=1612;
TCCR1B=0x0D;
for(i=0;i<24;i+=2)//处理结果
{//L2
if(IRcode==IRcode[i+1])//接收错误
{//L1
e=1;
gotonom();//取消212毫秒内不接收,马上回到等待状态
break;
}//L1
else //接收正确则解码
{//S1
if (i>11) //从第十一个开始
{ j=1;
j<<=((22-i)/2);
code+=j*IRcode;
}
}//S1
}//L2
if(e==0)
{
//接收到红外信息的动作
}
}//1
else//state=29;回到正常
gotonom();
}//2
break;
}
}
void gotonom(void)//回到正常等待状态
{
IRstate=0;
TIMSK=0x04;
TCNT1=65535;
TCCR1B=0x06;
}
void main(void)
{
DDRB=(~0x02);//初始化PB1
PORTB|=0x02;
TIMSK|=0x04;//初始化TC1,正常等待状态
TCNT1=65535;
TCCR1A=0;
TCCR1B=0x06;
SEI();
while(1)
{
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|