声明部分内容摘自:
http://www.hificat.com/dpj_step/compositive_7.html
http://www.ceet.hbnu.edu.cn/bbs/viewthread.php?tid=102
转自:http://my.oschina.net/jayzonex/blog/10649
1、红外遥控系统
下面,我们将使用下面两种设备:
由上图所示,当一个键按下超过22ms,振荡器使芯片激活,将发射一组108ms的编码脉冲(由位置1所示)。如果键按下超过108ms仍未松开,接下来发射的代码(连发代码由位置3所示)将仅由起始码(9ms)和结束码(2.5ms)组成。下面把位置1的波形放大:
放大,位定义0和位定义1波形如下:
注:代码宽度算法:
16位地址码的最短宽度:1.12×16=18ms 16位地址码的最长宽度:2.24ms×16=36ms
可以得知8位数据代码及其8位反代码的宽度和不变:(1.12ms+2.24ms)×8=27ms
#include #include // 函数原型 void SystemInit(void); void Delay_840us(void); void Delay_2400us(void); void LedDisp(); unsigned char GetCode(void);//获得码 void delay(unsigned char loop); // 位变量 sbit IRIN = P3^2; sbit BEEP = P1^6; sbit swch = P1^7; // 变量 unsigned char KeyValue; //机器码 unsigned char MaValue; //键值码; unsigned char disbuf[4]; //数码管显示缓冲 unsigned char scan[4]={0x04,0x08,0x10,0x20}; //p2位选择 unsigned char code table[16] = //共陰碼 {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7C,0x39,0x5E,0x79,0x71}; /** * 延时 */ void delay(unsigned char loop) { unsigned char i; for(i=0;i>8); TR1=1; while(!TF1); TF1=0; TR1=0; } /** * 延时9ms */ void Delay_9000us(void) { TL1 = 153.6; TH1 = 223.6; TR1 = 1; while(!TF1); TF1 = 0; TR1 = 0; } /** * 延时4.5ms */ void Delay_4500us(void) { TH1 = 239.8; TL1 = 204.8; TR1 = 1; while(!TF1); TF1 = 0; TR1 = 0; } /** * 系统初始化 */ void SystemInit(void) { IRIN = 1; IT0 = 1; //INT0负跳变触发 TMOD = 0x10; //定时器1工作在方式1 EA = 1; EX0 = 1; } /** * 读码 */ unsigned char GetCode() { unsigned char n; static temp = 0; for( n = 0; n < 8; n++ ) { while(!IRIN); // 等待高电平,开始解码 Delay_840us(); // 延时0.84ms if(IRIN) // 若仍然为高电平,则为1,否则为0 { temp = (0x80|(temp>>1)); // 1 while(IRIN); //等待跳变成低电平 } else { temp=(0x00|(temp>>1)); // 0 } } return temp; } /** * 数码管显示 */ void LedDisp() { unsigned char i; for(i=0;i<4;i++) { P0=table[disbuf[i]]; P2 = scan[i]; delay(50); P0=0x00; } } void main(void) { SystemInit(); while(1) { //以下是查表显示 disbuf[0]=(((KeyValue&0xf0)>>4)&0x0f); disbuf[1]=KeyValue&0x0f; disbuf[2]=(((MaValue&0xf0)>>4)&0x0f); disbuf[3]=MaValue&0x0f; LedDisp(); } } void interr_ir(void) interrupt 0 { /** * 用户码和机器码 */ unsigned char addrl,addrh,num1,num2; EA = 0; //先关闭外部中断0 Delay_9000us(); // 检测9ms开始码 if (IRIN) { // 检测是否为干扰信号 EA = 1; // 重新开启外部中断0 return ; // 退出解码 } while(!IRIN); // 等待跳为高电平 Delay_4500us(); // 检测4.5ms结果码 if (IRIN) { // 检测是否为干扰信号 EA = 1; // 重新开启外部中断0 return ; // 退出解码 } // 读码 addrl=GetCode(); // 用户编码高位 addrh=GetCode(); // 用户编码低位 num1=GetCode(); // 机器码 num2=GetCode(); // 机器码反码 //校验是否为错码 if(num1!=~num2) { KeyValue=14; EA=1; return; } KeyValue=num2; MaValue=addrh; EA=1; }
unsigned char GetCode() { unsigned char n; static temp = 0; for( n = 0; n < 8; n++ ) { while(!IRIN); // 等待高电平,开始解码 Delay_840us(); // 延时0.84ms if(IRIN) // 若仍然为高电平,则为1,否则为0 { temp = (0x80|(temp>>1)); // 1 while(IRIN); //等待跳变成低电平 } else { temp=(0x00|(temp>>1)); // 0 } } return temp; }