c51单片机红外解码程序汇总版和c语言版.docx
《c51单片机红外解码程序汇总版和c语言版.docx》由会员分享,可在线阅读,更多相关《c51单片机红外解码程序汇总版和c语言版.docx(18页珍藏版)》请在冰豆网上搜索。
![c51单片机红外解码程序汇总版和c语言版.docx](https://file1.bdocx.com/fileroot1/2022-11/24/f64c4941-8153-4bca-8ad7-101b5dd33ec1/f64c4941-8153-4bca-8ad7-101b5dd33ec11.gif)
c51单片机红外解码程序汇总版和c语言版
纯软件解码---汇编版
利用程序判电平和时间进行解码,缺点是浪费系统软件资源;优点是对系统硬件要求稍低
ORG0000H
T0ZDBIT20H.2
XHBITP3.3;红外接收头数据接口
RSBITP2.3
RWBITP2.4
EBITP2.5
BBBITP3.6
ORG0000H;
AJMPMAIN
ORG000BH;T0中断入口
LJMPT0ZDCX
ORG0100H;主程序首地址
MAIN:
LCALLCSH
MOVDPTR,#TAB;总查表
SETBEA;T0中断设定
SETBET0
MOVTMOD,#01H
DDXH:
;信号接收前准备
SETBP2.0;关信号指示灯
MOVP0,#0FFH
CLRTR0;关T0中断
CLRT0ZD;接收信号时间判断
MOVR5,#4;延时计数
MOVTH0,#00H
MOVTL0,#00H
;================解码主要过程===========关键============================================================
JBXH,$;等待电平变低,解码从这开始
CLRP2.0;开信号指示灯,表示正在接收信号
MOVP0,#8EH
SETBTR0;开T0中断
LCALLYS3MS
JBXH,DDXH;干扰检测
LCALLYS3MS
JBXH,DDXH;干扰检测
DD1:
JBT0ZD,DDXH;是否超出接收允许时间
JNBXH,DD1;等待电平变高
LCALLYS3MS
JNBXH,DDXH;干扰检测
DD2:
JBT0ZD,DDXH;是否超出接收允许时间
JBXH,DD2;等待电平变低
JSSJ:
;信号确认,开始接收数据
MOVR0,#30H
ZJ:
;接收一个字节数据
MOVR2,#8
WEI:
;位数据,分辩0和1
JBT0ZD,DDXH;是否超出接收允许时间
JNBXH,WEI;等待电平变高
LCALLYS845
MOVC,XH;取位数据
RRCA
DD3:
JBT0ZD,DDXH;是否超出接收允许时间
JBXH,DD3;等待电平变低,为1的高电平提供过度
DJNZR2,WEI;8位数据是否接收完
MOV@R0,A
INCR0
CJNER0,#34H,ZJ;四字节数据是否接收完
MOVA,33H
CPLA
CJNEA,32H,DDXH;键值确认,解码
MOVR4,A
;==========这里已经取出键值,存在R4中==================================================
MOVR7,#100;
TSY:
MOVR6,#255
DJNZR6,$
CPLBB
DJNZR7,TSY
MOVA,#0CDH;键值高位输出
LCALLYJP_XZL
MOVA,R4
MOVB,#10H
DIVAB
MOVCA,@A+DPTR
LCALLYJP_XSJ
MOVA,#0CEH;键值低位输出
LCALLYJP_XZL
MOVA,B
MOVCA,@A+DPTR
LCALLYJP_XSJ;
LCALLDYBF;调用灯控制子程序
LJMPDDXH;返还等待下一次信号
YS845:
;延时845微秒
MOVR7,#255
DJNZR7,$
MOVR7,#165
DJNZR7,$
RET
YS3MS:
;延时3ms
MOVR7,#8
DDD:
MOVR6,#255
DJNZR6,$
DJNZR7,DDD
RET
T0ZDCX:
;T0中断程序
MOVTL0,#00H
MOVTH0,#00H
DJNZR5,T0FH
SETBT0ZD
T0FH:
RETI
;===============以下是多余部分===========================================================================
DYBF:
MOVA,#0C0H;用号码前高位输出
LCALLYJP_XZL
MOVA,30H
MOVB,#10H
DIVAB
MOVCA,@A+DPTR
LCALLYJP_XSJ
MOVA,#0C1H;用户码前低位输出
LCALLYJP_XZL
MOVA,B
MOVCA,@A+DPTR
LCALLYJP_XSJ
MOVA,#0C4H;用户码后高位输出
LCALLYJP_XZL
MOVA,31H
MOVB,#10H
DIVAB
MOVCA,@A+DPTR
LCALLYJP_XSJ
MOVA,#0C5H;用户码后低位输出
LCALLYJP_XZL
MOVA,B
MOVCA,@A+DPTR
LCALLYJP_XSJ
;============此处专门针对我的开发板和遥控,不是解码的关键,只是一种应用举例
MOVA,R4
CJNEA,#0CH,BA1;是否1号键按下
CPLP1.0;点亮1号灯
BA1:
CJNEA,#18H,BA2;是否2号键按下
CPLP1.1;点亮1号灯
BA2:
CJNEA,#5EH,BA3;是否3号键按下
CPLP1.2;点亮1号灯
BA3:
CJNEA,#08H,BA4;是否4号键按下
CPLP1.3;点亮1号灯
BA4:
CJNEA,#1CH,BA5;是否5号键按下
CPLP1.4;点亮1号灯
BA5:
CJNEA,#5AH,BA6;是否6号键按下
CPLP1.5;点亮1号灯
BA6:
CJNEA,#42H,BA7;是否7号键按下
CPLP1.6;点亮1号灯
BA7:
CJNEA,#52H,BAB;是否8号键按下
CPLP1.7;点亮1号灯
BAB:
RET
CSH:
;=============液晶初始化===============
MOVA,#00111000B;8位数据,双行显示,5-7字型
LCALLYJP_XZL;调用写液晶指令
MOVA,#00001100B;显示屏开启,光标出现在地址计数器位置,光标不闪烁
LCALLYJP_XZL;调用写液晶指令
MOVA,#00000110B;光标右移一格,AC值加一,字符全部不动
LCALLYJP_XZL;调用写液晶指令
MOVA,#81H;
LCALLYJP_XZL
MOVA,#4CH;L的ASCII码
LCALLYJP_XSJ
MOVA,#83H;
LCALLYJP_XZL
MOVA,#47H;G的ASCII码
LCALLYJP_XSJ
MOVA,#85H;
LCALLYJP_XZL
MOVA,#58H;X的ASCII码
LCALLYJP_XSJ
MOVA,#88H;
LCALLYJP_XZL
MOVA,#5AH;Z的ASCII码
LCALLYJP_XSJ
MOVA,#89H;
LCALLYJP_XZL
MOVA,#68H;h的ASCII码
LCALLYJP_XSJ
MOVA,#8AH;
LCALLYJP_XZL
MOVA,#69H;i的ASCII码
LCALLYJP_XSJ
MOVA,#8CH;
LCALLYJP_XZL
MOVA,#5AH;Z的ASCII码
LCALLYJP_XSJ
MOVA,#8DH;
LCALLYJP_XZL
MOVA,#61H;a的ASCII码
LCALLYJP_XSJ
MOVA,#8EH;
LCALLYJP_XZL
MOVA,#6FH;o的ASCII码
LCALLYJP_XSJ
MOVA,#0C2H;
LCALLYJP_XZL
MOVA,#48H;H的ASCII码
LCALLYJP_XSJ
MOVA,#0C6H;
LCALLYJP_XZL
MOVA,#48H;H的ASCII码
LCALLYJP_XSJ
MOVA,#0CAH;
LCALLYJP_XZL
MOVA,#4AH;J的ASCII码
LCALLYJP_XSJ
MOVA,#0CBH;
LCALLYJP_XZL
MOVA,#5AH;Z的ASCII码
LCALLYJP_XSJ
MOVA,#0CCH;
LCALLYJP_XZL
MOVA,#3AH;:
的ASCII码
LCALLYJP_XSJ
MOVA,#0CFH;
LCALLYJP_XZL
MOVA,#48H;H的ASCII码
LCALLYJP_XSJ
RET
;=========写指令到液晶=============
YJP_XZL:
LCALLCHECK_BUSY;查询忙碌状态
CLRE
CLRRS
CLRRW
SETBE
MOVP0,A;写指令
CLRE
RET
;==========写数据到液晶==============
YJP_XSJ:
LCALLCHECK_BUSY;查询忙碌状态
CLRE
SETBRS
CLRRW
SETBE
MOVP0,A;写数据
CLRE
RET
;=========查询忙碌标志============
CHECK_BUSY:
PUSHACC
BUSY_LOOP:
CLRE
SETBRW
CLRRS
SETBE
MOVA,P0;读取状态
JBp0.7,BUSY_LOOP
POPACC
LCALLDEL
RET
DEL:
MOVR6,#5
L1:
MOVR7,#248
DJNZR7,$
DJNZR6,L1
RET
TAB:
DB30H,31H,32H,33H,34H,35H,36H,37H,38H,39H
DB41H,42H,43H,44H,45H,46H
END
中断加定时器---C语言版
优点:
完全是状态解码,极少的占用系统软件资源(CPU),随时都可以解码,而不管系统此时运行到何处。
缺点:
占用系统两个硬件资源,一个外部中断和一个定时器。
/******************************************************
********六哥红外解码程序********************************
********************************************************/
#include"STC15Fxxxx.H"
///**************************************************
/////用户配置区:
#definexi_tong_pl晶振频率设定如你的系统晶振频率是12MHz,则写
#definejan_zhiP1///解码输出二进制端口,解码成功则从该端口输出键值的二进制
sbitzhi_s=P5^5;///解码成功标志,解码成功一次该端口取反一次
////外部中断
#definezd_rkdzinterrupt0///中断入口设置
#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;//定时器中断打开
stc_dsqsz
TMOD&=0xF0;//设置定时器模式
TMOD|=0x01;//设置定时器模式
while
(1)
{if(hwjmok)
{hwjmok=0;
jan_zhi=hwjz;
zhi_s=~zhi_s;
}
}
}
/*------------------------------------------------
定时器0中断子程序
------------------------------------------------*/
voidT0ZDCX(void)interrupt1using3
{
yxjm=0;//未收到重复码清除解码允许标志
hwjz=0;
TR0=0;//关闭定时器
}
/*********************************************************
中断方式红外接收程序
***********************************************************/
voidZDhwjsCX(void)zd_rkdzusing3
{
unsignedinta=TH0*256+TL0;
TL0=0;
TH0=0;
TR0=1;///开启T0
if(a>shi_jian_*13000&&a{
hwsj=0;
hwjmws=32;
yxjm=1;
}
elseif(yxjm)///if1分支1.已收到引导码,允许解码
{
if(a>shi_jian_*11000&&a判重复码11-12ms
{
hwjmok=1;
}
else///if2分支3。
否则解码,取位
{
hwjmws--;
////////////////////////////////////////////////////////
if(a>shi_jian_*2000&&a{
hwsj>>=1;
hwsj|=0x80;
}
elseif(a>shi_jian_*1000&&a{
hwsj>>=1;
}
else
{
hwjmws=32;
yxjm=0;//清除允许解码标志
TR0=0;//关闭T0
}
//////////////////////////////////////////////////////////
}
switch(hwjmws)
{case24:
{
hwyhmh=hwsj;
hwsj=0;
}
break;
case16:
{hwyhml=hwsj;
hwsj=0;}
break;
case8:
{hwjz=hwsj;
hwsj=0;}
break;
case0:
{if(hwjz==~hwsj)
{hwjmok=1;
TL0=shi_jian_*12000%256;
TH0=shi_jian_*12000/256;
}
}
break;
default:
;}
}
else;
}
中断加定时器---汇编版
;******************************************************
;********六哥红外解码程序********************************
;********************************************************/
;******************************************************************
;*****本程序使用外部中断加定时器来实现红外解码,占用系统软件资********
;*****源极少,硬件方面占用了一个外部中断,定时器中断还可以进行********
;*****一些简单的运用,软件部分可以做很多的动作,就看你发挥了!
********
;******************************************************************/
hwyhmhdata7fh
hwyhmldata7eh
hwjzdata7dh
hwsjdata7ch
DSQ_ZDCSdata7bh
ZDCSDATA7AH
hwjmokbit20h.0
yxjmbit20h.1
hwjmweibit20h.2
hwjmkgBIT20H.3
HWJSTBITP3.3
ORG0000H
AJMPMAIN
ORG0013H
LJMPWBZD1
ORG000BH
LJMPDSQ_0
ORG0050H
MAIN:
SETBEA
SETBIT1
SETBEX1
SETBET0
MOVTMOD,#01H
CLRhwjmkg
CLRyxjm
CLRhwjmok
HHHH:
JBhwjmok,jm_cg;JBC:
为1跳转并把该位清零,为0则顺序执行
;此部分可写其他程序,不会影响接收
LJMPHHHH
jm_cg:
;这里写解码成功后的动作
CLRhwjmok
MOVP1,hwjz
LJMPHHHH
;==============================================
WBZD1:
INCZDCS
MOVA,ZDCS
JNByxjm,ZD0_5;
CLRTR0
MOVTH0,#0FAH;设置定时1400us
MOVTL0,#70H;
SETBTR0;开定时器
XCHA,hwsj
MOVC,hwjmwei
CLRhwjmwei
RRCA
XCHA,hwsj
CJNEA,#10,ZD0_0;取出用户码高位
MOVhwyhmh,hwsj
AJMPZD0_4
ZD0_0:
CJNEA,#18,ZD0_1;取出用户码低位
MOVhwyhml,hwsj
AJMPZD0_4
ZD0_1:
CJNEA,#26,ZD0_2;取出键值
MOVhwjz,hwsj
AJMPZD0_4
ZD0_2:
CJNEA,#34,ZD0_4;取出键值反码
MOVA,hwsj
CPLA
CJNEA,hwjz,ZD0_3;键值判断
SETBhwjmok;解码正确,置位标志位
ZD0_3:
;解码不成功
CLRTR0;关闭定时器
CLRhwjmkg;关闭解码开关
CLRyxjm;清除允许解码标志
MOVZDCS,#0;中断次数清零
MOVDSQ_ZDCS,#0;定时器中断次数清零
ZD0_4:
RETI;中断返回
ZD0_5:
;开始接收引导码
CJNEA,#1,ZD0_3;
MOVTH0,#0F2H;设置定时3.5ms
MOVTL0,#54H;
SETBTR0;开定时器
SETBhwjmkg;开红外解码开关
AJMPZD0_4
DSQ_0:
JNBhwjmkg,T0FH;
JNByxjm,DSQ_0_0;
SETBhwjmwei
CLRTR0
T0FH:
RETI
;==========引导码判断程序===============
DSQ_0_0:
MOVTH0,#0F2H;设置定时3.5ms
MOVTL0,#54H;
INCDSQ_ZDCS;对T0中断计数
MOVA,DSQ_ZDCS
CJNEA,#1,DSQ_0_1
JBHWJST,JMCW;判低电平,9ms引导码
AJMPT0FH
DSQ_0_1:
CJNEA,#2,DSQ_0_2
JBHWJST,JMCW;判低电平,9ms引导码
AJMPT0FH
DSQ_0_2:
JNBHWJST,JMCW;判高电平,4.5ms引导码
SETByxjm;引导码接收成功,允许解码
CLRhwjmwei;
CLRTR0
AJMPT0FH
JMCW:
;引导码接收错误,
CLRTR0;关闭定时器
CLRhwjmkg;关闭解码开关
CLRyxjm;清除允许解码标志
MOVZDCS,#0;中断次数清零
MOVDSQ_ZDCS,#0;定时器中断次数清零
AJMPT0FH
END
定时器捕获中断法---c语言版