sbit IR=P3^2; //红外接口标志 sbit dm = P2^2; //段码 sbit wm = P2^3; //位码
unsigned char hc[8]; //数码管显示缓存 unsigned char DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F unsigned char WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位码。显示的位置 unsigned char sj[33]; //接收脉冲时间数组 char w=0; //数码管显示缓存指针(0~7) unsigned char i; //脉冲个数记录 unsigned char mcsj; //脉冲时间(大于0.56ms小于1.125ms为0,大于1.125ms小于2.25ms) bit MC=0; //接收红外脉冲开始标志(0:脉冲已经结束,1:脉冲刚开始) bit JS=0; //脉冲接收结束标志位(1标志接收结束) bit JM=0; //解码完成标志位(1:解码完成) void Delay(unsigned char f); void dsq_0() interrupt 1 using 1 //定时器T0中断服务函数 { mcsj++; //256 } void wbzd_0() interrupt 0 //外部中断服务函数 {
if(MC) { if(mcsj>32) //判断是不是引导码。(如果是i=0) i=0; sj[i]=mcsj; //把脉冲时间存入sj这个数组里 mcsj=0; //清空脉冲时间准备接收下一个脉冲时间 i++; if(i==33) //判断是否接收完脉冲时间 { i=0; JS = 1; //接收完成标志位置1 MC=0; //红外脉冲结束 } } else { MC=1; //红外脉冲开始 mcsj=0; //清空脉冲时间 } } void csh_dsq_0() //初始化定时器0 { TMOD = 0x02; TH0=0x00; //定时器0的重装数据 TL0=0x00; //初始化 ET0=1; //打开定时器0中断 TR0=1; //启用定时器0 }
void csh_wbzd_0() //初始化外部中断0 { IT0=1; //外部中断0下降沿触发 EX0=1; //启用外部中断0 EA=1; //打开总中断 } void hwjm(unsigned char *p) //红外解码函数 { unsigned char i,j,k=1; for(i=0;i<4;i++) //4组数据的计数 { for(j=0;j<8;j++) //每组数据中的8位数据计算 { p[i] >>= 1; //数据右移一位 if(sj[k]>7) //脉冲时间大于7的就是1 p[i] |= 0x80; k++; } } JS = 0; //分析完成清零JS JM = 1; //解码完成JM置1
} unsigned char xhc(unsigned char *p) //红外按键匹配函数 { /* hc[0]=DM[p[1]/16]; //客户码 hc[1]=DM[p[1]%16]; //客户码 hc[2]=0x40; hc[3]=DM[p[2]/16]; //数据 hc[4]=DM[p[2]%16]; //数据 hc[5]=0x40; hc[6]=DM[p[3]/16]; //数据反码 hc[7]=DM[p[3]%16]; //数据反码 以上注释的代码是显示 红外解码后的原始数据 */
switch(p[2]) //匹配按键 { case 0x16:hc[w]=DM[0];break; //按键0 case 0x0c:hc[w]=DM[1];break; //按键1 case 0x18:hc[w]=DM[2];break; //按键2 case 0x5e:hc[w]=DM[3];break; //按键3 case 0x08:hc[w]=DM[4];break; //按键4 case 0x1c:hc[w]=DM[5];break; //按键5 case 0x5a:hc[w]=DM[6];break; //按键6 case 0x42:hc[w]=DM[7];break; //按键7 case 0x52:hc[w]=DM[8];break; //按键8 case 0x4a:hc[w]=DM[9];break; //按键9 case 0x09: //熄灭所有数码管(清零) { hc[0]=0x00; //熄灭所有数码管 w=7; //准备清空数码管显示缓存(不是真的清空) break; } default: return 0; //如果没有匹配的按键就结束函数 } if(w<7) //数码管显示缓存写入指针不能大于7 { w++; //显示缓存指针加一 hc[w]=0x00; //设置数码管扫描结束标志 } else w=0;//显示缓存指针清零 JM=0;
} void Delay(unsigned char f) //延时 { while(f--); } void main() { unsigned char k=0; //数码管扫描的位置 unsigned char jmsj[4]; //红外接收解码后的所有数据 csh_dsq_0(); //初始化定时器0 csh_wbzd_0(); //初始化外部中断0 while(1) { if(JS) //脉冲接收结束后调用解码函数解码 {hwjm(jmsj);} if(JM) //解码完成后调用按键匹配函数 {xhc(jmsj);} //下面的代码是数码管扫描 P1 = 0; //消影 dm = 1; dm = 0;
P1 = WM[k]; //写入位码 wm = 1; wm = 0;
P1 = hc[k]; //写入段码 dm = 1; dm = 0; if( k<7 && hc[k]!=0 ) //控制数码管显示的位数 k++; else k=0; Delay(50); } }
|