51单片机实现红外线编码检测
基于单片机红外线测距的51程序
#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define ulong unsigned longsbit RS=P2^0; //LCD命令/数据端sbit RW=P2^1; //LCD读/写端sbit LCDE=P2^2; //LCD使能端sbit MCP_CS=P2^3; //MCP3001与AT89S52的管脚接线定义sbit MCP_DO=P2^4;sbit MCP_CLK=P2^5;uint measure;uchar flag; //Busy标志uchar code dis[]={"Measure Start"}; //显示uchar code dis1[] = {"Distance:"}; //显示表头uchar code dis2[] = {"0123456789.cm"}; //显示代码uchar code dis3[]={"Out Measure!"}; //显示uchar dis_buf[6]; //显示缓冲区void L_delay(void); //短延时void delay_ms(uint n); //延时函数uint read_MCP(void); //读MCP3001void init_1602(void); //1602初始化函数void busy(void); //LCD忙标志判断函数void dat_wrt(uchar dat); //写数据子函数void cmd_wrt(uchar cmd); //写命令子函数uint distance(void); //距离计算函数void lcd_start(uchar start); //设定显示位置函数void LCD_Clear(void); //LCD清屏函数uchar dat_adj(uint dat1); //显示数据调整函数void print(uchar *str); //字符串显示函数void disp(uint dat); //显示子函数uint average(void); //算术平均滤波程序/****************************主函数*******************************/main(){init_1602();print(dis); //显示测量开始delay_ms(1000);while(1){measure=distance();disp(measure); //显示高度delay_ms(100);}}/**************************延时函数**************************/void delay_ms(uint n){uint j;while(n--){for(j=0;j<125;j++);}}/***************************短延时****************************/void L_delay(void){uchar i;for(i=0;i<5;i++)_nop_();}/************************读MCP3001函数*************************/uint read_MCP(void){uchar i;uint temp=0;MCP_CS=1;L_delay();MCP_CS=0; //CS置低,开始采样数据for(i=0;i<13;i++) //读转换的10位数据{MCP_CLK=0;L_delay();MCP_CLK=1;temp<<=1;if(MCP_DO==1)temp|=0x01;}MCP_CS=1;temp&=0x03ff; //获取有效转换值return(temp);}/************************LCD忙标志判断函数*******************/void busy(void){flag=0x80; //赋初值高位为1 禁止while (flag&0x80) //读写操作使能位禁止时等待继续检测{P0=0xff;RS=0; //指向地址计数器RW=1; //读LCDE=1; //信号下降沿有效flag=P0; //读状态位高位为状态LCDE=0;}}/************************写数据子函数************************/void dat_wrt(uchar dat){busy(); //检测读写操作使能吗LCDE=0;RS=1; //指向数据寄存器RW=0; //写P0=dat; //写数据LCDE=1; //高电平有效LCDE=0;}/*************************写命令子函数************************/ void cmd_wrt(uchar cmd){LCDE=0;busy(); //检测读写操作使能吗P0=cmd; //命令RS=0; //指向命令计数器RW=0; //写LCDE=1; //高电平有效LCDE=0;}/***********************距离计算函数***************************/ uint distance(void){uint temp1;temp1=average();if((temp1>160)&(temp1<960)) //在正常测量范围?{temp1=13569/(temp1+7)-4; //转换测量数据}else{temp1=0x00ff; //超出测量范围,返回错误标志}return(temp1);}/************************算术平均滤波程序**********************/uint average(void){uchar i;uint av_dat;ulong ave=0;for(i=0;i<10;i++) //连续读取10个数据值{ave+=read_MCP(); //读转换数据L_delay();}av_dat=(uint)(ave/10); //求平均值return(av_dat);}/*************************1602初始化函数************************/void init_1602(void){cmd_wrt(0x01); //清屏cmd_wrt(0x0c); //开显示,不显示光标,不闪烁cmd_wrt(0x06); //完成一个字符码传送后,光标左移,显示不发生移位cmd_wrt(0x38); //16×2显示,5×7点阵,8位数据接口}/************************设定显示位置函数************************/void lcd_start(uchar start){cmd_wrt(start|0x80);}/************************LCD清屏函数****************************/void LCD_Clear(void){cmd_wrt(0x01); //写入清屏指令delay_ms(1);}/************************显示数据调整函数************************/uchar dat_adj(uint dat1){uchar i;dis_buf[0]=(uchar)(dat1/10); //十位dis_buf[1]=(uchar)(dat1%10); //个位dis_buf[2]=11;dis_buf[3]=12;if(dis_buf[0]==0)i=1;return(i);}/**************************字符串显示函数**************************/ void print(uchar *str){while(*str!='\0') //直到字符串结束{dat_wrt(*str);str++; //指向下一个字符}}/***************************显示子函数****************************/ void disp(uint dat){uchar temp,j;if(dat!=0x00ff){temp=dat_adj(dat);LCD_Clear();lcd_start(0x00);print(dis1); //显示文字lcd_start(0x45+temp); //确定显示起始位置for(j=temp;j<4;j++) //写显示数据dat_wrt(dis2[dis_buf[j]]);}else{LCD_Clear();lcd_start(0x42+temp); //确定显示起始位置print(dis3);}}。
51单片机红外解码资料+源代码
位地 8FH 8EH 8DH 8CH 8BH 8AH 89H 88H 址
源代码如下: #include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; sbit wela=P2^7;
uchar irtime; //红外时间 uchar startflag; //启动接收 uchar irdata[33]; uchar bitnum; uchar irreceiveok; //红外接收完毕 uchar ircode[4]; uchar irprosok; uchar disp[8]; uchar code smg_du[]={
发射器发射的的信号为
接收器接收到的信号为
即 9ms 低电平后 4.5ms 高电平作为起始码,之后接受到两次 8 位客户码,一次八位数据码,和一次八位数据反码。
遥控器在按键按下之后周期性的发出同一种 32 位二进制编 码周期约为 108ms,一组码持续时间随本身的“0”“1”个数不同
而不同。大约在 45~63ms 之间,当一个键按下 36ms,振荡器使芯 片激活,将发射一组 108ms 的编码脉冲这 108ms 编码脉冲由一个 起始码(9ms),一个结束码(4.5ms),低八位地址码(9~18ms), 高八位地址码(9~18ms),八位数据码(9~18ms),和这八位数据 码反码(9~18ms),如果按下超过 108ms 仍未松开,接下来发射 的代码(连发代码)将仅有起始码(9ms)和结束码(2.5ms)组 成。
解码的关键是如何识别零和一: “0”和“1”都是以 0.56ms 低电平开始的,不同的是高电平 宽度不同,“0”为 0.56ms“1”为 1.168ms,所以必须根据高电平 宽度来区别“0”和“1”。 如果从 0.56ms 低电平过后,开始延时,0.56ms 后,若读到的 电平为低,说明该位为零,反之则为一,可靠其间,延时必须比 0.56ms'长一些,又不能超过 1.12ms,否则如果该位为零,读到的 已是下一位高电平,因此取(1.12+0.56)/2=0.84ms 最为可靠,一 般取 0.84ms 左右均可。根据码的格式,应该等待 9ms 起始码和 4.5ms 结束码完成后才能读码。 备注:定时器/计数器控制寄存器 TCON 位序 D7 D6 D5 D4 D3 D2 D1 D0 号 位符 TF1 TR1 TF0 IR0 IE1 IT1 IE0 IT0 号
基于51单片机的红外遥控编码解码的C语言程序和电路[1]
请勿转载!!!作品功能简介:当学习键按下后,红外接收头便可将接受到的信号存储到单片机中。
在接受到通用遥控器发出的信号后,如果按下发射键,单片机将调出刚刚储存的信息,通过红外发射头发射出和遥控器一样的信号来达到控制的作用。
#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit studylamp=P2^7;sbit lamp=P2^6;sbit studykey=P3^2;sbit remotein=P1^1;sbit remoteout=P1^0;sbit txkey=P2^0;uint i,j,m=255,n,k,s;uchar idata remotedata[206];uint head;uint remdata;//一毫秒延时程序delay1ms(uint t){for(i=0;i<t;i++)for(i=0;j<120;j++);}//初始化函数clearmen(){studylamp=1;lamp=1;remoteout=0;remotein=1;for(i=0;i<206;i++){remotedata[i]=0x00;}IE=0x00;IP=0x01;TMOD=0x22;PCON=0X00;TH1=0xf3;TL1=0xf3;IT0=1;EX0=1;EA=1;}//键功能函数void key_tx(){if(txkey==0){delay1ms(1);if(txkey==0){while(txkey==0);ET1=1;TR1=1;for(i=head;i>0;i--);remoteout=0;ET1=0;TR1=0;n=0;while(1){lamp=0;studylamp=1;if(remotedata[n]==0x00){delay1ms(10);break;}for(i=remotedata[n];i>0;i--){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}n++;ET1=1;TR1=1;for(i=remotedata[n];i>0;i--);remoteout=0;ET1=0;TR1=0;n++;}}}}//主函数void main(){clearmen(); //初始化while(1){key_tx(); //按键扫描}}//40KHz发生器void time_intt1(void) interrupt 3{remoteout=~remoteout;}//外中断0void intt0(void) interrupt 0{ET1=0;TR1=0;EX0=0;EA=0;head=0;while(studykey==0);studylamp=0;lamp=1;while(remotein==1);head=0;while(remotein==0){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();head++;}n=0;remdata=0x0000;while(1){while(remotein==1){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();remdata++;}if(remdata>m) //高电平>5毫秒退出 {remotedata[n]=0x00;EX0=1;EA=1;goto end;}remotedata[n]=remdata;n++;remdata=0x0000;while(remotein==0){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();remdata++;}remotedata[n]=remdata;n++;remdata=0x00;}end: lamp=0;studylamp=0;}电路:实物:2009-06-25 12:39。
红外遥控编码原理及C程序,51单片机红外遥控
case 0x19:j=1;//100+
break;
case 0x0d:k=1;//200+
break;
case 0x16:l=1;//0
break;
case 0x0c:m=1;//1
{
temp=temp>>1; //最先读出的是高位数据
dingshiqi();//定时器记高低电平时间,数据码
if((HighTime>300)&&(HighTime<900)) //说明该位是0
temp=temp&0x7f;
if((HighTime>1200)&&(HighTime<2200)) //说明该位是1
uchar code table1[]={"User Code:"};
void delay(uint x)
{
uint i,j;
for(i=x;i>0;i--)//i=xms即延时约xms毫秒
for(j=100;j>0;j--);
}
void write_com(uchar com)
{//写液晶命令函数
{
a=0;b=0;c=0;d=0;
e=0;f=0;g=0;h=0;
i=0;j=0;k=0;l=0;
m=0;n=0;o=0;p=0;
q=0;r=0;s=0;t=0;
u=0;
}
void init_1602()
{//初始化函数
uchar num;
lcden=0;
rs=0;
write_com(0x38);//1602液晶初始化
while(1)
51F单片机实现红外遥控器HT6221发射的红外编码解码程序
{
delay(10000);
LED = 1;
}
//-------------------------------------------------------------------------------
{
uint t;
t = (uint)a;
t <= 8;
t = t | (uint)b;
return t;
}
//---------------------------------------------------------------------------
//-------------------------------------------------------------------------
//IR RX DECODE ROUTINE
//AUTHER : Xu Sen
//CREATE DATE : May 28. 2007
void key1_process(void)
{
LED = 0;
delay(10000);
}
//----------------------------------------------------------------------------
//DEFINE THE BIT "0 " AND BIT "1" FOR DECODE
#define ST_UP 0xBB8
#define ST_DW 0x792
#define RST_UP 0x792
自己写的51单片机的红外线遥控接收程序(C语言)
//51单片机做的红外遥控实验(C语言)#include<reg51.h>#define u8 unsigned char#define u16 unsigned int#define ID 0x00 //本遥控器的ID号sbit ir=P3^3;code u8 seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9的段码code u8 s[]={1,0x40,0x48,0x04,0x02,0x05,0x54,0x0A,0x1E,0x0E}; u8 buf[4];bit ir_f=0;u8 nu;void delay(u16 x){while(x--);}void show(u16 x){u8 i=0,k=0;u8 s[4];kk:s[i]=x%10;if((x/10)>=1){x=x/10;i++;goto kk;}k=i+1;for(i=0;i<k;i++){P0=seg[s[i]];P2=~(8>>i);delay(300);P0=0XFF;P2=0XFF;}}void timer0_init(){TH0=0;TL0=0;TMOD|=0x01;TR0=0;}u16 low_test(){u16 t;TR0=1;while((ir==0)&&((TH0&0X80)!=0X80));TR0=0;t=TH0;t<<=8;t|=TL0;TH0=0;TL0=0; //t=(TH*256+TL0);//机器周期数return t;}u16 high_test(){u16 t;TR0=1;while((ir==1)&&((TH0&0X80)!=0X80));TR0=0;t=TH0;t<<=8;t|=TL0;TH0=0;TL0=0;return t;}/*u16 time_test(bit x){}*/u8 receive_8bit(){u8 d,i;u16 t;for(i=0;i<8;i++){t=low_test();t=high_test();d>>=1;if((t>=2750)&&(t<=3100)){d|=0x80;}}return d;}void ir_decode(){u16 t;u8 i;if(ir==0)//有遥控信号{t=low_test();//8295-9000us,倍频的是16590-18000if((t>=14500)&&(t<=18000))//检查引导码低电平时间{t=high_test();if((t>=8000)&&(t<=9000))//检查高电平{for(i=0;i<4;i++){buf[i]=receive_8bit();}if(buf[0]==(~buf[1]))//检查系统码是否正确{if(buf[0]==ID){if(buf[2]==(~buf[3])){//具体按键处理ir_f=1; //遥控有效}}}}}}}/*void key(){if(buf[2]==0x40){P1^=(1<<0);}if(buf[2]==0x48){P1^=(1<<1);}}*/void ir_execuse(){if(ir_f==1){switch(buf[2]){case 0x40:P1^=(1<<0);break;case 0x48:P1^=(1<<1);break;case 0x04:P1^=(1<<2);break;case 0x02:P1^=(1<<3);break;case 0x05:P1^=(1<<4);break;case 0x54:P1^=(1<<5);break;case 0x0A:P1^=(1<<6);break;case 0x1E:P1^=(1<<7);break;}ir_f=0;}}void show_d(){u8 j;for(j=0;j<10;j++){if(s[j]==buf[2]){nu=j;break;}}show(nu);}void isr_init(){EA=1;EX1=1;//外部中断,一直看3.3有没有下降沿。
基于MCS51单片机的红外线解码系统设计
JNC TT
;如果为0就跳转到TT
MOV R4,#2
;延时1000微秒
Hale Waihona Puke D6:MOV R5,#248
DJNZ R5,$
DJNZ R4,D6
;检测到高电平1的话延时1毫秒等
待脉冲高电平结束
TT:
MOV A,@R1 ;将R1中地址的给A
RRC A
;将C中的值0或1移入A中的最低位
MOV @R1,A ;
DJNZ R3,SS ;接收满8位换一个内存
低成本、高可靠性、体积小、结构简单、避免人身伤害等优
点,是一种先进的控制方式,具有广阔的应用前景。
一、单片机解码程序设计
单片机在进行解码时,首先根据SM0038所传输过来的信号
判断是否有红外信号,若检测红外信号,则单片机产生中断,
进入中断处理程序,对红外线信号进行解码,单片机程序使用
汇编设计,采用查询方式确定是否有红外线信号,其解码查询
基于MCS51单片机的红外线解码系统设计
李春燕
(重庆市铜梁职业教育中心)
摘 要:本文通过对通用红外线遥控器编码系统的研究,
利用MCS51系列单片机对红外线进行解码,实现了红外线解码系
统,并利用单片机的串行通信接口与通用计算机进行通信,实
现了计算机上位机显示软件的设计。
关键词:MCS-C51 红外线 解码 串行通信
INC R1
;对R1中的值加1,换下一个RAM
DJNZ R2,PP ;接收完所有数据
EXIT:
#pragma endasm
上位机程序设计
上位程序使用微软基于.NET的新一代程序设计语言C#(读
作C SHARP),该语言是一种安全的语言,具有内存自动回收功
基于51单片机控制红外通信
精心整理红外通信原理红外遥控有发送和接收两个组成部分。
发送端采用单片机将待发送的二进制信号编码调制为一系列的脉冲串信号,通过红外发射管发射红外信号。
红外接收完成对红外信号的接收、放大、检波、整形,并解调出遥控编码脉冲。
为了减少干扰,采用的是价格便宜性能可靠的一体化红外接收头(HS0038,它接收红外信号频率为38kHz,(2)PPM编码这种遥控编码具有以下特征:遥控编码脉冲由前导码、16位地址码(8位地址码、8位地址码的反码)和16位操作码(8位操作码、8位操作码的反码)组成。
前导码:是一个遥控码的起始部分,由一个9ms的高电平(起始码)和一个4.5ms的低电平(结果码)组成,作为接受数据的准备脉冲。
16位地址码:能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。
16位操作码:用来执行不同的操作。
采用脉宽调制的串行码,以脉宽为0.56ms、间隔0.56ms、周期为1.12ms的组合表示二进制的“0”;以脉宽为1.68ms、间隔0.56ms、周期为2.24ms的组合表示二进制的“1”。
???{???}?}}一串完整的编码如下图所示前导码地址码地址反码操作码操作反码2.红外接收部分:红外接收完成对红外信号的接收、放大、检波、整形,并解调出遥控编码脉冲。
为形得到HS0038#defineuintunsignedintucharram[4]={0,0,0,0};//存放接受到的4个数据地址码16位+按键码8位+按键码取反的8位voiddelaytime(uinttime)//延迟90uS{uchara,b;for(a=time;a>0;a--){for(b=40;b>0;b--);}}voidrem()interrupt0//中断函数{ucharramc=0;//定义接收了4个字节的变量ucharcount=0;//定义现在接收第几位变量{电平return;//}32位中//第一位数据的0.56MS开始脉冲for(ramc=0;ramc<4;ramc++)//循环4次接收4个字节{for(count=0;count<8;count++)//循环8次接收8位(一个字节){while(prem!=1);//开始判断现在接收到的数据是0或者1,首先在这行本句话时,//保已经进入数据的0.56MS低电平阶段//等待本次接受数据的高电平的到来。
51单片机红外解码、超声波测距程序(详细解释程序)
// c51红外解码、超声波测距程序#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define count 4uchar data IRcode[4]; //定义一个4字节的数组用来存储代码uchar table[4];uchar enled[4]={0x1f,0x2f,0x4f,0x8f};uchar CodeTemp,temp,tt; //编码字节缓存变量uchari,j,k,temp,timeH,timeL,succeed_flag,flag,h,h1,h2,a,key,key1,key2; //延时用的循环变量uint distance,distance1,time; //距离,timesbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)sbit come=P3^3;sbit d=P1^1;//发送码sbit BZ=P1^0;sbit s=P3^7;//38ksbit ss=P3^6;//38kuchar m;// 开关控制//sbit n=P2;//电机反转code unsigned charseg7code[10]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28}; //显示段码/**************************** 定时器0中断************************/void timer0() interrupt 1{TH0=(65536-count)/256;TL0=(65536-count)%256;s=~s;//产生38K信号ss=~ss;//tt++;//发送超声波个数}/**************************** 延时0.9ms子程序************************/void Delay0_9ms(void){uchar j,k;for(j=18;j>0;j--)for(k=20;k>0;k--);}/***************************延时1ms子程序**********************/void Delay1ms(void){uchar i,j;for(i=2;i>0;i--)for(j=230;j>0;j--);}/***************************延时4.5ms子程序**********************/ void Delay4_5ms(void){uchar i,j;for(i=10;i>0;i--)for(j=225;j>0;j--);}/**************************** 解码延时子程序************************/ void Delay(void){uchar i,j,k;for(i=100;i>0;i--)for(j=100;j>0;j--)for(k=3;k>0;k--);}/**************************** 显示延时子程序************************/ void ledDelay(unsigned int tc) //延时程序{unsigned int i,j;for(i=0;i<10;i++)for(j=0;j<tc;j++);}/************************************************ ****************///定时器1中断,用做超声波测距无回波void timer1() interrupt 3{TR1=0;ET1=0;EX1=0;TH1=0;TL1=0;}/***********************显示程序*********************/ void Led(int date) //显示函数{ int i;table[0]=date/1000;table[1]=date/100%10;table[2]=date/10%10;table[3]=date%10;date=0;for(i=0;i<120;i++){P2=enled[i%4]&m;//P2口高四位控制数码管,低位陪分控制继电器P0=seg7code[table[i%4]]; //取出千位数,查表,输出。
51单片机红外接收解码程序(详细解析)
51单片机红外接收解码程序接收以S52单片机作为接收系统。
以S52的P3.3口作为接收端口,该端口是外部中断1。
这个接受程序是以XC866作为红外发送控制系统,接收程序如下:#include<reg52.h>//头文件#include<intrins.h>#define uchar unsigned char//宏定义#define uint unsigned intsbit HWRx=P3^3;//位声明code uchar Table[]=//共阴数码管0-9 a-f - 表{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};uchar Table_Data[8]={0,0,0,0,0,0,0,0};//用于显示的数组uchar Table_Rx[67];//用于存储判断接收是1或0的参数void Delay();//延时子函数void Display(uchar *lp,uchar lc)//显示{uchar i;//定义变量P2=0;//端口2为输出,关闭P1=P1&0xF8;//将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管for(i=0;i<lc;i++)//循环显示,采用动态扫描{P2=Table[lp[i]]; //查表法得到要显示数字的数码段if(lp[i]>0x7f)P2+=0x80;Delay();//延时P2=0;//清0端口,准备显示下位if(i==7)//检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据break;P1++;//点亮下一位数码管}}void main()//主函数{EA=1;//首先开启总中断EX1=1;//开启外部中断1IT1=1;//设置成下降沿触发方式while(1)//一直显示,其它由中断处理{Display(Table_Data,8);}}void Delay()//延时时间大约为31us,晶振12M{uchar i=13;while(i)i--;}void Delay_ms(uint z) //延时时间约为1ms*X晶振为12M{uint x=0,y=0;for(x=z;x>0;x--)for(y=54;y>0;y--);}void hongwai()interrupt 2//外部中断1 ,INT1(P3^3)连接红外线接收IC数据脚{uchar i,j,tmp;EX1=0;//关闭中断j=33;//传送一组数包括引导码1位,4个八位数据,总共33位i=0;//从第一维数组开始Delay_ms(10);if(HWRx){//然后再检测红线接收脚是有数据招收,有继续,没有则退出EX1=1;return;}while(j--){//循环接收33位数据,为何我们用到66位数组,我们可以不接收高电平时间常数,只接低电平常数就//可以判断1或0了,在这里我们都接收,还有一点要知道,接收波形是反向,在没有接收时端口为高电平tmp=0;Table_Rx[i]=1;//时间量从1开始while(!HWRx) //检测高低电平的变化,这里检测的是高电平{Table_Rx[i]++;//没变继续加1Delay();//家一个延时防止,计数值一下子就加满了tmp++;//加1if(tmp==250)break;}i++;tmp=0;Table_Rx[i]=1;//时间量从1开始while(HWRx)//检测高低电平的变化,这里检测的是低电平{Table_Rx[i]++; //没变继续加1Delay();//同上tmp++;//加1,用于判断是1还是0的,低电平来了if(tmp==250)break;}i++;}P1=0xf8;i=200;//加入循环延时,抗干扰while(i)//在有接收数据的时候显示一个H{tmp=255;while(tmp){tmp--;P2=0x76;}i--;}tmp=0;for(i=3;i<19;i++,i++)//处理发送的数据{tmp>>=1;//右移一位,接收低位在前if(Table_Rx[i]>30)//检测低电平时间超过30就确认为1 tmp+=0x80;}Table_Data[0]=tmp/16;//分开2位以16进制显示,用显示发送的数据Table_Data[1]=tmp%16;tmp=0;for(i=19;i<35;i++,i++)//同上{tmp>>=1;if(Table_Rx[i]>30)tmp+=0x80;}Table_Data[2]=tmp/16;Table_Data[3]=tmp%16;tmp=0;for(i=35;i<51;i++,i++){tmp>>=1;if(Table_Rx[i]>30)tmp+=0x80;}Table_Data[4]=tmp/16;Table_Data[5]=tmp%16;tmp=0;for(i=51;i<67;i++,i++){tmp>>=1;if(Table_Rx[i]>30)tmp+=0x80;}Table_Data[6]=tmp/16;Table_Data[7]=tmp%16;EX1=1;//刚进中断时关闭了分控,现在要打开}。
51红外线解码方式
51单片机红外h遥控解码红外遥控发射芯片采用PPM编码方式,当发射器按键按下后,将发射一组108ms的编码脉冲。
遥控编码脉冲由前导码、8位用户码、8位用户码的反码、8位操作码以及8位操作码的反码组成。
通过对用户码的检验,每个遥控器只能控制一个设备动作,这样可以有效地防止多个设备之间的干扰。
编码后面还要有编码的反码,用来检验编码接收的正确性,防止误操作,增强系统的可靠性。
前导码是一个遥控码的起始部分,由一个9ms的低电平(起始码)和一个 4. 5ms的高电平(结果码)组成,作为接受数据的准备脉冲。
以脉宽为0. 56ms、周期为1. 12ms的组合表示二进制的“0”;以脉宽为1. 68ms、周期为2. 24ms的组合表示二进制的“1”。
如果按键按下超过108ms仍未松开,接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(2. 5ms)组成。
单片机采用外部中断INTI管脚和红外接收头的信号线相连,中断方式为边沿触发方式。
并用定时器0计算中断的间隔时间,来区分前导码、二进制的“1”、“0”码。
并将8位操作码提取出来在数码管上显示。
// 解码值在Im[2]中,当IrOK=1时解码有效。
/* 51单片机红外遥控解码程序 *///用遥控器对准红外接收头,按下遥控器按键,在数码管前两位上就会显示对应按键的编码#include <reg52.h>#define uchar unsigned charsbit dula=P2^6;sbit wela=P2^7;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71} ;uchar f;#define Imax 14000 //此处为晶振为11.0592时的取值,#define Imin 8000 //如用其它频率的晶振时,#define Inum1 1450 //要改变相应的取值。
红外解码51单片机程序
RETURN: RETI
;**********************定时**********************************************
;定时次数计数器用R3
NNIT1: CLR TR1
MOV TH1,#00H
MOV TL1,#00H
END
MOVC A,@A+DPTR
MOV P0,A
LCALL DEL1
MOV A,#21
MOVC A,@A+DPTR
MOV P1,#0FH
MOV P0,A
LCALL DEL1
LCALL DEL1
LCALL DEL1
RET
;**************************************************************************
DEL: MOV R6,#3
F1: MOV R5,#165
DJNZ R5,$
DJNZ R6,F1
RET
;**********************200MS******************************************************
DEL1: MOV R7,#200
DB 0C8H ;N 16
DB 0AFH ;R 17
DB 87H ;T 18
DB 0BFH ;- 19
DB 0F9H ;| 20
DB 0F6H ;= 21
DB 0CFH ;|- 22
DB 0CFH
;*********************显示结束信号************************************************************
基于51单片机红外发射程序
基于51单片机红外发射程序#include "reg52.h"sbit ir=P2^0;//红外发射管控制脚,使用24M晶振sbit led = P2^1;sbit ka=P1^0;sbit kb=P1^1;sbit kc=P1^2;sbit kd=P1^3;unsigned int count, set_count; //中断计数,设定中断次数bit irflag,keyflag; //红外发送标志位,按键标志位unsigned char irsys[]={0x00,0xff};//16位用户码unsigned char irdata,ircode; //发送的红外数据//---------------------------------------------------------------------------void delay(unsigned int a)//延时约1ms,晶振24M ,此处延时不需很精确{unsigned char i;while(--a!=0)for(i=300;i>0;i--); //若是12M晶振i=125}//---------------------------------------------------------------------------void keyscan() // 按键扫描{if(ka==0){ delay(5);while(!ka);keyflag=1;irdata=0x0a;} //a键按下,则发射数据0x0aif(kb==0){ delay(5);while(!kb);keyflag=1;irdata=0x0b;} //a键按下,则发射数据0x0aif(kc==0){ delay(5);while(!kc);keyflag=1;irdata=0x0c;} //a键按下,则发射数据0x0aif(kd==0){ delay(5);while(!kd);keyflag=1;irdata=0x0d;} //a键按下,则发射数据0x0a}//---------------------------------------------------------------------------void ir_sendbyte() //红外发送一个字节数据{unsigned char i;for(i=0;i<8;i++) //发送8位数据{set_count=43;//35; //发送编码中的0.56ms高电平(//后为12M 晶振下的数值)irflag=1; //启动红外发射二极管发射count=0; //中断计数先清0TR0=1; //开启定时器0while(count<="">TR0=0; //关闭定时器0if(ircode&0x01) set_count=130;//130; //判断红外编码最低位,若为1则1.69ms的低电平(//后为12M晶振下的数值)else set_count=43;//35; //为0则0.565ms的低电平(//后为12M 晶振下的数值) irflag=0; //低电平则不发射count=0; //中断计数清0TR0=1; //开启定时器0while(count<="">TR0=0; //关闭定时器0ircode=ircode>>1; //将数据右移,即从低位到高位发送}}//---------------------------------------------------------------------------void ir_send() //发送红外数据{set_count=692;//672; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值) tc9012irflag=1; //启动红外发射二极管发射count=0; //中断计数清0TR0=1;while(count<set_count);< p="">TR0=0;set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)irflag=0; //低电平则不发射count=0;TR0=1;while(count<="">TR0=0;ircode=irsys[0]; //发送16位用户码的前1-8位ir_sendbyte();ircode=irsys[1]; //发送16位用户码的前9-16位ir_sendbyte();ircode=irdata; //发送8位数据码ir_sendbyte();ircode=~irdata; //发送8位数据反码ir_sendbyte();set_count=43;//35; //发送编码中的0.56ms高电平(//后为12M 晶振下的数值)irflag=1;count=0;TR0=1;while(count<set_count);< p="">TR0=0;ir=1;delay(23); //延时23ms(编码中的23ms低电平)set_count=692;//670; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值)irflag=1;count=0;TR0=1;while(count<set_count);< p="">TR0=0;set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)irflag=0;count=0;TR0=1;while(count<set_count);< p="">TR0=0;set_count=43;//35; //发送编码中的0.56ms高电平(//后为12M 晶振下的数值) irflag=1;count=0;TR0=1;while(count<set_count);< p="">TR0=0;ir=1; //发射完了关闭红外发射二极管}//---------------------------------------------------------------------------void timer0_init() //定时器初始化{EA=1;TMOD=0x02; //定时0 8位自动重装模式ET0=1;TH0=0xe6;//0xf3; //定时13us,38K红外矩形波,晶振24M (//后为12M晶振下的数值) TL0=0xe6;}//---------------------------------------------------------------------------void main(){timer0_init(); //定时0初始化count=0; //中断计数先清0irflag=0; //红外发射标志先置0while(1){keyscan(); //键值扫描if(keyflag) //若有按键按下{led = 0;delay(10);ir_send(); //发送红外编码delay(500);keyflag=0; //按键标志清零delay(100);}else{led = 1;}}}//---------------------------------------------------------------------------void timer0() interrupt 1 //定时器0中断{count++;if(irflag==1) ir=~ir; //有发射标志,则发射38khz的矩形波else ir=1; //否则不发射,即相当于发射编码中的低电平}</set_count);<></set_count);<></set_count);<></set_count);<></set_count);<>。
51单片机 红外接收数码管显示解码实验
#include <reg51.h>#define c(x) (x*120000/120000)sbit Ir_Pin=P3^3;//接红外sbit beep=P3^6;unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极数码显示码0-F.unsigned char code Led_Sel[]={0x00,0x01,0x02,0x03};unsigned char Led_Buf[4]; //显示缓冲区char Led_Index;//位选unsigned char Ir_Buf[4]; //用于保存解码结果void delay_50ms(unsigned int t){unsigned int j;for(;t>0;t--)for(j=6245;j>0;j--){;}}//==============================================================//数码管扫描timer0() interrupt 1 using 1{TL0=65536-1000;TH0=(65536-1000)/256; //定时器0设定约1000us中断一次,用于数码管扫描P0=0xff;P2=Led_Sel[Led_Index]; //位选P0=Led_Tab[Led_Buf[Led_Index]]; //段选if(++Led_Index>3) Led_Index=0; //四个扫描完了,到第一个数码管}//============================================================== unsigned int Ir_Get_Low(){TL1=0;TH1=0;TR1=1;while(!Ir_Pin && (TH1&0x80)==0);TR1=0;return TH1*256+TL1;}//============================================================= unsigned int Ir_Get_High(){TL1=0;TH1=0;TR1=1;while(Ir_Pin && (TH1&0x80)==0);TR1=0;return TH1*256+TL1;}//============================================================== main(){unsigned int temp;char i,j;Led_Index=1;TMOD=0x11;TL0=65536-1000;TH0=(65536-1000)/256; //定时器0设定约1000us中断一次,用于数码管扫描EA=1;ET0=1;TR0=1;Led_Buf[0]=0;Led_Buf[1]=0;Led_Buf[2]=0;Led_Buf[3]=0; //显示区设成0do{ restart:while(Ir_Pin);temp=Ir_Get_Low();if(temp<c(8500) || temp>c(9500)) continue;//引导脉冲低电平9000temp=Ir_Get_High();if(temp<c(4000) || temp>c(5000)) continue;//引导脉冲高电平4500for(i=0;i<4;i++) //4个字节for(j=0;j<8;j++) //每个字节8位{temp=Ir_Get_Low();if(temp<c(200) || temp>c(800)) goto restart;temp=Ir_Get_High();if(temp<c(200) || temp>c(2000)) goto restart;Ir_Buf[i]>>=1;if(temp>c(1120)) Ir_Buf[i]|=0x80;}Led_Buf[0]=Ir_Buf[2]&0xf;Led_Buf[1]=(Ir_Buf[2]/16)&0xf;Led_Buf[2]=Ir_Buf[3]&0xf;Led_Buf[3]=(Ir_Buf[3]/16)&0xf; //显示结果P1=Ir_Buf[2];beep=0;delay_50ms(2);beep=1;}while(1);}。
红外遥控编码原理及C程序,51单片机红外遥控
红外遥控解解码程序#include <reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P1^0;sbit rs=P1^2;sbit ir=P3^2;sbit led=P1^3;sbit led2=P3^7;unsigned int LowTime,HighTime,x;unsigned char a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;unsigned char flag;//中断进入标志位uchar z[4];uchar code table[]={"husidonghahahah"};uchar code table1[]={"User Code:"};void delay(uint x){uint i,j;for(i=x;i>0;i--) //i=xms即延时约xms毫秒for(j=100;j>0;j--);}void write_com(uchar com){//写液晶命令函数rs=0;lcden=0;P2=com;delay(3);lcden=1;delay(3);lcden=0;}void write_date(uchar date){//写液晶数据函数rs=1;lcden=0;P2=date;delay(3);lcden=1;delay(3);lcden=0;}void init_anjian() //初始化按键{a=0;b=0;c=0;d=0;e=0;f=0;g=0;h=0;i=0;j=0;k=0;l=0;m=0;n=0;o=0;p=0;q=0;r=0;s=0;t=0;u=0;}void init_1602(){//初始化函数uchar num;lcden=0;rs=0;write_com(0x38);//1602液晶初始化write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);for(num=0;num<14;num++)//写入液晶固定部分显示{write_date(table[num]);delay(3);}write_com(0x80+0x40);for(num=0;num<9;num++){write_date(table1[num]);delay(3);}}void write_dianya(uchar add,char date){//1602液晶刷新时分秒函数4为时,7为分,10为秒char shi,ge;shi=date%100/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void dingshiqi() //定时器记高低电平时间{TH0=0; //定时器高八位置0TL0=0; //定时器低八位置0TR0=1; //开启定时器0while(ir==0); //如果是低电平就等待,给低电平计时TR0=0; //关闭定时器T0LowTime=TH0*256+TL0; //保存低电平时间TH0=0; //定时器高八位置0TL0=0; //定时器低八位置0TR0=1; //开启定时器0while(ir==1); //如果是高电平就等待,给引导码高电平计时TR0=0; //关闭定时器T0HighTime=TH0*256+TL0; //保存高电平长度}void main(){char i=0;TMOD=0x01; //定时器T0作为定时模式ET0=1; //开T0中断IT0=0; //外部中断,下降沿触发EX0=1; //开外部中断EA=1; //开总中断init_1602();while(1){}}void inter0() interrupt 0 //开始解码{EX0=0; //关闭外部中断0,不再接受红外信号,只解码当前的红外信号。
51单片机红外线遥控试验
红外线遥控试验XL2000试验仪配有一个标准的32位HT6121编码红外遥控器。
通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片来进行控制操作,如图1所示。
发射部分包括键盘矩阵、编码调制、LED红外发送器;接收部分包括光、电转换放大器、解调、解码电路。
当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。
这种遥控码具有以下特征:采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”,其波形如图2所示相关原理:解码的关键是如何识别“0”和“1”,从位的定义我们可以发现“0”、“1”均以0.56ms的低电平开始,不同的是高电平的宽度不同,“0”为0.56ms,“1”为1.68ms,所以必须根据高电平的宽度区别“0”和“1”。
如果从0.56ms低电平过后,开始延时,0.56ms以后,若读到的电平为低,说明该位为“0”,反之则为“1”,为了可靠起见,延时必须比0.56ms长些,但又不能超过1.12ms,否则如果该位为“0”,读到的已是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.84ms左右均可。
程序运行的照片:接线方法:1、接8位数码管的数据线。
将数码管部份的数据口 JP5接到CPU部份的P0口JP51.2、接8位数码管的显示位线。
将数码管部份的显示位口 JP8接到CPU部份的P2口JP52.3、用一根1PIN数据线一端插入CPU部分JP53(P3口)的P3.7另外一端插入红外遥控部分的输出端JP45。
程序流程图:汇编语言参考程序:org 00hORG 80HMOV P1,#0FFHMOV P2,#0FFHMOV P3,#0FFHSTART:JB P3.7,$ ;等待遥控信号出现SB:MOV R4,#8 ;8毫秒为高电平错误SBA:MOV R5,#250SBB:JB P3.7,SXB1DJNZ R5,SBBDJNZ R4,SBAMOV R4,#2JMP SBCSXB1:MOV R5,#5SXB2: ;去掉20US的尖峰干扰信号JNB P3.7,SBBDJNZ R5,SXB2JMP STARTSBC:MOV R5,#250SB1:JB P3.7,SB2 ;2MS内不为高电平错误(监测9MS的低电平引导码)DJNZ R5,SB1DJNZ R4,SBCJMP STARTSB2: ;去掉20US的尖峰干扰信号MOV R5,#5SB2_A:JNB P3.7,SB1DJNZ R5,SB2_AMOV R4,#3SB2_1:MOV R5,#250SB3: ;监测4.5MS高电平,如3MS内出现低电平错误JNB P3.7,SXCDJNZ R5,SB3DJNZ R4,SB2_1MOV R4,#2JMP SB3_1SXC: ;去掉20US的尖峰干扰信号MOV R5,#5SXC1:JB P3.7,SB3DJNZ R5,SXC1JMP STARTSB3_1: ;监测4.5MS高电平,如5MS内不为低电平错误MOV R5,#250SB3_2:JNB P3.7,SB4DJNZ R5,SB3_2DJNZ R4,SB3_1JMP STARTSB4: ;去掉20US的尖峰干扰信号MOV R5,#5SB4_1:JB P3.7,SB3_2DJNZ R5,SB4_1MOV R1,#1AH ;设定1AH为起始RAM区MOV R2,#4PP: MOV R3,#8JJJJ:MOV R5,#250JJJJ2: ;1MS内不为低电平错误JB P3.7,JJJJ3DJNZ R5,JJJJ2JMP STARTJJJJ3:LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态MOV C,P3.7 ;将P3.7引脚此时的电平状态0或1存入C中JNC UUU ;如果为0就跳转到UUUMOV R5,#250JJJJ4:JNB P3.7,UUUNOPDJNZ R5,JJJJ4JMP STARTUUU:MOV A,@R1 ;将R1中地址的给ARRC A ;将C中的值0或1移入A中的最低位MOV @R1,A ;将A中的数暂时存放在R1中DJNZ R3,JJJJ ;接收地址码的高8位INC R1 ;对R1中的值加1,换成下一个RAMDJNZ R2,PP ;接收完16位地址码和8位数据码和8位数据反码,存放在1AH/1BH/1CH/1DH的RAM中;以下对代码是否正确和定义进行识别MOV A,1AH ;比较高8位地址码XRL A,#00000000B;判断1AH的值是否等于00000000,相等的话A为0JNZ EXIT ;如果不相等说明解码失败退出解码程序MOV A,1BH ;比较低8位地址XRL A,#11111111B;再判断高8位地址是否正确JNZ EXIT ;如果不相等说明解码失败退出解码程序LCALL YS3MOV A,1CH ;比较数据码和数据反码是否正确?CPL AXRL A,1DH ;将1CH的值取反后和1DH比较不同则无效丢弃,核对数据是否准确JNZ EXIT ;如果不相等说明解码失败退出解码程序LCALL YS3CLR P2.6 ;选中数码管CLR P3.3 ;解码成功喇叭响?AJMP BIJIAO;判断在118毫秒内是否有连发码AA: MOV R1,#25XX: ACALL YS2JNB P3.7,HH ;跳转到判断连发代码是否正确的程序段DJNZ R1,XXEXIT: ;对所有端口清零AJMP START;连发码判断程序段-----------HH: MOV R6,#4S: ACALL YS1 ;调用882微秒延时子程序JB P3.7,EXIT ;延时882微秒后判断P3.7脚是否出现高电平如果有就退出解码程序DJNZ R6, S ;重复4次,目的是确认连发码的低电平信号波形JNB P3.7, $ ;等待高电?LCALL YS3AJMP AABIJIAO: MOV A,1CH ;按键数值判断执mov p1,aCJNE A,#10h,TT1MOV P0,#7EH ;数码管显示1TT1: CJNE A,#03h,T2MOV P0,#0A2H ;数码管显示2T2: CJNE A,#01h,T3MOV P0,#62H ;数码管显示3T3: CJNE A,#06h,T4T4: CJNE A,#09h,T5MOV P0,#61H ;数码管显示5 T5: CJNE A,#1dh,T6MOV P0,#21H ;数码管显示6 T6: CJNE A,#1fh,T7MOV P0,#7AH ;数码管显示7 T7: CJNE A,#0dh,T8MOV P0,#20H ;数码管显示8 T8: CJNE A,#19h,t9MOV P0,#60H ;数码管显示9 T9: CJNE A,#1bh,t10MOV P0,#28H ;数码管显示0 T10: CJNE A,#11h,t11MOV P0,#30H ;数码管显示A T11: CJNE A,#15h,t12MOV P0,#25H ;数码管显示b T12: CJNE A,#17h,t13MOV P0,#0a9H ;数码管显示C T13: CJNE A,#12h,t14MOV P0,#26H ;数码管显示d T14: CJNE A,#16h,t15T15: CJNE A,#4ch,t16MOV P0,#0b1H ;数码管显示ft16: AJMP AAYS1: MOV R4,#20 ;延时子程序1,精确延时882微秒D1: MOV R5,#20DJNZ R5,$DJNZ R4,D1RETYS2: MOV R4,#10 ;延时子程序2,精确延时4740微秒D2: MOV R5,#235DJNZ R5,$DJNZ R4,D2RETYS3: MOV R4,#2 ;延时程序3,精确延时1000微秒D3:MOV R5,#248DJNZ R5,$DJNZ R4,D3RETEND。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
51单片机实现红外编码检测通过51 单片机及外围电路实现对接受信号的处理(通过外部中断和计数器)获得信号的01编码,设备显示。
红外传感基础知识:❖红外发光管:红外发光二极管通常使用砷化镓(GaAs)、砷铝化镓(GaAlAs)等材料,采用全透明或浅蓝色、黑色的树脂封装。
产生的光波波长为940nm左右,为红外光❖红外接收头:左图为一常用的红外接收模块。
其内部含有高频的滤波电路,专门用来滤除红外线合成信号的载波信号(38KH),并送出接收到的信号。
当红外线合成信号进入红外接收模块,在其输出端便可以得到原先发射器发出的数字编码,只要经过单片机解码程序进行解码,便可以得知按下了哪一个按键,而做出相应的控制处理,完成红外遥控的动作。
❖红外发送协议:引导码+客户码1+客户码2+操作码+操作反码***用户真正须要的只有操作码***❖调制:“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率(因红外接收头能接收的红外线为38KHz 左右),还可达到降低电源功耗的目的。
主要内容:通过51 单片机及外围电路实现对接受信号的处理(通过外部中断和计数器)获得信号的01编码,用设备显示,(lcd或数码管);这里管脚的对应P3.2接受红外对管信息,lcd接线:主程序:#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<lcd.h>sbit IR=P3^2; //红外接口标志/*------------------------------------------------全局变量声明------------------------------------------------*/unsigned char irtime;//红外用全局变量bit irpro_ok,irok;unsigned char IRcord[4];unsigned char irdata[33];/*------------------------------------------------函数声明------------------------------------------------*/void Ircordpro(void);/*------------------------------------------------定时器0中断处理------------------------------------------------*/void tim0_isr (void) interrupt 1 using 1{irtime++; //用于计数2个下降沿之间的时间}/*------------------------------------------------外部中断0中断处理------------------------------------------------*/void EX0_ISR (void) interrupt 0 //外部中断0服务函数{static unsigned char i; //接收红外信号处理static bit startflag; //是否开始处理标志位if(startflag){if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5msi=0;irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1irtime=0;i++;if(i==33){irok=1;i=0;}}else{irtime=0;startflag=1;}}/*------------------------------------------------定时器0初始化------------------------------------------------*/void TIM0init(void)//定时器0初始化{TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值TH0=0x00; //重载值TL0=0x00; //初始化值ET0=1; //开中断TR0=1;}/*------------------------------------------------外部中断0初始化------------------------------------------------*/void EX0init(void){IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)EX0 = 1; //使能外部中断EA = 1; //开总中断}/*------------------------------------------------红外码值处理------------------------------------------------*/void Ircordpro(void)//红外码值处理函数{unsigned char i, j, k;unsigned char cord,value;k=1;for(i=0;i<4;i++) //处理4个字节{for(j=1;j<=8;j++) //处理1个字节8位{cord=irdata[k];if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差value|=0x80;if(j<8){value>>=1;}k++;}IRcord[i]=value;value=0;}irpro_ok=1;//处理完毕标志位置1}/*------------------------------------------------主函数------------------------------------------------*/void main(void){unsigned char temp[3];unsigned int i;EX0init(); //初始化外部中断TIM0init();//初始化定时器lcd_init(); // 初始化LCDdelay(10);lcd_pos(0); // 设置显示位置为第一行的第0个字符while(1)//主循环{if(irok) //如果接收好了进行红外处理{Ircordpro();irok=0;}if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等{/*------------------------------------------------将ascii的数字显示:即将字符对应的十进制数的每一位付给temp并转换成字符------------------------------------------------*/temp[0]=IRcord[2]%10+48;//个位temp[1]=IRcord[2]%100/10+48;//十位temp[2]=IRcord[2]/100+48;//百位lcd_wcmd(0x01); //清除LCD的显示内容delay(1);lcd_pos(0);lcd_wdat('*');lcd_wdat(temp[2]);lcd_wdat(temp[1]);lcd_wdat(temp[0]);lcd_wdat('*');for(i=0;i<10;i++)delay(100);}}}/*-------------------------------------------------#include<lcd.h>文件(lcd用到的一些函数)----------------------------------------------------*/#include<reg52.h>#include <intrins.h>/*------------------------------------------------定义数据类型------------------------------------------------*/ typedef unsigned char BYTE;typedef bit BOOL ;/*------------------------------------------------定义控制位------------------------------------------------*/ sbit rs = P2^6; //sbit rw = P2^5;sbit ep = P2^7;/*------------------------------------------------声明函数------------------------------------------------*/delay(BYTE ms){ // 延时子程序BYTE i;while(ms--){for(i = 0; i< 250; i++){_nop_();_nop_();_nop_();_nop_();}}}BOOL lcd_bz(){ // 测试LCD忙碌状态BOOL result;rs = 0;rw = 1;ep = 1;_nop_();_nop_();_nop_();_nop_();result = (BOOL)(P0 & 0x80);ep = 0;return result;}lcd_wcmd(BYTE cmd){ // 写入指令数据到LCD while(lcd_bz());rs = 0;rw = 0;ep = 0;_nop_();_nop_();P0 = cmd;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}lcd_pos(BYTE pos){ //设定显示位置lcd_wcmd(pos | 0x80);}lcd_wdat(BYTE dat){ //写入字符显示数据到LCD while(lcd_bz());rs = 1;rw = 0;ep = 0;P0 = dat;_nop_();_nop_();_nop_();_nop_();ep = 1;_nop_();_nop_();_nop_();_nop_();ep = 0;}lcd_init(){ //LCD初始化设定lcd_wcmd(0x38); //delay(1);lcd_wcmd(0x0c); //delay(1);lcd_wcmd(0x06); //delay(1);lcd_wcmd(0x01); //清除LCD的显示内容delay(1);}。