#include <reg52.h> //此表为 LED 的字模, 共阴数码管 0-9 a-f - unsigned char code smg_duan[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71,0x40}; //段码控制 //此表为8个数码管位选控制, 共阴数码管 1-8个 - unsigned char code smg_we[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdF,0xbF,0x7F}; //位选控制 查表的方法控制 sbit LS138A = P2^2; //定义138译码器的输入A脚由P2.2控制 sbit LS138B = P2^3; //定义138译码器的输入脚B由P2.3控制 sbit LS138C = P2^4; //定义138译码器的输入脚C由P2.4控制 unsigned char count; // 用于计数 unsigned char ircode[3]; // 存放计数数据,用于数码管显示 unsigned char ledonedata[2]; unsigned char ledeightbinary[8]; // 数码管显示八位二进制数 unsigned char startflag; // 开始计时标志 unsigned char irtime; // 用于计算时间 unsigned char irtimeArray[33]; // 存放一帧的时间 unsigned char irbit; // 红外位,一共33位,第一位引导码,后32后数据 unsigned char irreceiveok; // 一帧数据接收完成标志位 unsigned char ircodebyte[4]; // 四位数据 unsigned char irArrayProcessOK; // 数据处理完成标志 unsigned char leddata[8]; // 8个数码管 /**************************************** 延迟50ms 1s = 1000ms ****************************************/ void delay_50ms(unsigned char t) { unsigned int j; for(;t>0;t--) for(j=6245;j>0;j--); } /**************************************** 延迟50us ****************************************/ void delay_50us(unsigned int t) { unsigned char j; for(;t>0;t--) for(j=19;j>0;j--); } // 外部中断0 void int0init() { IT0 = 1; // 下降沿触发 EX0=1; EA=1; } // 计时器0 void timer0init() { TMOD = 0x02; TL0 = 0x00; TH0 = 0x00; ET0 = 1; EA = 1; TR0 = 1; } /* // 显示方式 P0 接段,P1 接位 void display() { unsigned char i; // count = 123 ircode[0] = smg_duan[count%1000/100]; // 百位 ircode[1] = smg_duan[count%100/10]; // 十位 ircode[2] = smg_duan[count%10]; // 个位 for(i=0;i<3;i++) { P0 = ircode[i]; P1 = smg_we[i]; delay_50us(20); } } */ // 74LS138译码器实现 void displayLS138() { unsigned char i; //count=123 ircode[0] = smg_duan[count%1000/100]; // 百位 ircode[1] = smg_duan[count%100/10]; // 十位 ircode[2] = smg_duan[count%10]; // 个位 for(i=0;i<3;i++) { P0 = ircode[i]; switch(i) //使用switch 语句控制位选 { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; case 4:LS138A=0; LS138B=0; LS138C=1; break; case 5:LS138A=1; LS138B=0; LS138C=1; break; case 6:LS138A=0; LS138B=1; LS138C=1; break; case 7:LS138A=1; LS138B=1; LS138C=1; break; } delay_50us(20); } } // 显示一位16进制数(未完成,有错误) void displayOneHex(unsigned char ch) { unsigned char i; unsigned char lsb; // 低四位 unsigned char hsb; // 高四位 //ledonedata[0] = smg_duan[ch/16]; //ledonedata[1] = smg_duan[ch%16]; for(i=0;i<2;i++) { P0 = ledonedata[i]; switch(i+4) //使用switch 语句控制位选 { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; case 4:LS138A=0; LS138B=0; LS138C=1; break; case 5:LS138A=1; LS138B=0; LS138C=1; break; case 6:LS138A=0; LS138B=1; LS138C=1; break; case 7:LS138A=1; LS138B=1; LS138C=1; break; } delay_50us(20); } } // 数码管显示八位二进制数 void displayBinary(unsigned char ch) { unsigned char i; unsigned char value; for(i=0;i<8;i++) { value = ch >> i; value = value & 0x01; ledeightbinary[7-i] = smg_duan[value]; } for(i=0;i<8;i++) { P0 = ledeightbinary[i]; switch(i) //使用switch 语句控制位选 { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; case 4:LS138A=0; LS138B=0; LS138C=1; break; case 5:LS138A=1; LS138B=0; LS138C=1; break; case 6:LS138A=0; LS138B=1; LS138C=1; break; case 7:LS138A=1; LS138B=1; LS138C=1; break; } delay_50us(20); } } // 测试显示16进制数 a-f void displayTest() { unsigned char i; for(i=10;i<17;i++) { P0 = smg_duan[i]; switch(i-10) //使用switch 语句控制位选 { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; case 4:LS138A=0; LS138B=0; LS138C=1; break; case 5:LS138A=1; LS138B=0; LS138C=1; break; case 6:LS138A=0; LS138B=1; LS138C=1; break; case 7:LS138A=1; LS138B=1; LS138C=1; break; } delay_50us(20); } } // 分析接受数据,解析成0,1信号 void irArrayProcess() { unsigned char k=1; // 第一位是引导码 unsigned char temp; unsigned char value; unsigned char i; unsigned char j; for(i=0;i<4;i++)//四个字节 { for(j=0;j<8;j++) // 一个字节8位 { temp = irtimeArray[k]; value=value>>1; if(temp>5) // 0:1.125ms, 1.125ms/0.256=4.39 1:2.25ms 2.25ms/0.256=8.78 { value=value|0x80; } k++; // 指向下一位 } ircodebyte[i]=value; } irArrayProcessOK=1; // 处理完成 } // 将4个字节16进制分别是数码管上显示 void irWork() { unsigned char ch; unsigned char k; unsigned char lsb; unsigned char hsb; for(k=0;k<4;k++) { lsb = ircodebyte[k] & 0x0f; hsb = (ircodebyte[k]&0xf0)>>4; leddata[k] = lsb; leddata[k+1] = hsb; } leddata[0] = ircodebyte[0]/16; leddata[1] = ircodebyte[0]%16; leddata[2] = ircodebyte[1]/16; leddata[3] = ircodebyte[1]%16; leddata[4] = ircodebyte[2]/16; leddata[5] = ircodebyte[2]%16; leddata[6] = ircodebyte[3]/16; leddata[7] = ircodebyte[3]%16; } void display() { unsigned char i; for(i=0;i<8;i++) { P0 = smg_duan[leddata[i]]; switch(i) //使用switch 语句控制位选 { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; case 4:LS138A=0; LS138B=0; LS138C=1; break; case 5:LS138A=1; LS138B=0; LS138C=1; break; case 6:LS138A=0; LS138B=1; LS138C=1; break; case 7:LS138A=1; LS138B=1; LS138C=1; break; } delay_50us(20); } } void main() { int0init(); timer0init(); while(1) { if(irreceiveok) // 一帧数据接受完成 { irArrayProcess(); irreceiveok=0; } if(irArrayProcessOK) { irWork(); irArrayProcessOK=0; } display(); //displayLS138(); //displayOneHex(irtimeArray[2]); //displayBinary(irtimeArray[8]); } // while } // 外部中断0 void int0() interrupt 0 { count++;// 用于计算下降沿次数 if(startflag) { if(irtime>32) // 引导码9ms,9ms/0.256 = 35.15 { irbit=0; // 清零 } irtimeArray[irbit] = irtime; irtime=0; // 清零 irbit++; if(irbit==33) // 在一帧接受完毕, { irreceiveok=1; // 一帧数据接受完成 startflag=0; // 开始标志为0 } }else { startflag = 1; // irtime=0; // 清零,计算引导码时间 irreceiveok=0; } } // 定时器0 void timer0() interrupt 1 { irtime++; // 255 }