通过中断方式接收红外线,并译出对应编码。
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- sbit hwx=P3^3; //定义红外接收脚,
- code unsigned char d[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- //P0段选,共阳数码管 0-9 a-f - 表
- unsigned char code w[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
- //P1位选,直接使用P1的8个端口进行8位选择
- unsigned char l_tmpdate[4]={0,0,0,0};//显示管数据
- unsigned char l_lhj[66]; //定义66位数组变量来存储接收的时间参数
- void delay(); //延时子函数
- void display(unsigned char *lp);//数字的显示函数;lp为指向数组的地址
- void main(void) //入口函数
- {
- EA=1; //首先开启总中断
- EX1=1; //开启外部中断 1
- IT1=1; // 设置成 下降沿触发方式
- while(1){ //循环显示,接收都由中断处理
- display(l_tmpdate);
- }
- }
- void display(unsigned char *lp)//显示
- {
- P2=w[5];
- P0=~d[lp[0]]; //查表法得到要显示数字的数码段
- delay();
- //P0=0; //清除显示,为下一位显示准备
- P2=w[4];
- P0=~d[lp[1]];
- delay();
- // P0=0;
- P2=w[2];
- P0=~d[lp[2]];
- delay();
- // P0=0;
- P2=w[1];
- P0=~d[lp[3]];
- delay();
- //P0=0;
- }
- void delay(void) //空5个指令
- {
- unsigned char i=13;
- while(i)
- i--;
- }
- void hongwai(void) interrupt 2 //外部中断 1 ,INT1(P3^3)连接红外线接收IC数据脚
- {
- unsigned char i,j,tmp;
- EX1=0; //暂是关闭处断中断1,才能正常接收数据
- j=33; //传送一组数包括引导码1位,地址码8位加反码8位,指令码8位加反码8位,总共33位
- i=0; //从第一维数组开始
- tmp=100; //加八延时,按键消抖
- while(tmp){
- tmp--;
- }
- if(hwx){ //然后再检测红线接收脚是有数据接收,有继续,没有则退出
- EX1=1;
- return;
- }
- while(j){ //循环接收33位数据,为何我们用到66位数组,我们可以不接收高电平时间常数,只接低电平常数就
- //可以判断1或0了,在这里我们都接收,为串口调试软件接收计算波形
- //还有一点要知道,接收波形是反向,在没有接收时端口为高电平
- tmp=0;
- l_lhj[i]=1; //时间量从1开始
- while(!hwx){ //检测高低电平的变化,累计低电平的持续时间
- l_lhj[i]++; //没变继续加1
- delay(); //加入延时,是因为我们采用8位二进来存储,如果不加延时,时间量将计满
- tmp++; //此变量为防止干扰带来的死循环,也就是低电平持续时间最长不超过250个延时
- if(tmp==250)
- break;
- }
- i++;
- tmp=0;
- l_lhj[i]=1; //时间量从1开始
- while(hwx){ //检测高低电平的变化,累计高电平的持续时间
- l_lhj[i]++; //没变继续加1
- delay(); //同上
- tmp++;
- if(tmp==250)
- break;
- }
- i++;
- j--;
- }
- i=255; //加入循环延时,抗干扰
- while(i){
- tmp=255;
- while(tmp){
- P0=0XF0;
- tmp--;
- }
- i--;
- }
- tmp=0;
- for(i=3;i<19;i++,i++){ //处理地址位,对低电平时间数据的数理,这里我们只处理地址码和指令码,引导码和反码我们就忽略
- tmp>>=1; //右移一位,接收低电平在前
- if(l_lhj[i]>30) //检测低电平时间超过30就确认为1
- tmp+=0x80; //0x80=10000000
- }
- l_tmpdate[0]=tmp/16; //分开2位以16进制显示
- l_tmpdate[1]=tmp%16;
-
- tmp=0;
- for(i=35;i<51;i++,i++){ //同上,这里处理指令位
- tmp>>=1;
- if(l_lhj[i]>30)
- tmp+=0x80;
- }
- l_tmpdate[2]=tmp/16;
- l_tmpdate[3]=tmp%16;
- EX1=1;
- //再次启用外部中断1,为下一次接收做准备
- }
复制代码
所有资料51hei提供下载:
ir.rar
(18.28 KB, 下载次数: 12)
|