资讯详情

红外解码程序(用1602显示码值)

#include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit beep=P1^7; bit startflag; //定义一个扫描开始标志位 bit irreceok;//红外接收OK标志位 bit irprosok;//红外接收处理OK标志位 uchar irdata[33];//定义一个存放编码的数组。引导码1位,客户码8位,客户反码8位,数据码8位,数据反码8位 ,共33位 uchar bitnum;//接收到的第几位数据的标志位 uchar irtime;//定义红外扫描时间 uchar ircode[4];//为四个码值定义一个数组存放,把四位码分开 uchar disp[8];//四组数据,每组拆成高四位和低四位,共八个元素 /**************1602部分******************/ sbit lcden=P1^2; sbit lcdrs=P1^0; sbit lcdrw=P1^1; /*char code Tab[]={'0','1','2','3','4','5','6','7','8', '9','A','B','C','D','E','F'};*/ char code Tab[]="0123456789abcdef"; void delay(uint z) //延时子程序 { uint x,y; for(x=z;x>0;x--) for(y=220;y>0;y--); }

void write_com(uchar com)//定义一个带参数的写命令子程序 { lcdrs=0; //1602的rs为0时,接收命令,为1时接收数据 P0=com;//把void write_com(uchar com)中的COM中的数据给P0口 delay(2); lcden=1; delay(2); lcden=0; delay(2); }

void init_1602()//定义一个初始化子程序 { lcden=0; lcdrw=0; write_com(0x38);//调用 write_com子程序并把0x38赋给P0口,显示模式打开 write_com(0x0f);//调用 write_com子程序并把“开显示,显示光标,光标闪烁”指令码赋给P0口 write_com(0x06);//调用 write_com子程序并把“地址指针加1,整屏不移动”指令码赋给P0口 //write_com(0x80+0x10);//数据指针初始化,让指针指向可显示的最右端 write_com(0x80);//数据指针初始化,让指针指向最左端,显示从第一行开始 write_com(0x01);//调用 write_com子程序并把"清零指"令码赋给P0口 } void write_dat(uchar dat)//定义一个带参数的写数据子程序 { lcdrs=1; //1602的rs为0时,接收命令,为1时接收数据 P0=dat;//把void write_shu(uchar shu)中的COM中的数据给P0口 delay(2); lcden=1; delay(2); lcden=0; delay(2); } void delayms(uint t) { uint i,j; for(i=t;i>0;i--) for(j=110;j>0;j--); } void timer0init()//定时器O初始化 { TMOD=0x02;//定时器设成方式2,因为方式2可以自动重装初值 TH0=0x00;//高位设为O TL0=0x00;//低位设为O ET0=1; //中断打开 EA=1;//总中断打开 TR0=1;//定时器打开 }

void int0init()//外部中断O初始化,按P3。2 { IT0=1;//设为下降沿触发方式。IT0=0为低电平触发。因为红外输入高时,接收为低,要从低开始计时 EX0=1;//外部中断打开 EA=1;//总中断打开 }

void irpros()//红外提取处理程序 { uchar i,k,j,irvalue; k=1;//第一k=0是引导码,不须要。所以从K=1开始提取编码,把K=0的引导码去掉 for(j=0;j<4;j++)//共有四个码,所以循环四次 { for(i=0;i<8;i++)//每个码八位,循环八次 { irvalue=irvalue>>1;//irvalue低位在前,高位在后,所以右移,判断8次,右移7次 if(irdata[k]>6)//如果两个中断的时间为1.125MS,说明传的是0,1.125/0.255=4.4个irtime, //如果两个中断的时间为1.125MS,说明传的是1,2.25/0.255=8.8个irtime, //我取中断值6;如果irdata大于6,说明是1,小于6说明是0; { irvalue=irvalue|0x80; } k++;//每提一次,K自增一次,一共要33次 } ircode[j]=irvalue; } irprosok=1; beep=0; delay(3); beep=1; } void irwork() { disp[0]=ircode[0]/16;//取高四位 disp[1]=ircode[0]%16;//取低四位 disp[2]=ircode[1]/16;//取高四位 disp[3]=ircode[1]%16;//取低四位 disp[4]=ircode[2]/16;//取高四位 disp[5]=ircode[2]%16;//取低四位 disp[6]=ircode[3]/16;//取高四位 disp[7]=ircode[3]%16;//取低四位 } void display() { write_com(0x80); write_dat(Tab[disp[0]]); write_dat(Tab[disp[1]]); write_dat(Tab[disp[2]]); write_dat(Tab[disp[3]]); write_dat(Tab[disp[4]]); write_dat(Tab[disp[5]]); write_dat(Tab[disp[6]]); write_dat(Tab[disp[7]]); } void main() { init_1602(); timer0init(); int0init(); while(1) { if(irreceok)//判断接收是否OK { irpros();//接收OK就要处理.把数据从irdata中提出来 irreceok=0;//要把irreceok清0,为下一次接收做准备 } if(irprosok) { irwork();//如果处理OK,把数据分离,可以去显示 irprosok=0;//要把irprosok清0,为下一次处理做准备 } display();//显示函数还没写,有待完善 } }

void timer0() interrupt 1//定时器0中断函数 { irtime++;/*irtime为字符型,最大为255,输入开始时读一次irtime 然后清0,结束再读一次,irtime乘以255就是一次扫描定时的时间*/ } void int0() interrupt 0//外部中断0函数,这是关键 { if(startflag)//如果startflag=1就开始接数据 { if(irtime>30) //接收引导码,引导码有9MS,9/0.256=33.15,在这就取32即可 //说明这时检测到了引导码 { bitnum=0;//收到引导码后,bitnum清O准备装数据 } irdata[bitnum]=irtime;//第1个bitnum=0的数据被装入数组。 irtime=0;//清0就不会对下次有影响 bitnum++; //不停地给数组加入新数据 if(bitnum==33)//如果bitmun=33,说明一帧数据传完 { bitnum=0;//bitnum清0为接收下一帧做准备 irreceok=1;//主函数只要判断irreceok是否为1做出后面的决定 } } else // { startflag=1; irtime=0; } }

-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台