51单片机红外解码资料+源代码

合集下载

基于51单片机的红外遥控程序(新)

基于51单片机的红外遥控程序(新)
P2=0x7f;//0x78
P1=table[shuma];
/* delay_ms(3);
P2=0xb8;
P1=table[bai];
delay_ms(3);
P2=0xd8;
P1=table[shi];
delay_ms(3);
P2=0xe8;
P1=table[ge];
}
///////////////////////////////////////////////////////////////////////
void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数
{
static unsigned char i;
//使用12M晶振 适用于TC9012芯片,其他芯片请自行更改解码时序
#include <REGX52.h>
#include<stdio.h>
#include<intrins.h>
////////////////////////////////////////////////
#define TURE 1
break;//2
case 2:
display(3);
fengming();
SBUF=3;
TI=0;
delay_ms(10);
break;//3
case 3:
display(4);
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}
/******************************************************************/

红外遥控编码原理及C程序,51单片机红外遥控

红外遥控编码原理及C程序,51单片机红外遥控
break;
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)

基于51单片机的NEC红外解码C语言程序

基于51单片机的NEC红外解码C语言程序

基于51单片机的NEC红外解码C语言程序#includetypedef unsigned intuint ;typedef unsigned char uchar ;#define Main_fosc 11059200ULsbitIR_test = P3^2;sbit du = P2^6;sbit we = P2^7;ucharDat[33],Number[4],counter,Receive_ok;/*-----------函数声明------------*/voidIR_init();void translate();void display(uchar *n);voidDelay_ms(uintnum);/*-------------------------------*/uchar table[]={0x3F, //"0"0x06, //"1"0x5B, //"2"0x4F, //"3"0x66, //"4"0x6D, //"5"0x7D, //"6"0x07, //"7"0x7F, //"8"0x6F, //"9"0x77, //"A"0x7C, //"B"0x39, //"C"0x5E, //"D"0x79, //"E"0x71, //"F"};void main(){IR_init();while(1){if(Receive_ok)translate();display(Number);}}voidIR_init(){TMOD = 0X02;TH0 = 0xa4;TL0 = 0xa4;EA = 1;ET0 = 1;TR0 = 1;EX0 = 1;IT0 = 1; //下降沿触发}void timer0()interrupt 1 {counter++; // 100us}/*------红外接收中断------*/voidIR_read() interrupt 0{static bit start_flag = 0;static char i=1;if(start_flag){if(counter>=125&&counter<=145) {counter = 0;Dat[0] = 1;}else if(Dat[0] == 1){if(counter>14)Dat[i] = 1;elseDat[i] = 0;counter = 0;i++;if(i==33){Dat[0] = 0;Receive_ok = 1;start_flag = 0;i = 1;}}else{start_flag = 0;}}else{counter = 0;start_flag = 1;}}/*----------解码---------*/ void translate(){uchari,j;for(i=0;i<4;i++)for(j=0;j<8;j++){Number[i]>>=1;if(Dat[i*8+j+1]) Number[i] |= 0x80;}Receive_ok = 0;}/*------数码管显示------*/ void display(uchar *n) {uchar a[8],i;a[0] = n[0]/16;a[1] = n[0]%16;a[2] = n[1]/16;a[3] = n[1]%16;a[4] = n[2]/16;a[5] = n[2]%16;a[6] = n[3]/16;a[7] = n[3]%16;for(i=0;i<8;i++){we = 1;switch(i){case 0:P0 = 0xfe;break; //1111 1110 case 1:P0 = 0xfd;break; //1111 1101 case 2:P0 = 0xfb;break; //1111 1011 case 3:P0 = 0xf7;break; //1111 0111 case 4:P0 = 0xef;break; //1110 1111 case 5:P0 = 0xdf;break; //1101 1111 case 6:P0 = 0xbf;break; //1011 1111 case 7:P0 = 0x7f;break; //0111 1111 }we = 0;du = 1;P0 = table[a[i]];du = 0;Delay_ms(1);}}/*---------延时1MS----------*/ voidDelay_ms(uintnum){uint i;do{i = Main_fosc/96000;while(i--);}while(--num); }。

51单片机红外遥控解码程序

51单片机红外遥控解码程序

51单片机红外遥控解码程序类别:单片机/DSP 阅读:2975编者按:以下是网友编写的遥控解码程序!一种用延时等待的解码方法,比较容易理解,但缺点是占用CPU运行时间,第二种方法用定时器和外中断的解码方法,初学不易理解,但优点也很明显,第二种方法如果能解决连发解码就比较完美,更完善的红外遥控解码程序,请参考本站TOPA V-2008,TOP51-2005所配程序。

解码方法一;//单片机接收红外解读程序\\;硬件结构:8951,P0口数码管段码,P2.0-P2.3为位,P1为8个LED;P3.2为红外接收头,P2.7蜂鸣器,晶振12M;适用UPD6121 6122芯片接收;---------------------------------------------------------ORG 0000HAJMP MAIN ;转入主程序ORG 0003H ;外部中断P3.2脚INT0入口地址AJMP INT ;转入外部中断服务子程序(解码程序);以下为主程序进行CPU中断方式设置MAIN: SETB EA ;打开CPU总中断请求SETB IT0 ;设定INT0的触发方式为脉冲下降沿触发SETB EX0 ;打开INT0中断请求AJMP $;以下为进入P3.2脚外部中断子程序,也就是解码程序INT: CLR EA ;暂时关闭CPU的所有中断请求MOV R6,#10SB: ACALL YS1 ;调用882微秒延时子程序JB P3.2,EXIT ;延时882微秒后判断P3.2脚是否出现高; 电平如果有就退出解码程序DJNZ R6, SB ;重复10次,目的是检测在8820微秒内;如果出现高电平就退出解码程序;以上完成对遥控信号的9000微秒的初始低电平信号的识别。

JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲ACALL YS2 ;延时4.74毫秒避开4.5毫秒的结果码MOV R1,#1AH ;设定1AH为起始RAM区MOV R2,#4;PP: MOV R3,#8JJJJ: JNB P3.2,$ ;等待地址码第一位的高电平信号LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信;号此时的高低电平状态MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中JNC UUU ;如果为0就跳转到UUULCALL YS3;UUU: 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,1CH ;比较数据码和数据反码是否正确?CPL AXRL A,1DH ;将1CH的值取反后和1DH比较不同则无效丢弃,核对数据是否准确JNZ EXITMOV DPTR,#TAB ;表头地址送指针MOV A,1DHANL A,#0FH ;相与,得到低四位码MOVC A,@A+DPTRMOV 1EH,A ;查表得表码存入1EHMOV A,1DHSWAP AANL A,#0FHMOVC A,@A+DPTRMOV 1FH,A ;查表得高四位码存入1FMOV R7,#20HDISP:MOV P0,1FH ;送数码管显示CLR P2.1ACALL YS2SETB P2.1MOV P0,1EHCLR P2.2ACALL YS2SETB P2.2MOV P1,1DH ;将按键的键值通过P1口的8个LED显示出来!CLR P2.7 ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功LCALL YS2SETB P2.7 ;蜂鸣器停止DJNZ R7,DISPEXIT: SETB EA ;允许中断RETI ;退出解码子程序YS1: 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,D3RETTAB: DB 0C0H,0DEH,0A2H,8AH,9CH,89H,81H,0DAH,80H,88H,90H,85H,0E1H,86H,0A1H,0B1H;数据表,0-9-A-FEND解码方法二你的解码程序和我现在用的解码程序大体是一样的,我自己实际做了一下,发现按下遥控器,接收到红外信号后,数码管闪的厉害。

基于c51的红外解码源代码

基于c51的红外解码源代码

#include<reg52.h>sbit DQ=P3^2; //接收头的数据输出引脚sbit FM=P2^3; //蜂鸣器的控制端unsigned char dat[4]; //用于接收4个字节的红外数据unsigned char data_code; //用于保存按键值sbit L0=P1^0;sbit L1=P1^1;sbit L2=P1^2;sbit L3=P1^3;sbit L4=P1^4;sbit L5=P1^5;sbit L6=P1^6;sbit L7=P1^7;bit key_on; //定义一个按键闭合标志位,如果按键被按下了,该位置1/*--毫秒级延时函数,参数为多少则延时多少毫秒--*/void delay_ms(unsigned int t){unsigned int a,b;for(a=0;a<t;a++){for(b=0;b<113;b++){;}}}/*定时器0和中断0的初始化函数*/void init(){TMOD=0x01; //定时器0工作在方式1,为16位的定时器EX0=1; //开中断1IT0=1; //低电平触发中断0EA=1; //开总中断}/*对4个字节的红外遥控数据进行解码操作的函数这4个字节数据保存在了dat[i]的数组中返回值为dat[2],它是我们需要的的按键值如果解码成功,会返回正确的dat[2],如果解码失败那么返回的dat[2]=0 */unsigned char de_code(){unsigned char i,j;unsigned char temp; //用于暂存接收到的数据unsigned int high_time,low_time; //分别用于保存高低电平的时间值for(i=0;i<4;i++) //循环4次才能接收完毕4个字节的数据{for(j=8;j>0;j--) //循环8次才能接收完毕一个字节的数据{temp=temp>>1; //数据整体右移一位,用于接收一个位数据TL0=0x00; //定时器0赋初值0TH0=0x00;TR0=1; //打开定时器0,对低电平时间进行计数while(DQ==0) //如果为低电平就一直while语句中此循环{if(TH0>0x03) //如果低电平时间远超过0.56ms了,说明不是0或者1return dat[2]=0x00; //跳出中断并返回一个值为0的按键码,表明本次解码失败}TR0=0; //关闭定时器0low_time=TH0*256+TL0; //计算低电平时间TL0=0x00; //重新装初值0TH0=0x00;TR0=1; //开定时器0,对高电平时间进行计数while(DQ==1){if(TH0>0x08) //如果高电平时间远超过1.69ms了,说明不是0或者1return dat[2]=0xff; //跳出中断并返回一个值为0的按键码,表明本次解码失败}TR0=0; //关定时器0,计算高电平时间high_time=TH0*256+TL0; //计算高电平时间if((low_time<370)||(low_time>640)) //如果高电平时间不是0.56ms左右(远离这个区间)return dat[2]=0x00; //那么返回0,说明解码失败if((high_time>420)&&(high_time<620)) //如果高电平时间在0.56ms左右(在这个区间即可)temp=temp&0x7f; //说明这个位数据为0,保存数据0else if((high_time>1300)&&(high_time<1800)) //如果高电平时间在1.69ms左右(在这个区间即可)temp=temp|0x80; //说明这个位数据为1,保存数据1else return dat[2]=0x00; //如果高电平时间不是1.69ms左右,那么返回0,说明解码失败}dat[i]=temp; //每解码完成一个字节后,对这个字节进行保存}if(dat[2]==~dat[3]) //解码得到的按键值与按键值的反码取反后进行比较{ //如果一致,则说明解码成功FM=0; //蜂鸣器发声,播报解码成功key_on=1; //置1,表明按键被按下return dat[2]; //返回这个解码成功的按键值}else return dat[2]=0x00; //如果不一致,那么返回0,说明解码失败}void int0_ISR() interrupt 0{unsigned int high_time,low_time; //分别用于保存高低电平的时间值EX0=0; //关闭中断TL0=0x00; //装初值0TH0=0x00;TR0=1; //开定时器0while(DQ==0) //{if(TH0>0x25) //如果低电平时间远超过9ms了,说明不是引导码{EX0=1; //开中断0,准备下次中断return; //跳出此次中断}}TR0=0;low_time=TH0*256+TL0;TL0=0x00;TH0=0x00;TR0=1;while(DQ==1){if(TH0>0x20) //如果高电平时间远超过4.5ms了,说明不是引导码{EX0=1; //开中断0,准备下次中断return; //跳出此次中断}}TR0=0; //关定时器0,计算电平时间high_time=TH0*256+TL0; //计算高电平时间if((low_time>7800)&&(low_time<8800)&&(high_time>3600)&&(high_time<4700))//如果低电平在9ms左右,高电平在4.5ms左右,说明为引导码data_code=de_code(); //对引导码后面的32位数据进行解码接收,并获得按键值EX0=1; //解码接收完成后,开中断delay_ms(30); //延时30ms,让蜂鸣器发声30msFM=1; //停止发声}void main(){init();while(1){if(key_on==1) //如果按键被按下了,那么就执行相应按键的操作{key_on=0; //按键标志位清0switch(data_code){case 0x45: L0=~L0; break; //此按键被按下,就对L0进行控制case 0x46: L1=~L1; break; //此按键被按下,就对L1进行控制case 0x47: L2=~L2; break; //此按键被按下,就对L2进行控制case 0x44: L3=~L3; break; //此按键被按下,就对L3进行控制case 0x40: L4=~L4; break; //此按键被按下,就对L4进行控制case 0x43: L5=~L5; break; //此按键被按下,就对L5进行控制case 0x07: L6=~L6; break; //此按键被按下,就对L6进行控制case 0x15: L7=~L7; break; //此按键被按下,就对L7进行控制default:break;}}}}。

REMOTE.为51单片机编写的红外遥控解码程序

REMOTE.为51单片机编写的红外遥控解码程序

1模块详细设计结果描述1.1基本原理REMOTE模块是针对NEC标准的遥控发射信号设计的。

共占用MCU两个资源:INT0和TIMER0。

通过INT0接收遥控信号,侦测脉冲信号的起止点。

通过TIMER0计算脉冲信号的时间长度。

根据时间的长短可识别出各种码值,从而可判断出是否是电磁干扰,或码值是否有效。

1.2扇出无。

1.3硬件接口请查阅“TOP LOAD SYSTEM MCU BOARD REV:01” 的原理图。

2源程序清单2.1源程序:下面所列为REMOTE模块的程序清单,(文件名:REMOTE.ASM)$INCLUDE(REMOTE.INC)CSEG AT EX_ADDR ;ADDR=03H FOR EXTERN INTERUPTER 0;ADDR=13H FOR EXTERN INTERUPTER 1LJMP EX_SERVERCSEG AT ET_ADDR ;ADDR=0BH FOR TIMER0 INTERUPTER;ADDR=1BH FOR TIMER1 INTERUPTERLJMP ET_SERVER;;;************************************************************************;;;* NAME: REMOTE_INIT *;;;* PURPOSE: Initial the Remote peripheral-INT0,TIMER1 *;;;* FUNCTION: Be called when system reset *;;;* OUTPUT: ET0,EX0,IT0,TMOD,REMMODE,REMCONT,REMV ALID,RPTV ALID *;;;* RAM:ACC,DPTR,TEMPDATA,LOWCONT *;;;* Excuting: Be called After main(){ *;;;*C-Declare: void REMOTE_INIT(void); *;;;************************************************************************RSEG ?PR?REMOTE?REMOTE INBLOCKREMOTE_INIT:SETB ET_ENABLE ;T0 enableSETB EX_ENABLE ;INT0 OR INT1 enableSETB EX_TRIG ;INT0 OR INT1MOV A,TMOD ;Set T0ANL A,#TMOD_MOD1ORL A,#TMOD_MOD2MOV TMOD,AMOV REMMODE,#0HMOV REMCONT,#0HCLR REMV ALIDCLR REMTEMPCLR RPTVALIDRET;;;************************************************************************ ;;;* NAME: EX_SERVER * ;;;* PURPOSE: Analyse and calculate remote wave,get the valid wave. * ;;;* FUNCTION: wil be called When rmeote wave is received. * ;;;* return REMMDOE,REMCONT * ;;;* SCOPE:NONE. * ;;;* INPUT:REMMODE,REMCONT,REMV ALID,RPTV ALID * ;;;* OUTPUT:REMMODE,REMCONT * ;;;* RAM:ACC,DPTR,TEMPDATA,LOWCONT * ;;;* Time(MAX): 80T+100us * ;;;* Excuting: Be called in INT0 interrupt * ;;;* Ref.Flowchart: REMOTE.wmf * ;;;************************************************************************ RSEG ?PR?REMOTE?REMOTE INBLOCKEX_SERVER:PUSH ACCPUSH DPHPUSH DPLPUSH PSWJB POWER_EN,SERVER1JB EX_TRIG,SERVER1SETB EX_TRIGLJMP EX_RSETALLSERVER1:MOV A,#DELAY100USDELAY_LOOP:DEC AJNZ DELAY_LOOPMOV DPTR,#MODETABMOV A,REMMODESUBB A,#9HJNC EX_RSETMOV A,REMMODERL AJMP @A+DPTRMODETAB:AJMP CODEMODE0AJMP CODEMODE1AJMP CODEMODE2AJMP CODEMODE3NOPNOPNOPNOPAJMP EX_RSETALLNOPNOPCODEMODE0:JB REM_RECEIVE,EX_RSETCLR TI_CTRLMOV TCON_HIGH,#PT1200_HIGH1MOV TCON_LOW,#PT1200_LOW1SETB TI_CTRL ;Start T0 1.72ms timer.MOV TEMPDATA,#80HAJMP EX_RSETCODEMODE1:JB REM_RECEIVE,EX_RSETAJMP EX_RTNCODEMODE2:JB REM_RECEIVE,EX_RTNCLR TI_CTRLMOV A,TCON_HIGHCLR CSUBB A,#R4500_lOWJC CHK_REPEA TSUBB A,#RANGE4500JNC EX_RSETALLMOV TCON_HIGH,#0H ;Timer=4.5ms,the leader code validMOV TCON_LOW,#R1125_PRESETB TI_CTRL ;Start timer.MOV REMMODE,#3H ;turn to mode3AJMP EX_RTNCHK_REPEA T:MOV A,TCON_HIGHCLR CSUBB A,#R2250_lOW1JC EX_RSETALLSUBB A,#RANGE2250JNC EX_RSETALLJB REMTEMP,SET_MODE5 ;Timer=2.25msJNB RPTVALID,EX_RSETSET_MODE5:MOV TCON_HIGH,#PT1200_HIGH ;The repeat leader code validMOV TCON_LOW,#PT1200_LOWSETB TI_CTRL ;Start 1.125ms timerMOV REMMODE,#5H ;turn to mode5AJMP EX_RTNEX_RSETALL:CLR REMV ALIDCLR REMTEMPCLR RPTVALIDEX_RSET:MOV REMMODE,#0HMOV REMCONT,#0HEX_RTN:POP PSWPOP DPLPOP DPHPOP ACCRETICODEMODE3:JB REM_RECEIVE,EX_RSETCLR TI_CTRLMOV A,TCON_HIGHMOV TCON_HIGH,#0HMOV TCON_LOW,#R1125_PRESETB TI_CTRLCJNE A,#R1125_HIGH,MOD3_LPWR ;TCON_HIGH=0,跳转DATA_CHK,检查TCON_LOW。

51单片机红外解码、超声波测距程序(详细解释程序)

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]]; //取出千位数,查表,输出。

c51单片机红外解码程序-汇总版和c语言版

c51单片机红外解码程序-汇总版和c语言版

精心整理纯软件解码---汇编版利用程序判电平和时间进行解码,缺点是浪费系统软件资源;优点是对系统硬件要求稍低ORG0000HT0ZDBIT20H.2XHBITP3.3;红外接收头数据接口RSBITP2.3RWBITP2.4============================================================JBXH,$;等待电平变低,解码从这开始CLRP2.0;开信号指示灯,表示正在接收信号MOVP0,#8EHSETBTR0;开T0中断LCALLYS3MSJBXH,DDXH;干扰检测LCALLYS3MSJBXH,DDXH;干扰检测DD1:JBT0ZD,DDXH;是否超出接收允许时间JNBXH,DD1;等待电平变高LCALLYS3MSJNBXH,DDXH;干扰检测DD2:JBT0ZD,DDXH;是否超出接收允许时间JBXH,DD2;等待电平变低JSSJ:;信号确认,开始接收数据ZJ:;MOVR7,#100;TSY:MOVR6,#255DJNZR6,$CPLBBDJNZR7,TSYMOVA,#0CDH;键值高位输出LCALLYJP_XZLMOVA,R4MOVB,#10HDIVABMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0CEH;键值低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTR LCALLYJP_XSJ; LCALLDYBF;调用灯控制子程序LJMPDDXH;返还等待下一次信号YS845:;延时845微秒MOVR7,#255RETRETDIVABMOVCA,@A+DPTR LCALLYJP_XSJMOVA,#0C1H;用户码前低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTR LCALLYJP_XSJMOVA,#0C4H;用户码后高位输出LCALLYJP_XZLMOVA,31HMOVB,#10HDIVABMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0C5H;用户码后低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTRLCALLYJP_XSJ;============此处专门针对我的开发板和遥控,不是解码的关键,只是一种应用举例BA7:CJNEA,#52H,BAB;是否8号键按下CPLP1.7;点亮1号灯BAB:RETCSH:;=============液晶初始化===============MOVA,#00111000B;8位数据,双行显示,5-7字型LCALLYJP_XZL;调用写液晶指令MOVA,#00001100B;显示屏开启,光标出现在地址计数器位置,光标不闪烁LCALLYJP_XZL;调用写液晶指令MOVA,#00000110B;光标右移一格,AC值加一,字符全部不动LCALLYJP_XZL;调用写液晶指令MOVA,#81H;LCALLYJP_XZLMOVA,#4CH;L的ASCII码LCALLYJP_XSJMOVA,#83H;LCALLYJP_XZLLCALLYJP_XZLMOVA,#61H;a的ASCII码LCALLYJP_XSJMOVA,#8EH;LCALLYJP_XZLMOVA,#6FH;o的ASCII码LCALLYJP_XSJMOVA,#0C2H;LCALLYJP_XZLMOVA,#48H;H的ASCII码LCALLYJP_XSJMOVA,#0C6H;LCALLYJP_XZLMOVA,#48H;H的ASCII码LCALLYJP_XSJMOVA,#0CAH;LCALLYJP_XZLMOVA,#4AH;J的ASCII码LCALLYJP_XSJMOVA,#0CBH;LCALLYJP_XZLMOVA,#5AH;Z的ASCII码RETRETCLRESETBRSCLRRWSETBEMOVP0,A;写数据CLRERET;=========查询忙碌标志============ CHECK_BUSY:PUSHACCBUSY_LOOP:CLRESETBRWCLRRSSETBEMOVA,P0;读取状态JBp0.7,BUSY_LOOPPOPACCLCALLDELRETDEL:MOVR6,#5RET/////////#definezd_cffsIT0///中断触发方式设置#definezd_dkEX0///中断打开设置////#definestc_dsqszAUXR&=0x7F;//定时器时钟12T模式,不需要可在AUXR....前加// ///**************************************************/****************************************************************** *****本程序使用外部中断加定时器来实现红外解码,占用系统软件资******** *****源极少,硬件方面占用了一个外部中断,定时器中断还可以进行******** *****一些简单的运用,软件部分可以做很多的动作,就看你发挥了!**************************************************************************/ #defineshi_jian定时器设置,请勿更改unsignedcharhwyhmh,hwyhml,hwjz,hwsj,hwjmws;///全局变量bithwjmok,yxjm;///全局变量,红外解码OK,允许解码voidmain(void){EA=1;//总中断打开zd_cffs=1;//外部中断_边沿触发方式zd_dk=1;//外部中断_打开ET0=1;//while(1)}}}定时器0{hwjz=0;TR0=0;//}voidZDhwjsCX(void)zd_rkdzusing3{unsignedinta=TH0*256+TL0;TL0=0;TH0=0;TR0=1;///开启T0if(a>shi_jian_*13000&&a<shi_jian_*14000)///if1分支2.判引导码13-14ms {hwsj=0;hwjmws=32;yxjm=1;}elseif(yxjm)///if1分支1.已收到引导码,允许解码{if(a>shi_jian_*11000&&a<shi_jian_*12000&&hwjmws==0)///if2分支1。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

位地 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 号
{ TMOD=0X02; //方式 2
TH0=0X00; //高第八位清零
TL0=0X00;
EA=1; //打开全局中断允许位 (中断允许寄存器 IE)
ET0=1;
//打开定时器 0 中断允许位 (中断允许寄存器
IE) TR0=1;
//寄存器 TCON,置一启动定时器 0
} void int0init(void)
}
irprosok=1;
} void main()
//从这里开始
{ timer0init(); int0init(); while(1)
//定时器 0 初始化 //外部中断 0 初始化 //大循环
{
if(irreceiveok)
{
irpros();
irreceiveok=0;
}
if(irprosok)
红外发射电路如图: 左边是一个 222 的无极性电容,然后接地。 发送 38K 方波,就是载波
上述“0”和“1”组成 32 位二进制代码,包括两次 8 位用户码, 8 位数据码,和 8 位数据反码以及最后的同部位。 一体化红外接收管原理图
一体化红外接收头在检测到 38K 红外遥控载波信号时输出低
电平,在未检测到 39K 的红外遥控载波信号时输出高电平。
wela=1;
P0=smg_we[i];
wela =0;
delay(1);
P0=0xff;
delay(1);
}
}
void irpros(void) 零)
//1.125ms/0.2777=4.39=4.05 个 irtime(数据
{ 中间值 6
//2.25ms/0.2777=8.10 个 irtime (数据一)取
uchar k,i,j;
uchar value; k=1; //跳过引导码
for(j=0;j<4;j++)
{
for(i=0;i<8;i++)
{ value=value>>1; //7 次
if(irdata[k]>6) //8 次
{
value=value | 0x80;
}
k++;
}
ircode[j]=value;
{
irwork();
irprosok=0;
}
display();
}
}
void timer0 () interrupt 1 //定时器 0,初值自动重装的 8 位定时器
{
//最大计数值 256,2 的 8 次方
irtime++; //256 //每加一,计数 256 次,计数一次时间为
0.001085069ms
//外部中断 0 初始化
{
IT0=1; //置一,跳变沿触犯方式,引脚 INT0 上,下降沿的
负跳变有效
EX0=1;
//外部中断 0 中断允许位
EAHale Waihona Puke 1; //全局中断允许位}
void irwork(void)
{
disp[0]=ircode[0]/16;
disp[1]=ircode[0]%16;
disp[2]=ircode[1]/16; disp[3]=ircode[1]%16;
51 单片机红外解码(NEC)
1,遥控发射及其编码
红外遥控编码具有以下特征: (1),采用脉宽调制串行码,以脉宽为 0.565ms,间隔 0.56ms, 周期为 1.125ms 的组合表示二进制的“0”。 (2)一脉宽为 0.565ms,间隔 1.685ms,周期为 2.25ms 的组合 表示二进制的“1”。
}
//每加一,计数 256 次,共需 0.2777ms
void int0 () interrupt 0 //外部中断 0(INT0)
{
if(startflag)
{
if(irtime>32) //说明收到的是引导码 13.5ms(引导码)
/0.2777=48.7 个 irtime { bitnum=0; }
}; uchar code smg_we[]={ 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf,
0xbf,
0x7f,
};
void delay(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
} void timer0init(void) //定时器 0 初始化
0x3F,/*0*/ 0x06,/*1*/
0x5B,/*2*/ 0x4F,/*3*/ 0x66,/*4*/ 0x6D,/*5*/ 0x7D,/*6*/ 0x07,/*7*/ 0x7F,/*8*/ 0x6F,/*9*/ 0x77,/*A*/ 0x7C,/*b*/ 0x39,/*C*/ 0x5E,/*d*/ 0x79,/*E*/ 0x71,/*F*/
disp[4]=ircode[2]/16; disp[5]=ircode[2]%16;
disp[6]=ircode[3]/16; disp[7]=ircode[3]%16; } void display(void) { uchar i; for(i=0;i<8;i++)
{ dula=1; P0=smg_du[disp[i]]; dula=0; P0=0xff;
irdata[bitnum]=irtime; irtime=0; bitnum++;
if(bitnum==33) { bitnum=0; irreceiveok=1; } } else { startflag=1; irtime=0; } }
相关文档
最新文档