原创 红外遥控;时钟显示(可调整时间);温度显示

2006-11-8 21:38 4891 6 7 分类: MCU/ 嵌入式


;**************************************************************
;             红外遥控;时钟显示(可调整时间);温度显示  
;**************************************************************
;*  Author:   Li Zheng hang <Sailing>
;*  Corp:     XXXXXXXXX
;*  Date  :   2006-07-16             
;*  Mobile:   13346446847
;*  Phone:    0760-xxxxxxxx
;*  QQ:       309593045
;*  E-mail:   47uf@sohu.com;56pf@163.com             
;***************************************************************
;*****         程序简介                                  
;***************************************************************
;1:程序作用:红外遥控键码测试;时钟显示(可调整时间);温度显示
;2:单片机:AT89C51,晶体的频率:11.0592MHz.编译器:Keil UVision V2.32
;3:硬件连接:数码管是共阴极,采用P1.P2端口,高电平驱动6个数码管
;4:在P0端口接了几个LED和BELL,用于显示程序运行的状态。
;5: 设定了三组内存单元为显示缓冲区;分别显示时间(时分秒),遥控代码和温度值
;   数码管初值为000000,以后按秒计时,可以用遥控器调整时间显示。
;6: 单片机接收后,遥控信号(NEC format)输出接在AT89C51的P3.2脚。
;   3AH、3BH、3CH、3DH是遥控接收代码的缓存区
;7: 本程序是采用动态扫描,P1是字形码,P20-P25是位控码


;8; 定义DS18B20输出端接在P3.3

;9: 程序作者:李正航,最后修改日期:7-Aug-2006


;;label------Opecode-Operand---------Note-----------------------
;****************************************************************
;****        符号定义        
;****************************************************************
                                     ;定义三个LED低电平亮
RED_LED      BIT P0.3                ;RED LED亮表示接收代码出错。
BLUE_LED     BIT P0.5                ;BULE LED亮表示正在等待接收状态
YELLOW_LED   BIT P0.1                ;YELLOW LED表示解码正常。
BLUE_LED2    BIT P0.2
GREEN_LED    BIT P0.0
BELL         BIT P2.6
;SPEAKER      BIT P0.1
IRIN         BIT P3.2
;RXD1         BIT P3.1
;TXD1         BIT P3.0
PW_OFF_R     BIT P3.6                ;RED LED__ POWER OFF
PW_ON_G      BIT P3.5                ;GREEN LED__POWER ON
PW_XX_B      BIT P3.4                ;BULE LED
TEMPER_L     EQU   36H                ;以下是定义几个变量
TEMPER_H     EQU   35H
TEMPER_NUM   EQU   50H
MARK1        EQU   33H
FLAG1        BIT   00H
DQ           BIT   P3.3              ;定义DS18B20输出端接在P3.3
;********************************************************
;****       中断入口程序     
;********************************************************
            ORG     0000H           ;程序执行开始地址
            AJMP    MAIN_0          ;跳到标号MAIN_0执行
            ORG     0003H           ;外中断0中断程序入口
            AJMP    INT_0
            RETI                    ;外中断0中断返回
            ORG     000BH           ;定时器T0中断程序入口
            AJMP    PITO            ;跳至INTTO执行;;;;;;;;;;;;
                                           ;;;;;;;;;;;;
            ORG     0013H           ;外中断1中断程序入口
            RETI                    ;外中断1中断返回
            ORG     001BH           ;定时器T1中断程序入口
            AJMP    T1_TEMP         ;跳至T1_TEMP执行
     ;RETI
            ORG     0023H           ;串行中断程序入口地址
            RETI                    ;串行中断程序返回
;********************************************************
;           主程序初始化
;********************************************************
            ORG      030H
   MAIN_0:  MOV      SP, #57H
            CLR      PW_ON_G
            MOV      3FH,#0AH
     SETB     P3.7
            MOV      R0,#70H
            MOV      R7,#0FH
    ML_1:   MOV      @R0,#00H
            INC      R0
            DJNZ     R7,ML_1         ;以上几行是对16个显示缓冲区清零
            MOV      TMOD,#11H       ;设置定时计数方式
            MOV      TL0,#01H
            MOV      TH0,#4CH        ;设置T0初始值50ms
     MOV      TL1,#00H
     MOV      TH1,#28H        ;设置T1初始值60ms
            SETB     TR0
            SETB     TR1             ;设置TR0,TR1=1,定时开始
     SETB     ET0
     SETB     ET1             ;设置ET0,ET1=1,打开定时中断
            SETB     EX0             ;设置EX1=1,打开外部中断0
     CLR      IT0             ;设置外部中断0的优先级为0(低优先,因为时钟更优先)
     ;SETB     PT1;  AAA     ;设定PT0(时钟定时中断)为1,优先权最高 
        SETB     PT0
     SETB     EA              ;设置总的中断开
     MOV      30H,#20         ;设置中断多少次是1秒!
     ;MOV      31H,#100
     ;MOV      32H,#2
            MOV      P1,#00H
            MOV      P2,#00H
    MAIN:   LCALL    IRDIR2           ;调用DIR显示程序   
            CLR      P0.0    
            AJMP     MAIN
   T1_TEMP: PUSH     PSW              ;定时中断的程序
            PUSH     ACC    
            SETB     PSW.4            ;选择第2组寄存器
            MOV      TL1,#00H
     MOV      TH1,#28H         ;计数器重新加载 
    
     DJNZ     31H,T1RET
    ;DJNZ     32H,T1RET
    ; MOV      A,31H
    ; DEC      A
     ;MOV      31H,A
     ;JNZ      T1RET
     ;MOV      31H,#200    
            ;SETB     PT1
     ;CLR      PT0
            LCALL    GET_TEMPER
            LCALL    TEMPER_COV
     ;RETI
     ;MOV      31H,#20
     ;SETB     PT0
     ;AJMP     MAIN
   T1RET:   POP      ACC
     POP      PSW
     SETB     P0.5
            RETI         
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;           读出转换后的温度值
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GET_TEMPER:
           SETB     DQ                  ;定时入口
    CLR      P0.5                ;点亮P0。5
    SETB     P0.0
  BCD:     LCALL    INIT_1820
           JB       FLAG1,S22
           LJMP     BCD                 ;若DS18B20不存在则返回
  S22:     LCALL    DELAY1
           MOV      A,#0CCH             ;跳过ROM匹配------0CC
           LCALL    WRITE_1820
           MOV      A,#44H              ;发出温度转换命令
           LCALL    WRITE_1820
           NOP
           LCALL    DELAY
           LCALL    DELAY
  CBA:     LCALL    INIT_1820
           JB       FLAG1,ABC
           LJMP     CBA
  ABC:     LCALL    DELAY1
           MOV      A,#0CCH             ;跳过ROM匹配
           LCALL    WRITE_1820
           MOV      A,#0BEH             ;发出读温度命令
           LCALL    WRITE_1820
           LCALL    READ_18200          ;READ_1820
           RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          读DS18B20的程序,从DS18B20中读出一个字节的数据
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
READ_1820:
           MOV      R2,#8
RE1:
           CLR      C
           SETB     DQ
           NOP
           NOP
           CLR      DQ
           NOP
           NOP
           NOP
           SETB     DQ
           MOV      R3,#7
           DJNZ     R3,$
           MOV      C,DQ
           MOV      R3,#23
           DJNZ     R3,$
           RRC      A
           DJNZ     R2,RE1
           RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          DS18B20初始化程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INIT_1820:
           SETB     DQ
           NOP
           CLR      DQ
           MOV      R0,#80H
 TSR1:
           DJNZ     R0,TSR1         ;延时
           SETB     DQ
           MOV      R0,#25H         ;96US-25H
 TSR2:
           DJNZ     R0,TSR2
           JNB      DQ,TSR3
           LJMP     TSR4            ;延时
 TSR3:
           SETB     FLAG1           ;置标志位,表示DS1820存在
           LJMP     TSR5
 TSR4:
           CLR      FLAG1           ;清标志位,表示DS1820不存在
           LJMP     TSR7
 TSR5:
           MOV      R0,#06BH        ;200US
 TSR6:
           DJNZ     R0,TSR6         ;延时
 TSR7:
           SETB     DQ
           RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          重新写DS18B20暂存存储器设定值
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RE_CONFIG:
           JB       FLAG1,RE_CONFIG1 ;若DS18B20存在,转RE_CONFIG1
           RET
RE_CONFIG1:
           MOV      A,#0CCH          ;发SKIP ROM命令
           LCALL    WRITE_1820
           MOV      A,#4EH           ;发写暂存存储器命令
           LCALL    WRITE_1820
           MOV      A,#00H           ;TH(报警上限)中写入00H
           LCALL    WRITE_1820
           MOV      A,#00H           ;TL(报警下限)中写入00H
           LCALL    WRITE_1820
           MOV      A,#7FH           ;选择12位温度分辨率
           LCALL    WRITE_1820
           RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          写DS18B20的程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WRITE_1820:
           MOV       R2,#8
           CLR       C
  WR_1:
           CLR       DQ
           MOV       R3,#6
           DJNZ      R3,$
           RRC       A
           MOV       DQ,C
           MOV       R3,#23
           DJNZ      R3,$
           SETB      DQ
           NOP
           DJNZ      R2,WR_1
           SETB      DQ
           RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;读DS18B20的程序,从DS18B20中读出两个字节的温度数据
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
READ_18200:
           MOV      R4,#2             ;将温度高位和低位从DS18B20中读出
           MOV      R1,#36H           ;低位存入36H(TEMPER_L),高位存入35H(TEMPER_H)
 RE_00:
           MOV      R2,#8
 RE_01:
           CLR      C
           SETB     DQ
           NOP
           NOP
           CLR      DQ
           NOP
           NOP
           NOP
           SETB     DQ
           MOV      R3,#7
           DJNZ     R3,$
           MOV      C,DQ
           MOV      R3,#23
           DJNZ     R3,$
           RRC      A
           DJNZ     R2,RE_01
           MOV      @R1,A
           DEC      R1
           DJNZ     R4,RE_00
           RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;        将从DS18B20中读出的温度数据进行转换
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TEMPER_COV:
          MOV       A,TEMPER_L            ;将TEMPER-L的低四位(即小数位)通过数据表格-TEMP_SMALL
          ANL       A,#0FH                ;转换成两位十进制数
   MOV       DPTR,#TEMP_SMALL      ;TEMP_SMALL是小数部份的数据表格
   MOVC      A,@A+DPTR             ;
   MOV       3DH,A                 ;3DH中将保留TEMPER_L的低四位数值 
        
TEMPER_COV1:
;;从这行起到下面的星号的那行是零度以上和零度以下温度的判别,正温度的BIT11--BIT15是零,也就是
;;TEMPER-H的高五位全是零。而负温度是相同正温度值的反码加1,例如+25.0625度=0000,0001,1001,0001
;;相应的十六进制是0191H,而负的-25.0625度=1111,1110,0110,1111B.十六进制是FE6FH.将-25.625取反
;;再加1就与正的温度值相同了。
           MOV       A,TEMPER_H          ;将TEMPER_H移到A中
    ANL       A,#0F0H             ;判断逻辑与后A中的值,如果A中为零。
    JZ        KKK_1               ;说明TEMPER_H的高位是零(即是正温度),程序将跳转到KKK_1
    MOV       MARK1,#1H           ;如果A中为非零,将先建一个标志,将MARK_1设置为1
    MOV       A,TEMPER_L          ;将TEMPER_L移到A中
    CPL       A                   ;先取反
    INC       A                   ;再加1
    MOV       TEMPER_L,A          ;回存到TEMPER_L中


    MOV       A,TEMPER_H          ;将TEMPER_H移到A中
    CPL       A                   ;取反
    MOV       TEMPER_H,A          ;回存到TEMPER_H中
;;*********************************************************************************
  KKK_1:   MOV      A,TEMPER_L            ;将TEMPER_L的高四位数据转存在R7中
           ANL      A,#0F0H               ;逻辑"与"转换
           SWAP     A                     ;
           MOV      R7,A                  ;R7中将保留TEMPER_L的高四位数值


           MOV      A,TEMPER_H            ;将TEMPER_H的低四位数据转存在R2中
           ANL      A,#0FH                ;逻辑"与"转换
           SWAP     A                     ;
           MOV      R2,A                  ;R2中将保留TEMPER_H的低四位数值


           ORL      A,R7                  ;TEMPER_NUM
           MOV      TEMPER_NUM,A          ;保存变换后的温度数据
           LCALL    BIN_BCD               ;


;-------------------将16进制的温度数据转换成压缩BCD码
BIN_BCD:
           MOV     DPTR,#TEMP_TAB      ;
           MOV     A,TEMPER_NUM        ;
           MOVC    A,@A+DPTR           ;
           MOV     3CH,A               ;TEMPER_NUM,A
           LCALL   BIJIAO_T            ;
           RET


BIJIAO_T:       
           MOV      A,3CH            ;数值判断执行,将3CH的八位数的                       
           ANL      A,#0FH           ;高4位和低4位分别转存在7AH和79H中
           MOV      72H,A
           MOV      A,3CH
           ANL      A,#0F0H
           SWAP     A
           MOV      73H,A
         
           MOV      A,3DH            ;数值判断执行,将3CH的八位数的                       
           ANL      A,#0FH           ;高4位和低4位分别转存在7AH和79H中
           MOV      70H,A            ;转存后79H,7AH,7BH,7CH,7EH,7FH的高4位都是0
           MOV      A,3DH
           ANL      A,#0F0H
           SWAP     A
           MOV      71H,A
         
    MOV      R2,#0FFH
    MOV      P1,#00H
    MOV      P2,#00H
    CALL     DELAY2400
           ACALL    DIR              ;执行显示功能,将码值显示在数码管上
          ;CALL     DELAYIR          ;延时,使数值能显示在数码管上一会儿


 DIR:     ;TEMP温度显示子程序
;****************************************************************
           MOV    P1,#00H;    #46H;A               ;DISPLAY + + + +=46H
    SETB    P2.0
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.0


           MOV    P1,#79H;A      ;78H, P2.5,数码管倒立的代码                          
           SETB    P2.5           ;DISPLAY 度数符号===79H
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.5


    MOV     DPTR ,#TABLE_2
    MOV     A,70H                  ;79H, P2.4
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.4
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.4


    MOV     A,71H                  ;7AH, P2.3
    MOVC    A,@A+DPTR
           MOV    P1,A   
    SETB    P2.3
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.3
   
    MOV     A,72H                  ;7BH, P2.2
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P1.7                   ;OPEN POINT
    SETB    P2.2
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.2


           MOV     A,73H                   ;7CH, P2.1
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.1
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.1
     
    DJNZ   R2,DIR                  ;7DH, P2.0 
    RET
;------------------延时子程序
 DELAY:    MOV     R7,#00H
   MIN:    DJNZ    R7,YS500
           RET
 YS500:    LCALL   YS500US
           LJMP    MIN
YS500US:   MOV     R6,#00H
           DJNZ    R6,$
           RET
DELAY1:    MOV     R7,#20H
           DJNZ    R7,$
           RET
;;====================================================================
TEMP_TAB:
           DB 00H,01H,02H,03H,04H,05H,06H,07H
           DB 08H,09H,10H,11H,12H,13H,14H,15H
           DB 16H,17H,18H,19H,20H,21H,22H,23H
           DB 24H,25H,26H,27H,28H,29H,30H,31H
           DB 32H,33H,34H,35H,36H,37H,38H,39H
           DB 40H,41H,42H,43H,44H,45H,46H,47H
           DB 48H,49H,50H,51H,52H,53H,54H,55H
           DB 56H,57H,58H,59H,60H,61H,62H,63H
           DB 64H,65H,66H,67H,68H,69H,70H,71H
           DB 72H,73H,74H,75H,76H,77H,78H,79H
           DB 80H,81H,82H,83H,84H,85H,86H,87H
           DB 88H,89H,90H,91H,92H,93H,94H,95H
           DB 96H,97H,98H,99H
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;TABLE:     DB  0FCH, 060H, 0DAH, 0F2H, 066H        ;01234串口共阴数码管
;           DB  0B6H, 0BEH, 0E0H, 0FEH, 0F6H        ;56789
;           DB  0EEH, 3EH,  9CH,  7AH,  9EH,8EH     ;AbCdEF
;           DB  2H,   00H,  0F1H                    ;负号/全灭/度数
;======================================================================
TEMP_SMALL: DB 00H,06H,13H,19H,25H,31H,38H,44H     ;小数部份的表格
            DB 50H,56H,63H,69H,75H,81H,88H,94H     ;
;======================================================================
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;;;;;;;;    串口共阴数码管;;;;;;带小数点;;;;;;;
                          ;;;;;;;;;;;;;;;;;;;;;
;TABLE_POINT: DB  0FDH, 061H, 0DBH, 0F3H, 067H      ;01234  串口共阴数码管
;             DB  0B7H, 0BFH, 0E1H, 0FFH, 0F7H      ;56789  带小数点
     ; DB  2H,   00H,  0F1H                  ;负号/全灭/度数
;***********************************************************************
;**************************************************************
;       PIT0:定时器T0中断程序
;**************************************************************
 PITO:    PUSH   PSW             ;定时中断的程序
          PUSH   ACC
          SETB   PSW.3           ;选择第1组寄存器
          MOV    TL0,#01H        ;计数器重新加载
          MOV    TH0,#4CH
          MOV    A,30H           ;设定循环次数并减1
          DEC    A
          MOV    30H,A
          JNZ    RET0            ;不到20次返回
          MOV    30H,#20         ;有20次了就开始计时


          MOV    R0,#79H         ;SSS: 将秒钟的显示地址移到R0中      
          ACALL  DAD1            ;执行秒加1程序
          MOV    A,R2            ;加1后秒值在R2中
          XRL    A,#60H          ;是否到60秒??
          JNZ    RET0            ;不到则返回
          ACALL  CLR0            ;到60则执行清0程序


          MOV    R0,#7BH         ;MMM:判断分钟的程序,与秒的相似
          ACALL  DAD1
          MOV    A,R2
          XRL    A,#60H
          JNZ    RET0
          ACALL  CLR0


          MOV    R0,#7DH         ;HHH: 判断小时的程序,与秒的相似
          ACALL  DAD1
          MOV    A,R2
          XRL    A,#24H
          JNZ    RET0
          ACALL  CLR0


 RET0:    POP    ACC             ;恢复现场和中断返回
          POP    PSW
          RETI
;***************************************************************
;**     加一程序
;**************************************************************
 DAD1:    MOV    A,@R0            ;加1子程序,秒或分或小时的十位数送到A中
          DEC    R0               ;
          SWAP   A                ;十位数占高4位
          ORL    A,@R0            ;个位数占低4位
          ADD    A,#01H           ;加1 
          DA     A                ;十进制调整
          MOV    R2,A             ;调整后的全值保存在R2中
          ANL    A,#0FH           ;取出个位数
          MOV    @R0,A            ;个位数送到显示缓冲单元
          MOV    A,R2             ;
          INC    R0               ;
          ANL    A,#0F0H          ;取出十位数
          SWAP   A                ;使十位数占低4位
          MOV    @R0,A            ;十位数送到显示缓冲单元
          RET                     ;返回
;==========================================
;        清零程序
;==========================================
 CLR0:    CLR    A                ;清缓冲单元子程序
          MOV    @R0,A            ;十位数缓冲单元清0
          DEC    R0               ;
          MOV    @R0,A            ;个位数缓冲单元清0
          RET                     ;返回
;==========================================================================
;      查询方式时要加下面两行!
;==========================================================================
;    M1:    JNB      P3.2,IR        ;遥控扫描
;           LJMP     M1             ;在正常无遥控信号时,一体化红外接收头
                                    ;输出是高电平,程序一直在循环。
;**************************************************************************
;**         遥控信号解码程序
;**************************************************************************
       ;以下对遥控信号的9000微秒的初始低电平信号的识别
;==========================================================================
  INT_0:                             ;外部中断的入口程序。
            PUSH     ACC             ;ACC、PSW入栈
     PUSH     PSW    
     CLR      EX0             ;响应外部遥控中断0后,要暂时将EX0关闭,
     IR:    MOV      R6,#10          ;因为遥控信号中也有低电平,可能也会产生中断。
  IR_SB:    ACALL    DELAY882        ;调用882微秒延时子程序
            JB       P3.2,IR_ERROR   ;延时882微秒后判断P2.2脚是否出现
                                     ;高电平,如果有就退出解码程序
            DJNZ     R6,IR_SB        ;重复10次,目的是检测在8820微秒内如果
                                     ;出现高电平就退出解码程序
                                     ;识别连发码,和跳过4.5MS的高电平。
            JNB      P3.2, $         ;等待高电平避开9毫秒低电平引导脉冲
            ACALL    DELAY2400
            JNB      P3.2,IR_ERROR   ;IR_GOTO;;这里为低电平,认为是连发码信号
            ACALL    DELAY2400       ;延时4.74毫秒避开4.5毫秒的结果码
;*************************************************************************
;           以下是32位数据码的读取,0和1的识别 请看图2
;=========================================================================
            MOV      R1,#3AH         ;设定3AH为起始RAM区
            MOV      R2,#4           ;共有四个数据。
 IR_4BYTE:  MOV      R3,#8           ;每位数据有8位。
  IR_8BIT:  JNB      P3.2,$          ;等待地址码第一位的高电平信号//////
            LCALL    DELAY882        ;高电平开始后用882微秒的时间
                                     ;判断信号此时的高低电平状态
            MOV      C,P3.2          ;将P3.2引脚此时的电平状态0或1存入C中
            JNC      IR_8BIT_0       ;如果为0就跳转到IR_8BIT_0
            LCALL    DELAY1000       ;////////////////////////////
IR_8BIT_0:  MOV      A,@R1           ;将R1中地址的给A
            RRC      A               ;将C中的值0或1移入A中的最低位
            MOV      @R1,A           ;将A中的数暂时存放在R1中
            DJNZ     R3,IR_8BIT      ;接收地址码的高8位
            INC      R1              ;对R1中的值加1,换下一个RAM
            DJNZ     R2,IR_4BYTE     ;接收完16位地址码和8位数据码和8位数据,
                                     ;存放在3AH/3BH/3CH/3DH的RAM中
            JMP      IR_GOTO         ;解码完成!跳到相应的执行部份
    
;************************************************************************ 
;         接收到重复码和错误码的执行处
;************************************************************************
;          IR_Rp:                    ;这里为重复码执行处                                   
;          JMP       IR_GOTO         ;按住遥控按键时,每过108ms就到这里来
;***********************************************************************
IR_ERROR:  CLR       RED_LED         ;RED LED==Error退出
           ;CALL      DELAY2400
           AJMP      INT_2
           AJMP      MAIN            ;退出解码子程
;************************************************************************
;**        遥控码值识别判断
;************************************************************************
IR_GOTO:   ;这里还要判断两个系统码或用户码,用于识别不同的遥控器,如果要测试
           ;其它的遥控器,下面几行要取消,          
           MOV      A,3AH
           CJNE     A,#9AH,IR_ERROR   ;用户码1不对(不等于#9AH)则退出
           MOV      A,3BH
           CJNE     A,#65H,IR_ERROR   ;用户码2不对(不等于#65H)则退出
           MOV      A,3AH
           CPL      A
           CJNE     A,3BH,IR_ERROR    ;有些遥控器用户码1与用户码2不是反码
                                      ;如果要测试其它的遥控器,以上几行要取消。
         
           MOV      A,3CH             ;判断两个数据码3CH,3DH是否相反
           CPL      A
           CJNE     A,3DH,IR_ERROR    ;两个数据码不相反则退出
     CLR      YELLOW_LED        ;YELLOW LED亮,解码正常
;**************************************************************************
;         遥控执行部份
;**************************************************************************
            MOV       A,3CH               ;判断对应按键
     CJNE      A,#5FH,Y_SS         ;当按下ON/OFF时打开或关闭显示(显示的电源)
     AJMP      OPENPW
;;=================================================================================
;;**        调整时间的子程序
;;===============================================================================
;;     以下程序是当按下调整秒、分、小时的按键时,分别对所调整的时间加1。


    Y_SS:   CJNE      A,#17H,Y_MM         ;调整秒钟(调整秒钟的键码值是17H)
            MOV       R0,#79H             ;SSS: 将秒钟的显示地址移到R0中      
            ACALL     DAD1                ;执行秒加1程序
            MOV       A,R2                ;加1后秒值在R2中
            XRL       A,#60H              ;是否到60秒??
            JNZ       INT_2               ;不到则返回
            MOV       79H,#00H            ;到60则执行清0程序
            AJMP      INT_2               ;返回


    Y_MM:   CJNE      A,#07H,Y_HH   ;调整分钟的程序,与秒的相似 
            MOV       R0,#7BH             ;(调整分钟的键码值是07H)
            ACALL     DAD1
            MOV       A,R2
            XRL       A,#60H
            JNZ       INT_2
            MOV       7BH,#00H
            AJMP      INT_2               ;返回


    Y_HH:   CJNE      A,#02H,BIJIAO        ;调整小时的程序,与秒的相似
            MOV       R0,#7DH              ;(调整小时的键码值是02H)
            ACALL     DAD1
            MOV       A,R2
            XRL       A,#24H
            JNZ       INT_2
            MOV       7DH,#00H
     MOV       7CH,#00H
            AJMP      INT_2                ;返回


;;====================================================================
;**        打开或关闭显示的电源
;;====================================================================
 OPENPW:    CPL       PW_ON_G
            CPL       PW_OFF_R
            CPL       P3.7                ;OPEN and close POWER
     NOP                           ;P3.7=1 ON,P3.7=0 OFF    
     AJMP      INT_2    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;         MOV       P1,3DH             ;将按键的键值通过P1口的8个LED显示出来!
;         CLR       P0.0               ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功
;         LCALL     DELAY2400
;         LCALL     DELAY2400
;         LCALL     DELAY2400
;         SETB      P0.0               ;蜂鸣器停止
;*========================================================================
;**************************************************************************
;**     比较数值,将3A,3B,3C,3D的4个16位的码值转换成8个4位分别存放在79H--7FH.
;**************************************************************************
 BIJIAO:  ; MOV      A,3AH           ;按键数值判断执行,将3AH的八位数的
          ; ANL      A,#0FH          ;高4位和低4位分别转存在7CH和7BH中
          ; MOV      76H,A           ;因为显示只有六位,将不显示3AH的代码。
          ; MOV      A,3AH           ;
          ; ANL      A,#0F0H
          ; SWAP     A
          ; MOV      77H,A


           MOV      A,3BH           ;按键数值判断执行,将3BH的八位数的高4位和
           ANL      A,#0FH          ;低4位分别转存在7CH和7BH中
           MOV      74H,A ;74H         
           MOV      A,3BH
           ANL      A,#0F0H
           SWAP     A
           MOV      75H,A ;75H
      
           MOV      A,3CH            ;按键数值判断执行,将3CH的八位数的                       
           ANL      A,#0FH           ;高4位和低4位分别转存在7AH和79H中
           MOV      72H,A ;72H
           MOV      A,3CH
           ANL      A,#0F0H
           SWAP     A
           MOV      73H,A ;73H
 
           MOV      A,3DH            ;按键数值判断执行,将3CH的八位数的                       
           ANL      A,#0FH           ;高4位和低4位分别转存在7AH和79H中
           MOV      70H,A ;70H       ;转存后79H,7AH,7BH,7CH,7EH,7FH的高4位都是0
           MOV      A,3DH
           ANL      A,#0F0H
           SWAP     A
           MOV      71H,A ;71H
          
    MOV      39H,#0FFH
    ;MOV      38H,#03H


           ACALL    DIR_IR           ;执行显示功能,将码值显示在数码管上
           ;CALL     DELAYIR         ;延时,使数值能显示在数码管上一会儿
;;=================================================================================
   INT_2:    POP       PSW
             POP       ACC
      SETB      RED_LED           ;中断返回时将RED、YELLOW两个LED置1(不亮状态)
      SETB      YELLOW_LED
             SETB      EX0               ;将EX0置1,重新打开外部中断。
      RETI
;;=======================================================================
;**       按键的键码处理
;;=======================================================================
  ;           KEY:    MOV 30H,#32        ;遥控面板的按键数量
  ;           MOV      DPTR,#IRTAB        ;
  ;           LOOKUP:  MOV      A,30H     ;A的初值为32
  ;           MOVC     A,@A+DPTR          ;
  ;           XRL      A,3CH              ;A中的值与3CH中的数据做比较,相同则异或后为0
  ;           JZ       INT_2;REM_0        ;A为0后则30H中的数是键码值
  ;           DJNZ     30H,LOOKUP
  ; REM_0:    MOV      A,30H
  ;           SJMP     INT_2;END_KEY
  ; REM_1:    CLR      A
  ;END_KEY:   SETB     EA
  ;           RET 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;         以下是动态扫描程序写法
;*********************************************************************** 
IRDIR2: 
;************************************************************************
;    DIR:     ;CLOCK显示子程序
;****************************************************************
           MOV     DPTR ,#TABLE_3         ;78H, P2.5,数码管倒立的代码
    MOV     A,78H
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.5
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.5


    MOV     DPTR ,#TABLE_2
    MOV     A,79H                  ;79H, P2.4
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.4
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.4


    MOV     A,7AH                  ;7AH, P2.3
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.3
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.3
   
    MOV     A,7BH                  ;7BH, P2.2
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.2
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.2


           MOV     A,7CH                   ;7CH, P2.1
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.1
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.1


    MOV     A,7DH                   ;7DH, P2.0
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.0
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.0   


   ; DJNZ    39H,IRDIR2
    RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     
;          几个延时子程序
;=========================882
DELAY882:                             ;1.085x ((202x4)+5)=882
           MOV    45H,#202
DELAY882_A:
           NOP
           NOP
           DJNZ   45H,DELAY882_A
           RET
;=========================1000
DELAY1000:                            ;1.085x ((229x4)+5)=999.285
           MOV    45H,#229
DELAY1000_A:
           NOP
           NOP
           DJNZ   45H,DELAY1000_A
           RET
;========================2400
DELAY2400:                           ;1.085x ((245x9)+5)=2397.85
           MOV    45H,#230
DELAY2400_A:
           NOP
           NOP
           NOP
           NOP
           NOP
           NOP
           NOP  
           DJNZ   45H,DELAY2400_A
           RET
;================================== ms
DELAYIR: 
           MOV     41H,#4
AD10_IR:
           MOV     42H,#4
AD11_IR:
           MOV     43H,#4
           DJNZ    43H,$
           DJNZ    42H,AD11_IR
           DJNZ    41H,AD10_IR
    RET
;=================================== ms       
BLANK:     MOV     P1,#00H
           MOV     41H,#3
AD10_A:
           MOV     42H,#3
AD11_A:
           MOV     43H,#3
           DJNZ    43H,$
           DJNZ    42H,AD11_A
           DJNZ    41H,AD10_A
           RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DIR_IR:    ;;遥控的码值显示程序。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    MOV     DPTR ,#TABLE_3         ;78H, P2.5,数码管倒立的代码
    MOV     A,70H
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.5
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.5


    MOV     DPTR ,#TABLE_2
    MOV     A,71H                  ;79H, P2.4
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.4
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.4


    MOV     A,72H                  ;7AH, P2.3
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.3
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.3
   
    MOV     A,73H                  ;7BH, P2.2
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.2
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.2


           MOV     A,74H                   ;7CH, P2.1
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.1
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.1


    MOV     A,75H                   ;7DH, P2.0
    MOVC    A,@A+DPTR
           MOV    P1,A
    SETB    P2.0
    LCALL   DELAYIR
    LCALL   BLANK
    CLR     P2.0   
          
   ; DJNZ    38H,DIR_IR
    DJNZ    39H,DIR_IR
    RET
;*********************************************************************
;**       数据列表
;*********************************************************************
;TABLE:DB 0C0H, 0F9H,  0A4H,  0B0H,  99H       ; (共阳数码管,显示的字
;      DB  92H,  82H,  0F8H,  80H,  90H ,088H  ; 形码对应从0--F)
;      DB  83H, 0C6H,  0A1H, 86H, 84H, 0FFH
;#####################################################################
TABLE_2: DB  03FH, 06H,  05BH,  04FH,  66H      ; (共阴数码管,显示的字
         DB  6DH,  7DH,  07H,  7FH,  6FH ,077H  ; 形码对应从0--F)
         DB  7CH,  39H,  5EH,  79H,  71H
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
TABLE_3: DB  03FH, 06H,  9BH, 08FH, 0A6H        ;01234 (将数码管倒立,小数点
         DB  0ADH, 0BDH, 07H, 0BFH, 0AFH        ;56789 向上时的数字代码)
  DB  0B7H, 0BCH, 39H, 9EH,  0B9H,0B1H   ;ABCDEF     
;;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;TABLE: DB 0BFH, 86H,  0DBH, 0CFH, 0E6H         ;01234  (IR WORD CODE)
;       DB 0EDH, 0FDH, 0E0H,  0FFH, 0F6H        ;56789
;       DB 0F7H, 0FCH, 0B9H ,0DEH, 0F9H, 0F1H   ;AbCdEF
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;TABLE: DB  0FCH, 060H, 0DAH, 0F2H, 066H        ;01234串口CD4094共阴数码管
;       DB  0B6H, 0BEH, 0E0H, 0FEH, 0F6H        ;56789
;       DB  0EEH, 3EH,  9CH,  7AH,  9EH,8EH,2H,00H  ;AbCdEF和负号和全灭
;======================================================================
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 
;;;;;;;;    串口共阴数码管;;;;;;带小数点;;;;;;;
                          ;;;;;;;;;;;;;;;;;;;;;
;TABLE_POINT: DB  0FDH, 061H, 0DBH, 0F3H, 067H      ;01234  串口共阴数码管
;             DB  0B7H, 0BFH, 0E1H, 0FFH, 0F7H      ;56789  带小数点
     ; DB  2H,   00H,  0F1H                  ;负号/全灭/度数
;***********************************************************************
END


 

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户893368 2008-12-13 20:30

谢了!太感谢了!现在我们几个同学在做着方面的东东!真是太感谢了!顶!

用户1053025 2006-11-22 13:28

今天突然来这么两句,是有感而发?
相关推荐阅读
用户1490572 2006-11-08 21:26
红外遥控(NECformat)接收程序和LED显示
 ;**************************************************************;             红外遥控(NEC format)接收程序  ...
我要评论
1
6
关闭 站长推荐上一条 /4 下一条