话不多说,做出来了,看效果。
显示分3次,用户码高8位,用户码低8位,遥控码。
源码已上传gitee。
构造图以前传过。就是这样的。
不过这个其实也不算完美,第一个是解码的头文件写的并不规范,不晓得是哪里的问题,不能拆分,拆分了会对别的造成干扰。
第二是有些遥控接收好像有问题,这个灵敏度不如下面的。
下面的这个通过遥控信号来直接控制中断,从原理上来说应该更好,但好像解码算法上又有问题,也许是我没搞懂吧。
避免时间长了遗失了,把那个高灵敏的源码贴上来。
#include<reg51.h> sbit OUTPUT=P3^2; //P3.2引脚为单片机外部中断0的触发引脚,同时连接红外接收模块IR 1838的输出端,在模块输出信号的同时进入外部中断0的服务函数 sbit Wei=P2^7; //数码管模块位锁存 unsigned char Code[9]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管显示从“1”到“9”的段码 unsigned char Code0[4]; unsigned char Code1[33]; unsigned char time; bit m,n; //定义两个标志位;标志位m表示一帧数据解码完毕,标志位n表示一帧数据接收完毕 void ET_0() interrupt 1 using 1 //定时器0中断 { time++; //对两个下降沿之间的时间间隔进行计数 } void EX_0() interrupt 0 //外部中断0 { static unsigned char i; static bit START; if(START) { if(time<63&&time>=33) //引导码,9ms+4.5ms { i=0; } Code1[i]=time; //存储两个下降沿之间的时间间隔,将用于数据帧的“0”和“1” time=0; i++; if(i==33) { n=1; i=0; } } else { time=0; START=1; } } void ET0_init() //定时器0中断初始化 { TMOD=0x02; //定时器0工作在方式2 TH0=0x00; //重载值 TL0=0x00; //初始值 ET0=1; //开启定时器0中断 TR0=1; } void EX0_init() //外部中断0初始化 { IT0=1; //设置外部中断0为下降沿触发 EX0=1; //开启外部中断0 EA=1; //开启总中断 } void DECODE() //红外解码 { unsigned char i,j,k; unsigned char x,y; k=1; for(i=0;i<4;i++) //对数据帧中的4个字节进行处理 { for(j=1;j<=8;j++) //对一个字节中的8位进行处理 { x=Code1[k]; if(x>7) //时间间隔大于某值则为1,与晶振(12MHz)相关,允许误差 { y|=0x80; } if(j<8) { y>>=1; } k++; } Code0[i]=y; y=0; } m=1; } void NUMBER() //将红外遥控器的按键值转换为数码管的段值 { switch(Code0[2]) { case 0x0c:P0=Code[0];break; case 0x18:P0=Code[1];break; case 0x5e:P0=Code[2];break; case 0x08:P0=Code[3];break; case 0x1c:P0=Code[4];break; case 0x5a:P0=Code[5];break; case 0x42:P0=Code[6];break; case 0x52:P0=Code[7];break; case 0x4a:P0=Code[8];break; default:break; } m=0; } void main() { ET0_init(); EX0_init(); P0=0xfe; //取数码管模块左边第一位选通 Wei=1; Wei=0; while(1) { if(n) { DECODE(); n=0; } if(m) { NUMBER(); } } }