红外遥控器发送数据时,是将二进制数据调制成一系列的脉冲信号红外发射管发射出去,红外载波为频率38KHz的方波,红外接收端在收到38KHz的载波信号时,会输出低电平,否则输出高电平,从而可以将“时断时续”的红外光信号解调成一定周期的连续方波信号,再经过1838一体化红外接收头解调便可以恢复出原数据信号。如图1所示
图1 红外接收头解调过程如图2所示
图2 解调后的“0”和“1”波形及单片机编码图3、图4所示
图3
图4 图5 了解了红外接收头解调及遥控编码下面就可以对照图5编写编码程序了,图5是遥控按键1的一段实际编码,由9ms低电平4.5ms高电平的启始码,26位系统码,及8位数据码、8位数据反码、23ms高电平及结束码组成。
实物图 ********以下是遥控完整程序******** /******** **项目: 自制红外电视遥控器(EE01学习板演示程序) **作者:一线工人 **网站:电子工程师之家 www.eehome.cn **转贴请保持代码的完整性 ********/ #include 《reg52.h》 #define uint unsigned int #define uchar unsigned char bit irout;//红外管状态 sbit ir=P1^7;//红外发射管控制脚 uint count, set_count;//中断计数,设定中断次数 bit flag,keyflag;//红外发送标志,按键标志位 uchar irsys[4]={0x1a,0xa1,0xdc,0x03};//26位系统码,最后一个字节只用2位 uchar ircode,irdata; /********************************************** 延时1ms ***********************************************/ void delay(uint z)//延时1ms,晶振22.1184M { uint x,y; for(x=z;x》0;x--) for(y=225;y》0;y--); } /********************************************** 按键扫描 **********************************************/ void keyscan(void) { uchar keytemp; P3=0xff; keytemp=P3&0x0f; if(keytemp!=0x0f) { delay(20); keytemp=P3&0x0f; if(keytemp!=0x0f) keyflag=1;//有按键标志 switch(keytemp) { case 0x0e:irdata=27;break;//按键1对应该遥控器P+的键值 case 0x0d:irdata=26;break;//按键2对应该遥控器P-的键值 case 0x0b:irdata=31;break;//按键3对应该遥控器VOL+的键值 case 0x07:irdata=30;break;//按键4对应该遥控器VOL-的键值 } } } /******************************************* 发送8位红外数据 *******************************************/ void sendcode_8(void) { uchar i; for(i=0;i《8;i++) { set_count=28;//发送0.56ms 38k红外波(编码中的0.56ms低电平) flag=1; count=0; TR0=1; while(count《set_count); TR0=0; if(ircode&0x01)//判断红外编码最低位,1宽的高电平,0窄的高电平 { set_count=120; } else { set_count=38; } flag=0; count=0; TR0=1; while(count《set_count); TR0=0; ircode=ircode》》1; } } /******************************************* 发送2位红外数据 *******************************************/ void sendcode_2(void)//前26位系统码最后两位 { uchar i; for(i=0;i《2;i++) { set_count=28; flag=1; count=0; TR0=1; while(count《set_count); TR0=0; if(ircode&0x01) { set_count=120; } else { set_count=38; } flag=0; count=0; TR0=1; while(count《set_count); TR0=0; ircode=ircode》》1; } } /******************************************* 发送红外数据 *******************************************/ void sendcode(void) { set_count=575;//发送9ms 38K红外光 flag=1; count=0; TR0=1; while(count《set_count); TR0=0; set_count=320;//间隔4.5ms flag=0; count=0; TR0=1; while(count《set_count); TR0=0; ircode=irsys[0];//发送26位系统码的前1-8位 sendcode_8(); ircode=irsys[1];//发送26位系统码的前9-16位 sendcode_8(); ircode=irsys[2];//发送26位系统码的前17-24位 sendcode_8(); ircode=irsys[3];//发送26位系统码的前24-26位 sendcode_2(); ircode=irdata;//发送8位数据码 sendcode_8(); ircode=~irdata; //发送8位数据反码 sendcode_8(); set_count=28;//发送0.56ms 38k红外波(编码中的0.56ms低电平) flag=1; count=0; TR0=1; while(count《set_count); TR0=0; ir=1; delay(23);//延时23ms(编码中的23ms高电平) set_count=575;//发送9ms 38k红外波 flag=1; count=0; TR0=1; while(count《set_count); TR0=0; set_count=330;//间隔4.5ms flag=0; count=0; TR0=1; while(count《set_count); TR0=0; set_count=30;//发送0.56ms 38k红外波(编码中的0.56ms低电平) flag=1; count=0; TR0=1; while(count《set_count); TR0=0; ir=1; } /******************************************* 定时器初始化 *******************************************/ void init_timer() { EA=1; TMOD=0X02;//8位自动重载模式 ET0=1; TH0=0XE8;//定时13us,38K红外波,晶振22.1184 TL0=0XE8; } /******************************************* 主函数 *******************************************/ void main(void) { init_timer(); count=0; flag=0; irout=1; while(1) { keyscan(); if(keyflag)//若有新按键 { delay(10); sendcode();//发送红外编码 delay(500); keyflag=0;//按键标志清零 } } } /******************************************* 定时器中断 *******************************************/ void timer0(void) interrupt 1 { count++; if(flag==1) { irout=~irout; } else { irout=1; } ir=irout; }
|
|
来自: ldjsld > 《电脑手机及电子技术》