开放实验报告课题名称基于单片机的红外解码器的设计学生姓名系、年级专业信息工程系、11、12级电子信息工程指导教师江世明2014年 5 月20日基于单片机的红外解码器的设计一.实验目的1、了解红外编码原理,模拟红外发射信号;2、用程序实现红外编码的解码;二.实验内容设计基于单片机的红外解码器,实现红外遥控信号智能解码,要求制作出实物,实现解码功能。
三.电路设计1、红外编码原理在实际应用中红外编码将二进制码调制到38MHz的载波频率上,通过在空中传播,由红外接收头接收之后,由内部的解调电路进行解调, 解调出来的就是我们发送的那些二进制码。
红外编码方式根据日本NEC 协议编码。
每次发送四个字节:用户码,用户反码,数据码,数据反码。
数据 0和 1的区别通常体现在高低电平的时间长短上。
一次按键首先发送9ms的低电平和4.5ms的高电平的引导码。
实际生活中,用遥控器发出的信号与上面的信号是相反的,经过红外线接收头解码以后就和上图一样了,值得大家注意的是发射模块的芯片不同,引导区的时间和数据都有所不同,但解决的方法都是一样的。
引导码后就是用户码。
但是怎么来区分0和1呢?前面我们提到了PWM(脉宽调制)。
根据脉冲的宽度来区别0和1.0.56ms低电平之后接0.56ms高电平为0,接1.12ms高电平为1.2、红外解码方法在实际生活中红外解码一般由红外接收头接收并解码。
解码时先跳过9ms 高电平和4.5ms的低电平,然后跳过0.56ms的低电平,最后通过循环等待搞电平的结束并计时。
通过判断高电平时间的长短来区分0(0.56ms)和1(1.12ms)。
最后判断接收到的四个字节(用户码,用户反码,数据码,数据反码)中数据码和取反后的数据反码相不相等。
3、红外编解码电路四、程序设计见附录五、系统仿真仿真分析:仿真照片如上图,当从4*4键盘按下K5时,单片机U1的数码管显示5,同时P3.0发送出如下图所示的脉冲。
上图包含了9ms高电平和4.5ms低电平的引导码和4字节(32位)的信息码,包括用户码(00000000),用户反码(11111111),数据码(00001001),数据反码(11110110)。
六、结论通过本次试验用软件模拟了红外发送编码与接收解码的过程。
基本上可以脱离硬件实现红外的发送与接收。
但是本实验还是存在一些问题,发送信号没有用38Khz的载波频率载波和实际的发送信号应该与本实验相反。
所以做实物时应该考虑这些问题。
附录:发送程序:#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar IR[4]; //全局变量存放发送数据sbit IRIN=P3^4;// 发送脚sbit BEEP = P3^0;// 蜂鸣器void SendData();void Delay(uint x);void Delay_112();void Delay_56();void Delay_50();void Key_scan();void Beep();uchar DM[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1 ,0x86,0x8e,0xff};void main(){uchar t=16;IR[2]=16;while(1){Key_scan();P0 = DM[IR[2]];if(t!=IR[2]) //保证每次只发送一个数据缺点:每个键不能重复发送{t=IR[2]; //保护IR[2]的值Beep();SendData();IR[2]=t; //还原IR[2]的值}Delay(100);}}void SendData(){uchar k,i,t;IR[1]=~IR[0]; //用户码取反IR[3]=~IR[2]; //数据码取反IRIN=0;Delay(9); //假设9ms低电平发射IRIN=1;Delay(4); //4.5ms高电平Delay_50();for(k=0;k<4;k++)for(i=0;i<8;i++){IRIN=0;Delay_56();t=IR[k]; //保存IR[k]的值if(IR[k]>>=7) //取最高位{IRIN=1;Delay_112();}else{IRIN=1;Delay_56();}t<<=1; //次高位变为最高位IR[k]=t;}IRIN=0;//保证最后一个脉冲的高电平时间Delay_56();IRIN=1;}void Key_scan(){uchar i;P1=0x0f;if(P1!=0X0f){Delay(2); //消抖if(P1!=0x0f)switch(P1){case 0x0e: i=0;break;case 0x0d: i=1;break;case 0x0b: i=2;break;case 0x07: i=3;}Delay(1);P1=0xf0;switch(P1){case 0xe0: i+=0;break;case 0xd0: i+=4;break;case 0xb0: i+=8;break;case 0x70: i+=12;}IR[0]=0; //用户码为0IR[2]=i;}}void Beep(){uchar i,j;for(i=0;i<100;i++){for(j=0;j<123;j++);BEEP=~BEEP;}BEEP=1;}void Delay(uint x){uint i,s;for(i=x;i>0;i--)for(s=127;s>0;s--);}void Delay_112(){uint m,n;for(m=1;m>0;m--)for(n=142;n>0;n--);}void Delay_56(){uint m,n;for(m=1;m>0;m--)for(n=68;n>0;n--);}void Delay_50(){uint m,n;for(m=1;m>0;m--)for(n=64;n>0;n--);}接收程序:#include <reg51.h>#define uchar unsigned char#define uint unsigned int#define SMG P0sbit IRIN=P2^7; //红外线输入sbit TS=P1^0; //显示灯void Delay(uint x);void Delay_50();void ReadIR();uchar IR[4];uchar DM[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1 ,0x86,0x8e,0xff};void main(){IR[2]=16;//关显示while(1){ReadIR();Delay(10);if(IR[2]>=16) //接收到的值大于等于16关显示SMG=DM[16];elseSMG=DM[IR[2]];} }void ReadIR(){uchar i,j,time;if(IRIN==0){while(IRIN==0); //等待9ms的引导码过去if(IRIN==1){while(IRIN==1); //等待4.5ms的引导码过去IR[2]=0; //重新给数据码清零for(i=0;i<4;i++){for(j=0;j<8;j++){while(IRIN==0); //等待560us的低电平过去while(IRIN==1){time++; //计时Delay_50();}IR[i]<<=1; //因为有8次循环为了保证最后一次为个位if(time>=6){IR[i]|=0x01;}time=0; //计时清零}}TS=0; //灯闪烁提示Delay(200);TS=1;}}}void Delay(uint x){uint i,s;for(i=x;i>0;i--)for(s=127;s>0;s--);}void Delay_50(){uint m,n;for(m=1;m>0;m--)for(n=20;n>0;n--);}。