;**************************************************************
; 红外遥控;时钟显示(可调整时间);温度显示
;**************************************************************
;* 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
用户893368 2008-12-13 20:30
用户1053025 2006-11-22 13:28