找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5680|回复: 2
收起左侧

51单片机红外解码-C语言和汇编

[复制链接]
ID:70941 发表于 2015-3-21 05:02 | 显示全部楼层 |阅读模式
             中断加定时器---C语言版
              优点:极少的占用系统软件资源(CPU),随时都可以解码,而不管系统此时运行到何处。
      缺点:占用系统两个硬件资源,一个外部中断和一个定时器。
/******************************************************
********六哥红外解码程序********************************
********************************************************/


#include"STC15Fxxxx.H"
///**************************************************
/////用户配置区:
#define  xi_tong_pl   12000000  ///晶振频率设定  如你的系统晶振频率是12MHz,则写12000000   
#define  jan_zhi      P1        ///解码输出二进制端口,解码成功则从该端口输出键值的二进制
sbit     zhi_s    =   P5^5;     ///解码成功标志,解码成功一次该端口取反一次
////外部中断
#define  zd_rkdz      interrupt 0   ///中断入口设置
#define  zd_cffs      IT0           ///中断触发方式设置
#define  zd_dk        EX0           ///中断打开设置
////
#define  stc_dsqsz    AUXR &= 0x7F;//定时器时钟12T模式,不需要可在AUXR....前加//
///**************************************************



/******************************************************************
*****本程序使用外部中断加定时器来实现红外解码,占用系统软件资********
*****源极少,硬件方面占用了一个外部中断,定时器中断还可以进行********
*****一些简单的运用,软件部分可以做很多的动作,就看你发挥了!********
******************************************************************/




#define shi_jian_   (xi_tong_pl/12000000)///定时器设置,请勿更改
unsigned char hwyhmh,hwyhml,hwjz,hwsj,hwjmws;///全局变量
bit   hwjmok,yxjm;///全局变量,红外解码OK,允许解码
void main(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中断子程序
------------------------------------------------*/
void T0ZDCX(void) interrupt 1 using 3
{
yxjm=0;                //未收到重复码清除解码允许标志
hwjz=0;
TR0=0;                 //关闭定时器
}

/*********************************************************
            中断方式红外接收程序
***********************************************************/
void ZDhwjsCX(void) zd_rkdz using 3
{
unsigned int a=TH0*256+TL0;

TL0=0;
TH0=0;
TR0=1;            ///开启T0

if(a>shi_jian_*13000&&a<shi_jian_*14000)///if1分支2.判引导码13-14ms
   {
    hwsj=0;
    hwjmws=32;
    yxjm=1;
    }

else if(yxjm)          ///if1分支1.已收到引导码,允许解码
   {

    if(a>shi_jian_*11000&&a<shi_jian_*12000&&hwjmws==0)///if2分支1。判重复码11-12ms
      {
       hwjmok=1;
       }


    else               ///if2分支3。否则解码,取位
      {
       hwjmws--;

////////////////////////////////////////////////////////
       if (a>shi_jian_*2000&&a<shi_jian_*2400)///        判1   2-2.4ms
         {
          hwsj>>=1;
          hwsj|=0x80;      
          }


       else if (a>shi_jian_*1000&&a<shi_jian_*1300)///   判0  1-1.3ms
          {
           hwsj>>=1;
           }
       else               
          {
           hwjmws=32;
           yxjm=0;           //清除允许解码标志
           TR0=0;            //关闭T0
           }
//////////////////////////////////////////////////////////
       }

       switch(hwjmws)
          {case 24:{
                    hwyhmh=hwsj;
                    hwsj=0;
                    }
                    break;

           case 16:{hwyhml=hwsj;
                    hwsj=0;}
                    break;

           case  8:{hwjz=hwsj;
                    hwsj=0;}
                    break;

           case  0:{if(hwjz==~hwsj)
                       {hwjmok=1;
                        TL0=shi_jian_*12000%256;
                        TH0=shi_jian_*12000/256;
                        }
                    }
                    break;

           default:;}      

    }
else;
}


中断加定时器---汇编版;******************************************************
;********六哥红外解码程序********************************
;********************************************************/

;******************************************************************
;*****本程序使用外部中断加定时器来实现红外解码,占用系统软件资********
;*****源极少,硬件方面占用了一个外部中断,定时器中断还可以进行********
;*****一些简单的运用,软件部分可以做很多的动作,就看你发挥了!********
;******************************************************************/

hwyhmh   data   7fh
hwyhml   data   7eh
hwjz     data   7dh
hwsj     data   7ch
DSQ_ZDCS data   7bh
ZDCS     DATA   7AH

hwjmok   bit    20h.0
yxjm     bit    20h.1
hwjmwei  bit    20h.2
hwjmkg   BIT    20H.3
HWJST    BIT    P3.3

ORG 0000H
AJMP  MAIN
ORG 0013H
LJMP  WBZD1
ORG 000BH
LJMP  DSQ_0
ORG 0050H
MAIN:
SETB  EA
SETB  IT1
SETB  EX1
SETB  ET0
MOV   TMOD,#01H
CLR   hwjmkg
CLR   yxjm
CLR   hwjmok
HHHH:
JB    hwjmok,jm_cg  ;JBC:为1跳转并把该位清零,为0则顺序执行
                     ;此部分可写其他程序,不会影响接收
LJMP  HHHH
jm_cg:               ;这里写解码成功后的动作
CLR   hwjmok
MOV   P1,hwjz
LJMP  HHHH
;==============================================
WBZD1:
INC   ZDCS
MOV   A,ZDCS
JNB   yxjm,ZD0_5    ;
CLR   TR0
MOV   TH0,#0FAH     ;设置定时1400us
MOV   TL0,#70H      ;
SETB  TR0           ;开定时器
XCH   A,hwsj
MOV   C,hwjmwei
CLR   hwjmwei
RRC   A
XCH   A,hwsj
CJNE  A,#10,ZD0_0   ;取出用户码高位
MOV   hwyhmh,hwsj
AJMP  ZD0_4
ZD0_0:
CJNE  A,#18,ZD0_1   ;取出用户码低位
MOV   hwyhml,hwsj
AJMP  ZD0_4
ZD0_1:
CJNE  A,#26,ZD0_2   ;取出键值
MOV   hwjz,hwsj
AJMP  ZD0_4
ZD0_2:
CJNE  A,#34,ZD0_4   ;取出键值反码
MOV   A,hwsj
CPL   A   
CJNE  A,hwjz,ZD0_3  ;键值判断
SETB  hwjmok        ;解码正确,置位标志位
ZD0_3:              ;解码不成功
CLR   TR0           ;关闭定时器
CLR   hwjmkg        ;关闭解码开关
CLR   yxjm          ;清除允许解码标志
MOV   ZDCS,#0       ;中断次数清零
MOV   DSQ_ZDCS,#0   ;定时器中断次数清零
ZD0_4:
RETI                ;中断返回
ZD0_5:              ;开始接收引导码
CJNE  A,#1,ZD0_3    ;
MOV   TH0,#0F2H     ;设置定时3.5ms
MOV   TL0,#54H      ;
SETB  TR0           ;开定时器
SETB  hwjmkg        ;开红外解码开关
AJMP  ZD0_4
DSQ_0:
JNB   hwjmkg,T0FH   ;
JNB   yxjm,DSQ_0_0  ;
SETB  hwjmwei
CLR   TR0
T0FH:
RETI
;==========引导码判断程序===============
DSQ_0_0:
MOV   TH0,#0F2H     ;设置定时3.5ms
MOV   TL0,#54H      ;
INC   DSQ_ZDCS      ;对T0中断计数
MOV   A,DSQ_ZDCS
CJNE  A,#1,DSQ_0_1
JB    HWJST,JMCW    ;判低电平,9ms引导码   
AJMP  T0FH
DSQ_0_1:
CJNE  A,#2,DSQ_0_2
JB    HWJST,JMCW    ;判低电平,9ms引导码      
AJMP  T0FH
DSQ_0_2:
JNB   HWJST,JMCW    ;判高电平,4.5ms引导码
SETB  yxjm          ;引导码接收成功,允许解码
CLR   hwjmwei       ;
CLR   TR0      
AJMP  T0FH
JMCW:               ;引导码接收错误,
CLR   TR0           ;关闭定时器
CLR   hwjmkg        ;关闭解码开关
CLR   yxjm          ;清除允许解码标志
MOV   ZDCS,#0       ;中断次数清零
MOV   DSQ_ZDCS,#0   ;定时器中断次数清零
AJMP  T0FH
END

纯软件解码 --- 汇编版
利用程序判电平和时间进行解码,缺点是浪费系统软件资源;优点是对系统硬件要求稍低
ORG   0000H
T0ZD    BIT   20H.2
XH      BIT   P3.3   ;红外接收头数据接口   
RS      BIT   P2.3
RW      BIT   P2.4
E       BIT   P2.5
BB      BIT   P3.6
ORG   0000H          ;
AJMP  MAIN
ORG   000BH           ;T0中断入口
LJMP  T0ZDCX
ORG   0100H           ;主程序首地址
MAIN:
LCALL   CSH
MOV   DPTR,#TAB       ;总查表
SETB  EA              ;T0中断设定
SETB  ET0
MOV   TMOD,#01H
DDXH:                   ;信号接收前准备
SETB    P2.0            ;关信号指示灯
MOV     P0,#0FFH
CLR     TR0             ;关T0中断
CLR     T0ZD           ;接收信号时间判断
MOV     R5,#4           ;延时计数
MOV     TH0,#00H
MOV     TL0,#00H
;================解码主要过程===========关键============================================================
JB      XH,$            ;等待电平变低,解码从这开始
CLR     P2.0            ;开信号指示灯,表示正在接收信号
MOV     P0,#8EH         
SETB    TR0             ;开T0中断
LCALL   YS3MS
JB      XH,DDXH         ;干扰检测
LCALL   YS3MS
JB      XH,DDXH         ;干扰检测
DD1:
JB      T0ZD,DDXH      ;是否超出接收允许时间
JNB     XH,DD1          ;等待电平变高
LCALL   YS3MS
JNB     XH,DDXH         ;干扰检测  
DD2:
JB      T0ZD,DDXH      ;是否超出接收允许时间
JB      XH,DD2          ;等待电平变低
JSSJ:                   ;信号确认,开始接收数据
MOV     R0,#30H
ZJ:                     ;接收一个字节数据
MOV     R2,#8
WEI:                    ;位数据,分辩0和1
JB      T0ZD,DDXH      ;是否超出接收允许时间
JNB     XH,WEI          ;等待电平变高
LCALL   YS845
MOV     C,XH            ;取位数据
RRC     A
DD3:
JB      T0ZD,DDXH      ;是否超出接收允许时间
JB      XH,DD3          ;等待电平变低,为1的高电平提供过度
DJNZ    R2,WEI          ;8位数据是否接收完
MOV     @R0,A
INC     R0
CJNE    R0,#34H,ZJ      ;四字节数据是否接收完
MOV     A,33H
CPL     A
CJNE    A,32H,DDXH      ;键值确认,解码
MOV    R4,A            
;==========这里已经取出键值,存在R4中==================================================
    MOV   R7,#100;
TSY:MOV   R6,#255
    DJNZ  R6,$
    CPL   BB
    DJNZ  R7,TSY
MOV    A,#0CDH          ;键值高位输出
LCALL  YJP_XZL
MOV    A,R4
MOV    B,#10H
DIV    AB
MOVC   A,@A+DPTR
LCALL  YJP_XSJ
MOV    A,#0CEH          ;键值低位输出
LCALL  YJP_XZL
MOV    A,B
MOVC   A,@A+DPTR
LCALL  YJP_XSJ          ;
LCALL  DYBF             ;调用灯控制子程序
LJMP   DDXH             ;返还等待下一次信号   
YS845:                  ;延时845微秒
MOV   R7,#255
DJNZ  R7,$
MOV   R7,#165
DJNZ  R7,$
RET
YS3MS:                  ;延时3ms
MOV   R7,#8
DDD:
MOV   R6,#255
DJNZ  R6,$
DJNZ  R7,DDD
RET
T0ZDCX:                   ;T0中断程序
MOV     TL0,#00H
MOV     TH0,#00H
DJNZ   R5,T0FH
SETB   T0ZD
T0FH:
RETI
;===============以下是多余部分===========================================================================
DYBF:
MOV    A,#0C0H          ;用号码前高位输出
LCALL  YJP_XZL
MOV    A,30H
MOV    B,#10H
DIV    AB
MOVC   A,@A+DPTR
LCALL  YJP_XSJ
MOV    A,#0C1H          ;用户码前低位输出
LCALL  YJP_XZL
MOV    A,B
MOVC   A,@A+DPTR
LCALL  YJP_XSJ         
MOV    A,#0C4H          ;用户码后高位输出
LCALL  YJP_XZL
MOV    A,31H
MOV    B,#10H
DIV    AB
MOVC   A,@A+DPTR
LCALL  YJP_XSJ
MOV    A,#0C5H          ;用户码后低位输出
LCALL  YJP_XZL
MOV    A,B
MOVC   A,@A+DPTR
LCALL  YJP_XSJ
;============此处专门针对我的开发板和遥控,不是解码的关键,只是一种应用举例
MOV     A,R4
CJNE    A,#0CH,BA1      ;是否1号键按下
CPL     P1.0            ;点亮1号灯
BA1:
CJNE    A,#18H,BA2      ;是否2号键按下
CPL     P1.1            ;点亮1号灯
BA2:
CJNE    A,#5EH,BA3      ;是否3号键按下
CPL     P1.2            ;点亮1号灯
BA3:
CJNE    A,#08H,BA4      ;是否4号键按下
CPL     P1.3            ;点亮1号灯
BA4:
CJNE    A,#1CH,BA5      ;是否5号键按下
CPL     P1.4            ;点亮1号灯
BA5:
CJNE    A,#5AH,BA6      ;是否6号键按下
CPL     P1.5            ;点亮1号灯
BA6:
CJNE    A,#42H,BA7      ;是否7号键按下
CPL     P1.6            ;点亮1号灯
BA7:
CJNE    A,#52H,BAB      ;是否8号键按下
CPL     P1.7            ;点亮1号灯
BAB:RET
CSH:
;=============液晶初始化===============
MOV  A, #00111000B    ;8位数据,双行显示,5-7字型
LCALL  YJP_XZL        ;调用写液晶指令
MOV  A, #00001100B    ;显示屏开启,光标出现在地址计数器位置,光标不闪烁
LCALL  YJP_XZL        ;调用写液晶指令
MOV  A, #00000110B    ;光标右移一格,AC值加一,字符全部不动
LCALL  YJP_XZL        ;调用写液晶指令
MOV  A,#81H     ;
LCALL YJP_XZL
MOV  A, #4CH          ;L的ASCII码
LCALL YJP_XSJ
MOV  A,#83H     ;
LCALL YJP_XZL
MOV  A, #47H          ;G的ASCII码
LCALL YJP_XSJ
MOV  A,#85H     ;
LCALL YJP_XZL
MOV  A, #58H          ;X的ASCII码
LCALL YJP_XSJ
MOV  A,#88H           ;
LCALL YJP_XZL
MOV  A, #5AH          ;Z的ASCII码
LCALL YJP_XSJ
MOV  A,#89H           ;
LCALL YJP_XZL
MOV  A, #68H          ;h的ASCII码
LCALL YJP_XSJ
MOV  A,#8AH     ;
LCALL YJP_XZL
MOV  A, #69H          ;i的ASCII码
LCALL YJP_XSJ
MOV  A,#8CH           ;
LCALL YJP_XZL
MOV  A, #5AH          ;Z的ASCII码
LCALL YJP_XSJ
MOV  A,#8DH           ;
LCALL YJP_XZL
MOV  A, #61H          ;a的ASCII码
LCALL YJP_XSJ
MOV  A,#8EH     ;
LCALL YJP_XZL
MOV  A, #6FH          ;o的ASCII码
LCALL YJP_XSJ
MOV  A,#0C2H          ;
LCALL YJP_XZL
MOV  A, #48H          ;H的ASCII码
LCALL YJP_XSJ
MOV  A,#0C6H          ;
LCALL YJP_XZL
MOV  A, #48H          ;H的ASCII码
LCALL YJP_XSJ
MOV  A,#0CAH          ;
LCALL YJP_XZL
MOV  A, #4AH          ;J的ASCII码
LCALL YJP_XSJ
MOV  A,#0CBH          ;
LCALL YJP_XZL
MOV  A, #5AH          ;Z的ASCII码
LCALL YJP_XSJ
MOV  A,#0CCH          ;
LCALL YJP_XZL
MOV  A, #3AH          ;:的ASCII码
LCALL YJP_XSJ
MOV  A,#0CFH          ;
LCALL YJP_XZL
MOV  A, #48H          ;H的ASCII码
LCALL YJP_XSJ
RET
;=========写指令到液晶=============
YJP_XZL:
LCALL  CHECK_BUSY;查询忙碌状态
CLR    E
CLR    RS
CLR    RW
SETB   E
MOV    P0,A;写指令
CLR    E
RET
;==========写数据到液晶==============
YJP_XSJ:
LCALL  CHECK_BUSY;查询忙碌状态
CLR    E
SETB   RS
CLR    RW
SETB   E
MOV    P0,A;写数据
CLR    E
RET
;=========查询忙碌标志============
CHECK_BUSY:
PUSH   ACC
BUSY_LOOP:
CLR    E
SETB   RW
CLR    RS
SETB   E
MOV    A,P0;读取状态
JB     p0.7,BUSY_LOOP
POP    ACC
LCALL  DEL
RET
DEL: MOV R6,#5
L1:  MOV R7,#248
     DJNZ  R7,$
     DJNZ  R6,L1
     RET
TAB:DB  30H,31H,32H,33H,34H,35H,36H,37H,38H,39H
    DB  41H,42H,43H,44H,45H,46H
END  


定时器捕获中断法---c语言版


   



评分

参与人数 2黑币 +10 收起 理由
fanks001 + 5 很给力!
958842929qq + 5 赞一个!51还是很经典的。

查看全部评分

回复

使用道具 举报

ID:67366 发表于 2017-10-5 12:51 | 显示全部楼层
学习学习
回复

使用道具 举报

ID:237377 发表于 2017-10-5 17:57 | 显示全部楼层
学习学习。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表