51单片机的红外遥控解码参考程序
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单片机解码
车载红外遥控之51单片机对单片机的了解学习,是作为简单的遥控器解码学习的基础,因为本次DIY 是通过MCU 作为解码媒介的。
但实验中的DIY 方式又不必需要功能强大的ARM 系列单片机去实现,一般0851单片机就能解决。
本实验的演示功能是通过对红外遥控键值解码后,对设定的目标键值做出响应,实验中的响应是单片机对继电器的开合、通断控制,可以简单理解为单片机检测到遥控器某个指定的按键按下,则控制继电器实现开关的切换功能,实现过程如下:首先是选型,由于物资条件,我们考虑成本,所以选择的都是廉价器件,器件有车载MP3红外遥控,1318红外接收头,51系列的stc15F104w芯片,一个11.0592MHZ 的晶振,两个100pf容,一个继电器,一个二极管1N4148,一个三极管9012/S8550,两个200欧姆电阻。
收到的遥控编码信息发送至单片机,单片机对红外遥控的键值解码后在P3.5口输出控制信原理图所示。
最后,实现解码功能的51Figure 1原理图化定时器配置,之后是不断地轮询单片机的中断引脚,检测单片机的引脚状态是否改变,如果引脚状态被改变了,说明端口有数据到来,此时单片机的定时器将在中断中被激活。
定时器被激活的作用是用来给给每个二进制数据位进行定时的,将高低电平状态产生的时间存储到一个数组里面,最后将该时间值数组转换成高低电平状态。
左图是红外遥控采集单片机中断引脚的高低电平时间,并将得到的时间放在irdate 数组里,我们使用的红外遥控的编码是32位的编码。
由引导码、用户码、数据码和数据码反码组成32位的编码方式。
实验测试得到,引导码是有9ms 的高电平和4.5ms 的低电平组成。
用户码或数据码中的每一个位可以是位‘1’,也可以是位‘0’。
区分‘0’和‘1’是利用脉冲的时间间隔来区分,这种编码方式称为脉冲位置调制方式。
英文简写PPM 。
其脉冲调制是使用455KHz 晶体产生的载波脉冲实现。
总结:通过本次实验,了解到了红外遥控编码及解码的工作原理。
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解码方法二你的解码程序和我现在用的解码程序大体是一样的,我自己实际做了一下,发现按下遥控器,接收到红外信号后,数码管闪的厉害。
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单片机红外遥控解码,很详细(汇编语言,C语言等)
//i++;
if(TH0<3)
b=1;
else b=0;
TH0=0;
TL0=0;
}
uchar hw_key()
{
uchar j,m;
//i=0;
hw_start(); //等待低电平到来
hw_pulse();
for(j=0;j<24;j++) //测试用户码脉冲宽度
{
hw_pulse();
}
for(j=0;j<8;j++) //测试键码脉冲宽度
{
hw_pulse();
if(b==1)
m=(m<<1)|1;
else
m<<=1;
}
return m; //键码
}
while(in==0); //高电平到了,
TR0=0; //关闭定+;
TH0=0;
TL0=0;
TR0=1; //高电平到了,启动定时器1,测试高电平宽度
while(in==1); //低电平到了,
TR0=0; //关闭定时器1,高电平宽度测试完
请注意甄别内容中的联系方式诱导购买等信息谨防诈骗
51单片机红外遥控解码,很详细(汇编语言,C语言等)
单片机源程序如下:
#include
#define hw_hs0038_ENTITY
#include "hw_hs0038.h"
sbit in=P3^2;
//uchar i=0;
//uchar k[2];
bit bdata b=0;
/*
void timer0(void) interrupt 1 using 1
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;//刚进中断时关闭了分控,现在要打开}。
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。
keilc51红外遥控解码程序
keilc51红外遥控解码程序keil c51红外遥控解码程序本keil c51程序适用uPC1621/uPC1622及兼容的红外遥控器芯片,占用外部中断0和定时器1,以中断方式解码,节省系统资源,以查询方式检测遥控信号是否有效.解码思路:红外线经一体化接受头解码放到后送到单片机的外部中断0,单片机设置外部中断下降沿触发,T0和T1为16位定时器,T0在系统启动后定时5ms.T1在外部中断0启动后开始定时,初值为0,每次在INT0中断后先读T1计数值,并重设初值为0,而且判断T1的计数值,18.unsigned char IR_repeat=0;19.unsigned char IR_ready=0;20.unsigned char IR_poweron=0;21.//bit ir_done=0;22.// time constants23.unsigned int IRtimer=0; // IR timeout24.25.//cpu初始化26.void cpu_init(void)27.{28.TMOD=0X11; // T0 and T1 十六位定时29.TH0=0xee; //fosc=11.0592M,timer=5ms30.TL0=0x00;31.TR0=1; // run timer 0;32.TF0=0;33.34.ET0=1; // enable tmr 0 overflow interrupt35.IT0=1; // int0 edge sensitive36.EX0=1; // enable "int0"37.EA=1; // global interupt enable38.}39.40.//T0中断41.void tmrint() interrupt 142.{43.TH0=0xee;44.TL0=0x00;45.if (IRtimer) //IR接收超时46.--IRtimer; //47.else48.{49.IRstate=IR_idle;50.// IR_poweron=0;51.}52.}53.54.//Fosc=11.0592MHz55.#define msec_12p5 0x2d0056.#define msec_15 0x360057.#define msec_9 0x206658.//#define msec_9 0x106659.#define msec_2p5 0x90060.#define msec_0p9 0x33d61.#define msec_1p68 0x61062.63.64.//void IRint() interrupt 0(void)65.66.//When the IR receive pin goes low and interrupt is ge nerated67.// IR is collected by starting timer 2 in the first falling edge of the pin68.// then on every other falling edge, the timer value i s saved and the timer restarted .69.// the captured time is then used to get the IR data70.// a "start of data" is 13.5Msec,a "1" is 2.25Msec,a "0" i s 1.12 msec and a "repeat" is 11.25msec.71.// the counter increments at 1.085 Usec72.// I allow a fairly large tolerance to time jitter but there are no false triggers seen.73.74.void IRint() interrupt 075.{76.static unsigned char bits;77.unsigned short time;78.switch(IRstate)79.{80.case IR_idle:81.TL1=0;82.TH1=0;83.TR1=1;84.IRstate=IR_waitstart;85.IRtimer=26;86.break;87.case IR_waitstart: //P2_4=!P2_4;88.TR1=0;89.time=TH1;90.time =(time <<8)+TL1;;91.TL1=0;92.TH1=0;93.TR1=1;94.if ((time > msec_12p5)&&(time < msec_15)) // greate r than 12.5Msec & less than 15 msec = start code95.{96.IRaddr=0;97._IRaddr=0;98.IRdata=0;99._IRdata=0;100.bits=1;101.IRstate=IR_getaddr;102.}103.else if ((time > msec_9)&&(time < msec_12p5))// les s than 12.5Msec and greater than 9 msec =Repeat code 104.{105.IR_repeat=2;106.IRstate=IR_idle;107.}108.else109.{ // to short, bad data just go to idle110.IRstate=IR_idle;111.}112.break;113.case IR_getaddr: // P2_4=!P2_4;114.TR1=0;115.time=TH1;116.time =(time <<8)+TL1;;117.TL1=0;118.TH1=0;119.TR1=1;120.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle121.{122.IRstate=IR_idle;123.break;124.}125.if (time>msec_1p68)// greater than 1.68Msec is a 1126.{127.IRaddr|= bits;128.}129.bits=bits<<1;130.if (!bits)131.{132.IRstate=IR_getaddrinv;133.bits=1;134.}135.break;136.case IR_getaddrinv: //P2_4=!P2_4;137.TR1=0;138.time=TH1;139.time =(time <<8)+TL1;;140.TL1=0;141.TH1=0;142.TR1=1;143.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle144.{145.IRstate=IR_idle;146.break;147.}148.if (time>msec_1p68)// greater than 1.68Msec is a 1 149.{150._IRaddr|= bits;151.}152.bits=bits<<1;153.if (!bits)154.{155.IRstate=IR_getdata;;156.bits=1;157.}158.break;159.case IR_getdata:160.TR1=0;161.time=TH1;162.time =(time <<8)+TL1;;163.TL1=0;164.TH1=0;165.TR1=1;166.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle167.{168.IRstate=IR_idle;169.break;170.}171.if (time>msec_1p68)// greater than 1.68Msec is a 1172.{173.IRdata|= bits;174.}175.bits=bits<<1;176.if (!bits)177.{178.IRstate=IR_getdatainv;179.bits=1;180.}181.break;182.case IR_getdatainv:183.TR1=0;184.time=TH1;185.time =(time <<8)+TL1;;186.TL1=0;187.TH1=0;188.TR1=1;189.if ((time>msec_2p5)||(time<msec_0p9)) // if > 2.5mse c or shorter than .9Msec bad data , go to idle190.{191.IRstate=IR_idle;192.break;193.}194.if (time>msec_1p68)// greater than 1.68Msec is a 1 195.{196._IRdata|= bits;197.}198.bits=bits<<1;199.if (!bits) // we have it all , now we make sure it i s a NEC code from the CHS IR transmitter200.{ // make sure address,~address are correc t , data ,~data are correct and address is 0.201.IR_ready=((IRaddr^_IRaddr)==0xff)&&((IRdata^_IRda ta)==0xff)&&(IRaddr==0);202.if(IR_ready)203.{204.IRstate=IR_idle;205.}206.}207.break;208.default:209.IRstate=IR_idle;210.break;211.}212.}213.214.void main(void) 215.{216.cpu_init();217.while(1)218.{219.if(IR_ready)220.{221.IR_ready=0;222.switch(IRdata) 223.{224.case 0x45: //1 225.//your code226.break;227.case 0x44: //3 228.//your code229.break;230.case 0x43: //4 231.//your code232.break;233.case 0x08: //prev 234.//your code235.break;236.case 0x5a: //next 237.//your code238.break;239.default:240.break;241.&n bsp; } 242.}243.}。
51单片机红外遥控程序
;遥控执行部份
IR_GOTO
;这里还要判断1AH和1BH两个系统码或用户码,用于识别不同的遥控
器
;MOV A,1AH
;CJNE A,#xxH,IR_ERROR ;用户码1不对则退出
;MOV A,1BH
单片机采用外部中断INTI管脚和红外接收头的信号线相连,中断方式为边沿触发方式。并用定时器0计算中断的间隔时间,来区分前导码、二进制的“1”、“0”码。并将8位操作码提取出来在数码管上显示。
// 解码值在Im[2]中,当IrOK=1时解码有效。
/* 51单片机红外遥控解码程序 */
//用遥控器对准红外接收头,按下遥控器按键,在数码管前两位上就会显示对应按键的编码
MOV R7,#202
DELAY882_A
NOP
NOP
DJNZ R7,DELAY882_A
RET
;=============================1000
DELAY1000 ;1.085x ((229x4)+5)=999.285
MOV R7,#229
DELAY1000_A
NOP
NOP
DJNZ R7,DELAY1000_A
上述“0”和“1”组成的
32位二进制码经
38kHz的载频进行二次调制以提高发
射效率,达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空
间发射,如图
3所示。
图
3遥控信号编码波形图
UPD6121G产生的遥控编码是连续的
32位二进制码组,其中前
16位为用
户识别码,能区别不同的电器设备,防止不同机种遥控码互相干扰。该芯片的用
红外遥控编码原理及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单片机之红外解码
上面的程序结合前面对遥控发射信息的介绍来读,理解起来应该
不是很困难,好好看看。
下面就是操作 LED 灯了。解码之后我们怎么来运用红外遥控呢,
这里我们可以用其中的操作码或操作反码来使用它。每个按键对应的
操作码都不同,这样我们就可以判断是否是那个按键发过来的操作
码。控制程序如下:(如果操作码是 0x01)
if((HW_DAT[2]==0x01)&&(HW_OK==1))
{ HW_OK = 0; led = 0;
//标志位清 0,按一下之执行一次所以清 0 //点灯
}
}
}
/*******************************************************************
菜鸟学习 51 单片机
while(1)世界
以脉宽为 1. 68ms、周期为 2. 24ms 的组合表示二进制的“1”。
这里我们做的是解码,所以我们看下面的两个图,就是一体化接收头 输出的码。‘1’和‘0’时的低电平时间相同,所以这里我们主要还 是判断高电平来解析现在到底是 1 还是 0。如果高电平时间是 1.685ms 则是‘1’如果高电平时间为 0.56ms 则是‘0’.
上面提到过,前导码可以滤掉不用管,那么我们解码就可以得到 后面的:8 位的用户码,8 位的用户码反码,8 位操作码,8 位的操作 码反码。
菜鸟学习 51 单片机
while(1)世界
上图就是我们用来接收红外遥控的万能接收头。将 OUT 脚接在外部 中断 0 的引脚上,也就是 P3.2 脚上就可以了。下面我们根据程序来 分析和学习。
解码的,一个是 LED 灯的控制引脚。我们这个实验就做,用用的是外部中断 0,下降沿触发中断。并且需要定时器 0
基于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单片机红外解码程序1、红外遥控系统通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片 来进行控制操作,如图1所示。
发射部分包括键盘矩阵、编码调制、LED 红外发送器; 接收部分包括光、电转换放大器、解调、解码电路。
瑚研f I 编码调制ILED 卜f 遥控发射器 *1光/电放大卜3解诵丽盛径函攵麝■"1 红外遥控系统框图另外,使用51单片机进行解码2、原理图卜面,我们将使用下面两种设发射:红外遥控器接收:0D38W 接收头nnY _______ " ___________ 〃 —■杭E 也用户疏码月户毓E叫叫〃叫「「据国3 Sin27mi®位置1放大5S 5ms^'6.5iH5红外接收头与单片机连接原理图IR 的data 脚与51的PD2(P3.2) 相连。
2、红外发射原理要对红外遥控器所发的信号进行解码,必须先理解这些信号。
a )波形首先来看看,当我们按下遥控器时,红外发射器是发送了一个什么样的信号波形, 如下图:位置o5” 至 76.5msluSini由上图所示,当一个键按下超过 22ms,振荡器使芯片激活,将发射一组108ms 的编码脉冲(由位置1所示)。
如果键按下超过108ms 仍未松开,接下来发射的 代码(连发代码由位置3所示)将仅由起始码(9ms )和结束码(2.5ms )组成。
下面把位置1的波形放大:由位置1的波形得知,这108ms 发射代码由一个起始码(9ms ), 一个结果码IX 心1堂 I&LCF1 111 心 UUCH DOLT DUlll EL 芯、「如卖 LCD n^R PLto 1^ LCD -nRDPLTl^ 心{RXDi]f Dl OXD)PD2〔INTO] 心(IXTI i PINPD! (OCIA)PD6(WR) PD7 (RD)51单片机从原理图看出, 1R cornelzz[〃(4.5ms ),低8位地址码(用户编码)(9ms~18ms),高8位地址码(用户编码)(9ms~18ms ),8位数据码(键值数据码)(9ms~18ms)和这8位数据的反码(键值数据码反码)(9ms~18ms)组成。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
EX0=0;
for(i=0;i<255;i++) //9ms内有高电平认为是干扰
{
if(P3&0x04) //255的值实际时间为800us
{
EX0=1;
return;
}
}
while(!(P3&0x04)); //等待9ms低电平过去
if(k>=8)
addr[i]=addr[i]|0x80; //高电平大于0.56ms,则为1
k=0;
}
}
P2=~(addr[2]); //P2的LED显示二进制键值
EX0=1;
}
while(1);
}
void io_init(void)
{
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
}
void int_init(void)
{
EX0=1;
EA=1;
}
void interrupt0()interrupt 0
{
uchar i=0,j=0,k=0,us=0;
#define uint unsigned int
#define uchar unsigned char
uchar led=0x00;
void io_init(void);
void int_init(void);
void main(void)
{
io_init();
int_init();
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
while(P3&0x04); //等待4.5ms高电平过去
while(!(P3&0x04)); //等待0.56ms低电平后面的高电平
while(P3&0x04) //计算这个高电平的时间
//作者:新思科电子 2011-06
//资源:P3.2=接收头输入,P2=8LED
//#######################################################################de"reg52.h"
//#################################################################################################
//文件:51单片机的红外遥控解码程序
//属性:使用外部中断0连接遥控头,接收红外遥控键值送P2口显示,12MHz外部晶振
{
for(us=0;us<=32;us++); //100us的延时语句
if((k++)>=30) //高电平时间过长退出程序
{
EX0=1;
return;
}
}
addr[i]=addr[i]>>1; //接收一位数据