|
keil c51程序适用uPC1621/uPC1622及兼容的红外遥控器芯片,占用外部中断0和定时器1,以中断方式解码,节省系统资源,以查询方式检测遥控信号是否有效. 解码思路: 红外线经一体化接受头解码放到后送到单片机的外部中断0,单片机设置外部中断下降沿触发,T0和T1为16位定时器,T0在系统启动后定时5ms.T1在外部中断0启动后开始定时,初值为0,每次在INT0中断后先读T1计数值,并重设初值为0,而且判断T1的计数值, 代码 //Fosc=11.0592MHz // states for and variables IR data processing ; typedef enum{ IR_idle, IR_waitstart, IR_getaddr, IR_getaddrinv, IR_getdata, IR_getdatainv }_IRstate; _IRstate IRstate = IR_idle; unsigned char IRaddr=0xff; unsigned char _IRaddr=0xff; unsigned char IRdata=0xff; unsigned char _IRdata=0xff; unsigned char IR_repeat=0; unsigned char IR_ready=0; unsigned char IR_poweron=0; //bit ir_done=0; // time constants unsigned int IRtimer=0; // IR timeout //cpu初始化 void cpu_init(void) { TMOD=0X11; // T0 and T1 十六位定时 TH0=0xee; //fosc=11.0592M,timer=5ms TL0=0x00; TR0=1; // run timer 0; TF0=0; ET0=1; // enable tmr 0 overflow interrupt IT0=1; // int0 edge sensitive EX0=1; // enable "int0" EA=1; // global interupt enable } //T0中断 void tmrint() interrupt 1 { TH0=0xee; TL0=0x00; if (IRtimer) //IR接收超时 --IRtimer; // else { IRstate=IR_idle; // IR_poweron=0; } } //Fosc=11.0592MHz #define msec_12p5 0x2d00 #define msec_15 0x3600 #define msec_9 0x2066 //#define msec_9 0x1066 #define msec_2p5 0x900 #define msec_0p9 0x33d #define msec_1p68 0x610 //void IRint() interrupt 0(void) //When the IR receive pin goes low and interrupt is generated // IR is collected by starting timer 2 in the first falling edge of the pin // then on every other falling edge, the timer value is saved and the timer restarted . // the captured time is then used to get the IR data // a "start of data" is 13.5Msec,a "1" is 2.25Msec,a "0" is 1.12 msec and a "repeat" is 11.25msec. // the counter increments at 1.085 Usec // I allow a fairly large tolerance to time jitter but there are no false triggers seen. void IRint() interrupt 0 { static unsigned char bits; unsigned short time; switch(IRstate) { case IR_idle: TL1=0; TH1=0; TR1=1; IRstate=IR_waitstart; IRtimer=26; break; case IR_waitstart: //P2_4=!P2_4; TR1=0; time=TH1; time =(time <<8)+TL1;; TL1=0; TH1=0; TR1=1; if ((time > msec_12p5)&&(time < msec_15)) // greater than 12.5Msec & less than 15 msec = start code { IRaddr=0; _IRaddr=0; IRdata=0; _IRdata=0; bits=1; IRstate=IR_getaddr; } else if ((time > msec_9)&&(time < msec_12p5))// less than 12.5Msec and greater than 9 msec =Repeat code { IR_repeat=2; IRstate=IR_idle; } else { // to short, bad data just go to idle IRstate=IR_idle; } break; case IR_getaddr: // P2_4=!P2_4; TR1=0; time=TH1; time =(time <<8)+TL1;; TL1=0; TH1=0; TR1=1; if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5msec or shorter than .9Msec bad data , go to idle { IRstate=IR_idle; break; } if (time>msec_1p68)// greater than 1.68Msec is a 1 { IRaddr|= bits; } bits=bits<<1; if (!bits) { IRstate=IR_getaddrinv; bits=1; } break; case IR_getaddrinv: //P2_4=!P2_4; TR1=0; time=TH1; time =(time <<8)+TL1;; TL1=0; TH1=0; TR1=1; if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5msec or shorter than .9Msec bad data , go to idle { IRstate=IR_idle; break; } if (time>msec_1p68)// greater than 1.68Msec is a 1 { _IRaddr|= bits; } bits=bits<<1; if (!bits) { IRstate=IR_getdata;; bits=1; } break; case IR_getdata: TR1=0; time=TH1; time =(time <<8)+TL1;; TL1=0; TH1=0; TR1=1; if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5msec or shorter than .9Msec bad data , go to idle { IRstate=IR_idle; break; } if (time>msec_1p68)// greater than 1.68Msec is a 1 { IRdata|= bits; } bits=bits<<1; if (!bits) { IRstate=IR_getdatainv; bits=1; } break; case IR_getdatainv: TR1=0; time=TH1; time =(time <<8)+TL1;; TL1=0; TH1=0; TR1=1; if ((time>msec_2p5)||(time<msec_0p9)) // if > 2.5msec or shorter than .9Msec bad data , go to idle { IRstate=IR_idle; break; } if (time>msec_1p68)// greater than 1.68Msec is a 1 { _IRdata|= bits; } bits=bits<<1; if (!bits) // we have it all , now we make sure it is a NEC code from the CHS IR transmitter { // make sure address,~address are correct , data ,~data are correct and address is 0. IR_ready=((IRaddr^_IRaddr)==0xff)&&((IRdata^_IRdata)==0xff)&&(IRaddr==0); if(IR_ready) { IRstate=IR_idle; } } break; default: IRstate=IR_idle; break; } } void main(void) { cpu_init(); while(1) { if(IR_ready) { IR_ready=0; switch(IRdata) { case 0x45: //1 //your code break; case 0x44: //3 //your code break; case 0x43: //4 //your code break; case 0x08: //prev //your code break; case 0x5a: //next //your code break; default: break; &n bsp; } } } }
下一篇链接:基于C51TEA5767的收音机模块控制程序
上一篇链接:51单片机C语言编程基础和实例(共八节)
|