搜档网
当前位置:搜档网 › 电子万年历汇编程序

电子万年历汇编程序

;程序通过protues 仿真通过,做出有实际的实锡.ds18b20 ,ds1302.带温度报警,和闹钟,有不同的工作模式,能自动时间计算出星期
;如果有需要(请留言)可提供protues 仿真图,原理图,但 PADS的画板图找不到了
;把.txt 改成.ASM
;************************************************************************************
;伪指令定义区




TIME_MIAOGE EQU 30H ;秒个位显示缓冲区
TIME_MIAOSHI EQU 31H ;秒十位显示缓冲区
TIME_FENGE EQU 32H ;分个位显示缓冲区
TIME_FENSHI EQU 33H ;分十位显示缓冲区
TIME_SHIGE EQU 34H ;时个位显示缓冲区
TIME_SHISHI EQU 35H ;时十位显示缓冲区

WEEK_DIS EQU 36H ;星期显示缓冲区
DAY1 EQU 37H ;天个位显示缓冲区
DAY2 EQU 38H ;天十位显示缓冲区

MONTH1 EQU 39H ;月个位显示缓冲区
MONTH2 EQU 3AH ;月十位显示缓冲区

YEAR1 EQU 3BH ;年个
YEAR2 EQU 3CH ;年十
YEAR3 EQU 3DH ;年百
YEAR4 EQU 3EH ;年千


TEMPEL EQU 40H ;temperature L
TEMPEH EQU 41H ;temperature H
;TEMP_AL EQU 61H ;温度下限
;TEMP_AH EQU 62H ;温度的上限
TEMP_DISHH EQU 63H ;上限十位显示缓存
TEMP_DISHL EQU 64H ;上限个位显示缓存
TEMP_DISLH EQU 65H ;下限十位显示缓存
TEMP_DISLL EQU 66H ;下限个位显示缓存
DISTH EQU 42H ;温度显示缓冲区个位
DISTL EQU 43H ;温度显示缓冲区十位
TEM_C EQU 44H ;显示温度C符号
LEDPLAY EQU 45H

BEEP BIT P3.2 ;蜂鸣器
DQ_LINE BIT P3.6 ;DS18B20数据线

PRESENCE BIT 20H.0 ;DS18B20存在标志位
FLAG BIT 20H.1 ;温度符号标志位
SEC_S BIT 20H.2 ;设定秒标志位 (1)
MIN_S BIT 20H.3 ;设定分标志位 (1)
HOUR_S BIT 20H.4 ;设定时标志位(1)
FLAG_M BIT 20H.5 ;显示时间还是年月日标志,模式标志位0为时间
YEAR_S BIT 20H.6 ;设定年标志位(1)
MONTH_S BIT 20H.7 ;设定月标志位(1)
DAY_S BIT 21H.0 ;设定日标志位(1)
LEAP BIT 21H.1 ;闰年标志位(1)
MAX_MF BIT 21H.3 ;大月标志位(1)
KMENU BIT 21H.4 ;菜单键按下标志位(1)
FLAG_UP BIT 21H.5
WEEK_S BIT 21H.6 ;星期闪(1闪)
FLASH BIT 21H.7 ;闪烁标志位(1闪)
FLAG_MS BIT 22H.0 ;年月日进入闪烁标志(1闪)
FEB_MONTH BIT 22H.1 ;二月标志位(1)
TEMP_S BIT 22H.2 ;温度闪烁标志位(1)
TEMP_HL BIT 22H.3 ;闪烁的是高还是低

SECOND EQU 46H ;读ds

1302秒的值保存在stc中
MINUTE EQU 47H
HOUR EQU 48H
DAY EQU 49H
MONTH EQU 4AH
WEEK EQU 4BH
YEAR EQU 4CH

KEYBUFF EQU 4DH ;键值暂存单元,查表时用
COUNT EQU 4EH ;加减存放值
MAX_NUM EQU 4FH ;存放加减键的最大值
COUNT_MODE EQU 60H ;模式计数器
DS1302_IO BIT P3.4
DS1302_SCLK BIT P3.3
DS1302_RST BIT P3.5

;*********************************************按键操作缓存区***********************
TIME_MIAOGEB EQU 50H ;秒个位显示缓存区
TIME_MIAOSHIB EQU 51H ;秒十位显示缓存区
TIME_FENGEB EQU 52H ;分个位显示缓存区
TIME_FENSHIB EQU 53H ;分十位显示缓存区
TIME_SHIGEB EQU 54H ;时个位显示缓存区
TIME_SHISHIB EQU 55H ;时十位显示缓存区

WEEK_DISB EQU 56H ;星期显示缓存区
DAY1B EQU 57H ;天个位显示缓存区
DAY2B EQU 58H ;天十位显示缓存区

MONTH1B EQU 59H ;月个位显示缓存区
MONTH2B EQU 5AH ;月十位显示缓存区

YEAR1B EQU 5BH ;年个位显示缓存区
YEAR2B EQU 5CH ;年十位显示缓存区
YEAR3B EQU 5DH ;年百位显示缓存区
YEAR4B EQU 5EH ;年千位显示缓存区
MODIB EQU 5FH ;按键数据保存区

;***********************************************************************************

;系统起始程序区
ORG 0000H
START: LJMP MAIN


;***********************************************************************************
;系统监控程序区

ORG 0030H
MAIN: MOV SP, #68H ;指针初始化
MOV R0, #20H ;RAM区首地址
MOV R7, #96 ;RAM区单元个数
MOV PSW, #00H ;通用寄存器第0组
INT: MOV @R0, #00H ;初始化
INC R0
DJNZ R7, INT
MOV P2, #0FFH

MOV SECOND, #00H ;初始时间设为12:00:00
;MOV TEMP_AH,#35 ;默认温度比较上限
;MOV TEMP_AL,#5
MOV TEMP_DISHH, #3
MOV TEMP_DISHL, #5
MOV TEMP_DISLH, #0
MOV TEMP_DISLL, #5

/*
MOV MINUTE, #00H
MOV HOUR, #12H
MOV DAY, #01H ;初始日期设为12年1月1日第一周
MOV MONTH, #01H
MOV WEEK, #01H
MOV YEAR, #12H ;
*/
MOV R3, #25
SETB HOUR_S ;默认进入调试模式时显
;LCALL SETDS1302
LCALL GET1302 ;待修改
LCALL DATACHULI
LCALL DISPLAY
KEYSCAN:
LCALL GET1302
LCALL DATACHULI
;LCALL DISPLAY
MOV P1, #0FFH ;清P1口,初始化键
CLR P1.2 ;清P1.2口
LCALL WORK_DS18B20
JB P1.7, KEYSCAN ;无键按下则继续扫
LCALL DISPLAY
MOV

P1, #0FFH ;清P1口,初始化键
CLR P1.2 ;清P1.2口
JB P1.7, KEYSCAN ;无键按下则继续扫
SETB KMENU ;MENU有键按下,置标志位。数值显示暂不更新
KEYSCAN1: LCALL DISPLAY ;显示,有键按下,进入按键模式
LCALL KEYMODE
LCALL WEEK_ARI ;最后调用星期算法,显示星期
LCALL KEYSCAN2 ;等等5S看键是否有up,down,切换按下
JB KMENU, KEYSCAN1;如果有MENU按键按下,则扫描按键UP,DOWN
LJMP KEYSCAN ;否则跳到KEYSCAN

;*********************************************************************
KEYSCAN2:
MOV P1, #0FFH ;清P1口,初始化键
CLR P1.3 ;清P1.3口
MOV A, P1 ;读P1口状态
ANL A, #0F0H ;清低4位,保留高四位高电平有效
XRL A, #0F0H ;异或相同则为0不同结果为1,为0则表示无键被按下(这一行)
JZ NOKEY1 ;为0则转下一行键值处理
;LCALL DL10MS ;有键按下则延时10ms再测一次抗干扰
LCALL DISPLAY ;调用显示延时去抖
;LCALL DISPLAY
MOV A, P1
ANL A, #0F0H
XRL A, #0F0H
JZ NOKEY1 ;是干扰则转下一行键值处理程序
MOV A, P1
ANL A, #0F0H ;保留高四
MOV B, A ;

LCALL WAITFREE ;判断释放

MOV A, B

KB1:
CJNE A, #070H, KB2 ;如果值为#0E0则为P1.3与P1.7组合的键
MOV KEYBUFF, #0 ;赋键值
LCALL KEYWORK_OK ;转键处理
LJMP NOKEY1

KB2: CJNE A, #0B0H, KB3 ;如果值为#0D0则为P1.3与P1.6组合的键
MOV KEYBUFF, #1
SETB FLAG_UP
;CLR FLAG_DOWN
LCALL KEYWORK
LJMP NOKEY1

KB3: CJNE A, #0D0H, KB4 ;如果值为#0B0则为P1.3与P1.5组合的
MOV KEYBUFF, #2
CLR FLAG_UP
;SETB FLAG_DOWN
LCALL KEYWORK
LJMP NOKEY1

KB4: CJNE A, #0E0H, NOKEY1 ;如果值为#70则为P1.3与P1.4组合的
MOV KEYBUFF, #3
LCALL KEYWORK_CANCEL
LJMP NOKEY1

NOKEY1: RET

;*************************************************************************************
WORK_DS18B20:
LCALL RESET ;复位与检测DS18B20
;MOV P0, #0FFH ;关闭数码管显示
MOV A, #0CCH ;跳过RON匹配
LCALL WRITE ;写入命令
MOV A, #044H ;发出温度转换命令
LCALL WRITE
;MOV R4, #130 ;利用显示程序延时
;MOV R4, #2 ;循环由原来的80改为10显烁明显减少,变为5时更新秒数变为2点几
LOOP1: LCALL DISPLAY ;延时>750ms
;DJNZ R4, LOOP1 ;等待温度转换完成

LCALL RESET ;复位与检测DS18B20
MOV A, #0CCH ;跳过ROM匹配
LCALL WRITE
MOV A, #0BEH ;发出读温度命令
LCALL WRITE
LCALL READ_TEMP ;读温度数据
LCALL CONVTEMP

;温度数据处理

LCALL COMPARE ;温度比较子程序


RET

;*************************************************************按键模式选择

KEYMODE: MOV P1, #0FFH ;清P1口,初始化键
CLR P1.2 ;清P1.2口
LCALL DISPLAY
JB P1.6, NOKEY2 ;无键按下则继续扫
LCALL DISPLAY
MOV P1, #0FFH ;清P1口,初始化键
CLR P1.2 ;清P1.2口
JB P1.6, NOKEY2 ;无键按下则继续扫
MOV B, A ;保护
LCALL WAITFREE ;判断释放
MOV A, B ;保护
LCALL MODE_SEL ;否则调用
NOKEY2: RET

;**************************************************************************************;

SETDS1302:
CLR DS1302_RST
NOP
CLR DS1302_SCLK
NOP
SETB DS1302_RST
NOP
MOV B, #8EH ;写寄存
LCALL WRITE_BYTE
MOV B, #00H ;写保护关闭
LCALL WRITE_BYTE
SETB DS1302_SCLK
NOP
CLR DS1302_RST
MOV R0, #SECOND ;内存中的时间首地址
MOV R1, #80H ;DS1302中的时间首地址
MOV R7, #07H ;字节数
SETLOOP:
CLR DS1302_RST ;时序操作
NOP
CLR DS1302_SCLK
NOP
SETB DS1302_RST
NOP
MOV B, R1 ;写命令字
LCALL WRITE_BYTE
MOV A, @R0 ;设置时间
MOV B, A
LCALL WRITE_BYTE
INC R0
INC R1
INC R1
SETB DS1302_SCLK
NOP
CLR DS1302_RST
NOP
DJNZ R7, SETLOOP
CLR DS1302_RST
NOP
CLR DS1302_SCLK
NOP
SETB DS1302_RST
NOP
MOV B, #8EH
LCALL WRITE_BYTE
MOV B, #80H ;开写保护
LCALL WRITE_BYTE
SETB DS1302_SCLK
NOP
CLR DS1302_RST
NOP
RET

;**************************************************************************************;
GET1302:

MOV R0, #SECOND
MOV R1, #81H
MOV R2, #7
GET13021: CLR DS1302_RST
NOP
CLR DS1302_SCLK
NOP
SETB DS1302_RST
NOP
MOV B, R1
LCALL WRITE_BYTE

LCALL READ_BYTE
MOV @R0, A
INC R0
INC R1
INC R1
SETB DS1302_SCLK
NOP
CLR DS1302_RST
NOP
DJNZ R2, GET13021


RET
;**************************************************************************************;
;向DS1302写一个字节
WRITE_BYTE: MOV R4, #08H
;CLR C
;CLR A
WRITE_LOOP: MOV A, B
RRC A
MOV B, A
MOV DS1302_IO, C

NOP ;使数据稳定
NOP
SETB

DS1302_SCLK
NOP
CLR DS1302_SCLK
DJNZ R4, WRITE_LOOP
RET


;**************************************************************************************;
;向ds1302读一个字节
READ_BYTE: MOV R4, #08H
CLR C
CLR A
READ_LOOP:
NOP
MOV C, DS1302_IO
NOP
NOP
RRC A
SETB DS1302_SCLK
NOP
NOP
CLR DS1302_SCLK
DJNZ R4, READ_LOOP
RET
;**************************************************************************************;
DATACHULI: PUSH DPH
PUSH DPL
PUSH ACC
PUSH PSW
CLR RS1
SETB RS0
CLR P0.4
MOV R7, #03H
MOV R0, #TIME_MIAOGE;数码管显数
MOV R1, #SECOND
DATAPR: MOV A, @R1 ;把DS1302秒中的数放到A中
ANL A, #0FH ;数据处理
MOV @R0, A ;把转换好的数据放到数据等显示的缓冲区

INC R0 ;缓冲区的地址加一,数码管显示缓冲区加1
MOV A, @R1 ;处理DS1302高位数据
SWAP A ;
ANL A, #0FH
MOV @R0, A
INC R1 ;DS1302寄存器加1
INC R0 ;缓冲区寄存器加1
DJNZ R7, DATAPR ;时分秒数据保存
;**************************星期
MOV R0, #WEEK ;星期
MOV R1, #WEEK_DIS
MOV A, @R0 ;星期数据转换
MOV @R1, A
;**************************日
MOV R0, #DAY ;DAY个位
MOV R1, #DAY1
MOV A, @R0 ;数据转换
ANL A, #0FH ;数据处理
;DAY SHI
MOV @R1, A ;把转换好的数据放到数据等显
INC R1 ;缓冲区的地址加一,数码管显示缓冲区加1
MOV A, @R0 ;处理DS1302高位数据
SWAP A ;
ANL A, #0FH
MOV @R1, A
;**************************月
MOV R0, #MONTH ;月个位
MOV R1, #MONTH1
MOV A, @R0 ;数据转换
ANL A, #0FH ;数据处理
;月 SHI
MOV @R1, A ;把转换好的数据放到数据等显
INC R1 ;缓冲区的地址加一,数码管显示缓冲区加1
MOV A, @R0 ;处理DS1302高位数据
SWAP A ;
ANL A, #0FH
MOV @R1, A
;**************年

MOV R1, #YEAR ;要处理的数据
MOV R0, #YEAR1 ;缓冲区寄存器加1;年的个位
MOV A, @R1
ANL A, #0FH
MOV @R0, A
INC R0
MOV A, @R1
SWAP A ;年十位的处理
ANL A, #0FH
MOV @R0, A ;年十位

MOV YEAR3, #0
MOV YEAR4, #2

POP PSW ;恢复当前寄存器组的组号
POP ACC
POP DPL
POP DPH
RET
;**************************************************************************************
;DS18B20温度子程序
;**************************************************************************************;
;复位子程序

RESET:
SETB DQ_LINE ;释放数据线
NOP
NOP
CLR DQ_LINE ;主

机发出复位低脉冲
MOV B, #64H ;延时600us
MOV R1, #03H
RESET1:
DJNZ B, RESET1
MOV B, #64H
DJNZ R1, RESET1

SETB DQ_LINE ;释放数据线
NOP
MOV B, #22H
RESET2:
DJNZ B, RESET2 ;延时64us
JNB DQ_LINE,RESET3 ;检测DS18B20应答位
AJMP RESET4
RESET3:
MOV B, #210 ;延时420us
DJNZ B, $
JNB DQ_LINE,RESET4 ;判DS1820释放数据线
CLR PRESENCE ;清标志位,表示DS1820存在
AJMP RESET5
RESET4:
SETB PRESENCE ;置标志位,表示DS1820不存在
RESET5:
SETB DQ_LINE ;释放数据线
RET
;**************************************************************************************;
;写数据子程序
WRITE: MOV R2, #08H
CLR C
WRITE_BYTE1: CLR DQ_LINE ;开始写时,数据线要处于低电平
MOV B, #05H
DJNZ B, $
RRC A
MOV DQ_LINE,C
MOV B, #23
DJNZ B, $ ;延时46us
SETB DQ_LINE ;释放总线,表示此次位写操作完成
DJNZ R2, WRITE_BYTE1 ;写入下一个BIT
RET
;**************************************************************************************;
;读数据子程序
READ: SETB BEEP
MOV R2, #08H
SETB DQ_LINE
CLR C
READ_BYTE1: CLR DQ_LINE
NOP
NOP
SETB DQ_LINE
NOP
NOP
MOV C, DQ_LINE
RRC A ;把读得的位值移入A
MOV B, #25 ;25而非23(>25)
DJNZ B, $ ;延时50us,不能延时46us
SETB DQ_LINE ;释放总线,表示此次位读操作完成
DJNZ R2, READ_BYTE1 ;读下一个BIT
RET

;**************************************************************************************;
;读温度子程序
READ_TEMP:
MOV R4, #2
MOV R1, #TEMPEL ;A中存放的温度放入TEMPEL(40H,41H中)
RE00:
ACALL READ ;调用
MOV @R1, A
INC R1
DJNZ R4, RE00
RET

;**************************************************************************************;
;温度数据处理子程序

CONVTEMP: ;MOV TEMPEH, #0FEH ;85度,观察温度处理子程序是理正确
;MOV TEMPEL, #05H
MOV A, TEMPEH
ANL A, #80H
JZ TEMPEL1
CLR C
MOV A, TEMPEL
CPL A
ADD A, #01
MOV TEMPEL, A
MOV A, TEMPEH
CPL A ;取反
ADDC A, #00
MOV TEMPEH, A
CLR FLAG ;温度是零下,清温度符号标志位
SJMP TEMPEP

TEMPEL1: SETB FLAG ;温度是零上,置温度符号标志位

TEMPEP:
MOV A, TEMPEL ;整数部分
ANL A, #0F0H

;取TEMPEL的高四位
SWAP A
MOV TEMPEL, A
MOV A, TEMPEH ;取TEMPEH的低四位
ANL A, #0FH
SWAP A
ORL A, TEMPEL ;组合后的值存入A

LCALL HEX2BCD1 ;转换为BCD码
MOV TEMPEL, A ;转换好的放到TEMPLE中
ANL A, #0FH
MOV DISTL, A ;个位数存入

MOV A, TEMPEL
SWAP A
ANL A,#0FH
MOV DISTH, A ;十位数存入
MOV R6, A ;A中的值放入r6中
;**********先判温度是否零下
JNB FLAG, TEMPC13 ;flag=0,温度为零下跳转
MOV A, R7 ;判断是否超出99
JNZ TEMPC14 ;如果超出则显示“--”
MOV A, R6 ;把A中的值还原出来
JZ TEMPC12 ;如果十位数为"0"转

AJMP TEMPC15
TEMPC12: ;正温度
;MOV A,DISTH ;温度为正,且十位为0
;JNZ TEMPC15
MOV DISTH, #0AH ;十位为"0"不显示
AJMP TEMPC15
TEMPC13:
;负温度
MOV A, DISTH ;判断十位是否为0
JNZ TEMPC14 ;如果十位数不为"0"转
MOV DISTH, #0DH ;如果十位为0则显示"-"

AJMP TEMPC15

TEMPC14: CLR BEEP
LCALL DL
MOV DISTH, #0DH ;显示"-"符号
MOV DISTL, #0DH ;显示"-"符号,并提示警报
AJMP TEMPC15
; 温度低于负十度,超出显示范围,调用蜂鸣器报警程序
TEMPC15:
RET

;**************************************************************************************;

HEX2BCD1:
PUSH B ;保护B中的值
MOV B, #64H ;除数为100
DIV AB
MOV R7, A ;百位数据存入R7
MOV A, #0AH ;除数为10
XCH A, B ;A与B数据交换
DIV AB
SWAP A ;高低4位数据交换 二位要变成一位数
ORL A, B ;十位和个位数据存入A
POP B
RET

;**************************************************************************************
;温度上下限比较
COMPARE:

CLR C ;上限比较
MOV A, TEMPEL
;SUBB A, TEMP_AH
JNC COMPARE_L
;LCALL BEEP_BL
COMPARE_L:
CLR C
MOV A, TEMPEL ;下限比较
;SUBB A, TEMP_AL
JNC COMPARE_END
;LCALL BEEP_BL

COMPARE_END:
RET



;**************************************************************************************;

DISPLAY: PUSH DPH
PUSH DPL
PUSH ACC
PUSH PSW

;SETB FLAG_M
JB FLAG_M, DISPLAY9;模式标志位,1跳
JMP DISPLAY10
DISPLAY9: LJMP DISPLAY3 ;接力
DISPLAY10: SETB RS1
CLR RS0
;**

****************

JB KMENU, FLASH_CHAG ;如果有菜单键按下则判断哪个闪
SJMP DISP1
FLASH_CHAG: LJMP FLASH0
;否则正常显示
DISP1:
MOV P0, #0
MOV R0, #TIME_SHISHI
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #1
MOV R0, #TIME_SHIGE
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #2
MOV R0, #TIME_FENSHI
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #3
MOV R0, #TIME_FENGE
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #4
MOV R0, #TIME_MIAOSHI
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #5
MOV R0, #TIME_MIAOGE
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #6
MOV R0, #DISTH
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #7
MOV R0, #DISTL
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #8
MOV P2, #0C6H ;C
LCALL DL
MOV P2, #0FFH
LJMP DISPLAY8


;******************************************闪烁子程序


FLASH0:
INC R1
CJNE R1, #56H, FLASH1 ;不相等则跳
MOV R1, #0 ;置0
CPL FLASH

FLASH1:
JNB HOUR_S, FLASH2
JNB FLASH, FLASH2 ;
MOV P0, #0
MOV P2, #0FFH ;灭
LCALL DL3
MOV P0, #1
MOV P2, #0FFH ;灭
LCALL DL3 ;
LJMP FLASH3

FLASH2:
MOV P0, #0
MOV R0, #TIME_SHISHI
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #1
MOV R0, #TIME_SHIGE
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

;************

FLASH3: JNB MIN_S, FLASH4
JNB FLASH, FLASH4
MOV P0, #2
MOV P2, #0FFH ;灭
LCALL DL3
MOV P0, #3
MOV P2, #0FFH ;灭
LCALL DL3 ;
LJMP FLASH5

FLASH4:
MOV P0, #2
MOV R0, #TIME_FENSHI
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #3
MOV R0, #TIME_FENGE
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

;***************
FLASH5:
JNB SEC_S, FLASH6
JNB FLASH, FLASH6

MOV P0, #4
MOV P2, #0FFH ;灭
LCALL DL3
MOV P0, #5
MOV P2, #0FFH ;灭
LCALL DL3 ;
LJMP FLASH7

FLASH6:
MOV P0, #4
MOV R0, #TIME_MIAOSHI
MOV A, @R0
MOV DPTR, #TA

BLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #5
MOV R0, #TIME_MIAOGE
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3


FLASH7: JNB TEMP_S, FLASH8
JNB FLASH, FLASH8

MOV P0, #6
MOV P2, #0FFH ;灭
LCALL DL3
MOV P0, #7
MOV P2, #0FFH ;灭
LCALL DL3
MOV P0, #8
MOV P2, #0FFH ;灭
LCALL DL3
LJMP DISPLAY8

FLASH8:
JNB TEMP_HL,FLASH9 ;判断应该闪高还是低
MOV P0, #6
MOV R0, #TEMP_DISHH
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #7
MOV R0, #TEMP_DISHL
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3
MOV P0, #8
MOV P2, #89H ;H
LCALL DL3
LJMP DISPLAY8

FLASH9: ;JB TEMP_HL,FLASH9
MOV P0, #6
MOV R0, #TEMP_DISLH
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #7
MOV R0, #TEMP_DISLL
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3
MOV P0, #8
MOV P2, #0C7H ;L
LCALL DL3

LJMP DISPLAY8 ;入栈了一定要出

;***************模式2**********************************************
DISPLAY3: SETB RS1
SETB RS0
MOV P0, #0
MOV R0, #YEAR4 ;缓存区的,显示年
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #1
MOV R0, #YEAR3 ;缓存区的,显示年
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

;LJMP FLASH10
JB FLAG_MS, FLASH10 ;有菜单键按下

MOV P0, #2
MOV R0, #YEAR2 ;缓存区的,显示年
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #3
MOV R0, #YEAR1 ;缓存区的,显示年
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #4
MOV R0, #MONTH2 ;缓存区的,显示月
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #5
MOV R0, #MONTH1 ;缓存区的,显示月
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #6
MOV R0, #DAY2 ;缓存区的,显示日
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #7
MOV R0, #DAY1 ;缓存区的,显示日
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #8
MOV R0, #WEEK_DIS ;缓存区的,显示星期
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

DISP

LAY8:
POP PSW ;恢复当前寄存器组的组号
POP ACC
POP DPL
POP DPH
;CLR RS1
;CLR RS0
RET

;*******************年月日 闪烁子程序

FLASH10:
INC R1
CJNE R1, #56H, FLASH11 ;不相等则跳
MOV R1, #0 ;置0
CPL FLASH

FLASH11:
JNB YEAR_S, FLASH12
JNB FLASH, FLASH12 ;
MOV P0, #2
MOV P2, #0FFH ;灭
LCALL DL3
MOV P0, #3
MOV P2, #0FFH ;灭
LCALL DL3 ;
LJMP FLASH13 ;FLASH3 ERROR

FLASH12:
MOV P0, #2
MOV R0, #YEAR2
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #3
MOV R0, #YEAR1
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

;************

FLASH13:
JNB MONTH_S, FLASH14
JNB FLASH, FLASH14
MOV P0, #4
MOV P2, #0FFH ;灭
LCALL DL3
MOV P0, #5
MOV P2, #0FFH ;灭
LCALL DL3 ;
LJMP FLASH15

FLASH14:
MOV P0, #4
MOV R0, #MONTH2
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #5
MOV R0, #MONTH1
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

;***************
FLASH15:
JNB DAY_S, FLASH16
JNB FLASH, FLASH16

MOV P0, #6
MOV P2, #0FFH ;灭
LCALL DL3
MOV P0, #7
MOV P2, #0FFH ;灭
LCALL DL3 ;
LJMP FLASH17

FLASH16:
MOV P0, #6
MOV R0, #DAY2
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

MOV P0, #7
MOV R0, #DAY1
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

FLASH17:

JNB WEEK_S, FLASH18
JNB FLASH, FLASH18

MOV P0, #8
MOV P2, #0FFH ;灭
LCALL DL3 ;
LJMP DISPLAY8 ;入栈了一定要出

FLASH18:
MOV P0, #8
MOV R0, #WEEK_DIS
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV P2, A
LCALL DL3

LJMP DISPLAY8 ;入栈了一定要出

;**************************************************************************************;
TABLE:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H
; “0" “1" “2" “3" “4"“5"“6"“7"
DB 80H,90H,0FFH,0C6H,9CH,0BFH,0C7H,89H
; “8"“9""灭" C "-" "L" "H"

;**************************************************************************************;
;延时1ms子程序(晶振频率12MHz)DL
DL : MOV R7, #02H ;
MOV R7, #02H
DL1: MOV R6, #0FFH ;
MOV R6, #0FFH
DL2: DJNZ R6, DL2
DJNZ R7, DL1
RET

;**************************************************************************************;
;延时0.5ms子程序(晶振频率12MHz)DL
DL3 :

MOV R5, #01H ;
MOV R5, #01H
DL4: MOV R4, #0FFH ;
MOV R4, #0FFH
DL5: DJNZ R4, DL5
DJNZ R5, DL4
RET

;**************************************************************************************;

;***************************************************************
;模式1显示时间时的键功能程序

KEYWORK: JB FLAG_M, KEYWORK1 ;模式1年月日时跳转
JMP KEYWORK2
KEYWORK1: LJMP WORK_MODE2

KEYWORK2: JB HOUR_S, HOUR_M ;时位闪烁默认调节时

MIN_M1: JB MIN_S, MIN_M ;分位显则加的最大值为60

SEC_M1: JB SEC_S, SEC_M

SEC_M2: JB TEMP_S, TEMP_M

SEC_M3: RET

HOUR_M:
;灭一下
MOV MAX_NUM, #23
MOV B, TIME_SHIGE ;把缓存区当前的时的数据送往按键缓存区
MOV A, TIME_SHISHI ;
LCALL COMB ;合并成一个单元
MOV COUNT, A ;把转换好的数据放入按键缓存
LCALL MODI ;与最大值比较看是回一是否到最大值,如果不是按键值加1
LCALL COMB1 ;按键值分离
MOV TIME_SHIGE, B ;个位放入按键缓存区
MOV TIME_SHISHI, A ;十位放入按键缓存区
LJMP MIN_M1

MIN_M: MOV MAX_NUM, #59
MOV B, TIME_FENGE ;把缓存区当前的时的数据送往按键缓存区
MOV A, TIME_FENSHI ;
LCALL COMB ;合并成一个单元
MOV COUNT, A ;把转换好的数据放入按键缓存
LCALL MODI ;与最大值比较看是回一是否到最大值,如果不是按键值加1
LCALL COMB1 ;按键值分离
MOV TIME_FENGE, B ;个位放入按键缓存区
MOV TIME_FENSHI, A ;十位放入按键缓存区
LJMP SEC_M1 ;执行完后跳回

SEC_M: MOV MAX_NUM, #59
MOV B, TIME_MIAOGE ;把缓存区当前的数据送往按键缓存区
MOV A, TIME_MIAOSHI ;
LCALL COMB ;合并成一个单元
MOV COUNT, A ;把转换好的数据放入按键缓存
LCALL MODI ;与最大值比较看是回一是否到最大值,如果不是按键值加1
LCALL COMB1 ;按键值分离
MOV TIME_MIAOGE, B ;个位放入按键缓存区
MOV TIME_MIAOSHI, A ;十位放入按键缓存区
LJMP SEC_M2

TEMP_M: MOV MAX_NUM, #99
JNB TEMP_HL, TEMP_M1 ;为0时上限
MOV B, TEMP_DISHL
MOV A, TEMP_DISHH
LCALL COMB
MOV COUNT, A ;把转换好的数据放入按键缓存
LCALL MODI ;与最大值比较看是回一是否到最大值,如果不是按键值加1
LCALL COMB1 ;按键值分离
MOV TEMP_DISHL, B ;个位放入按键缓存区
MOV TEMP_DISHH, A ;十位放入按键缓存区
;CLR TEMP_HL
LJMP SEC_M3

TEMP_M1:
MOV B, TEMP_DISLL
MOV A, TEMP_DISLH
LCALL COMB
MOV COUNT, A ;把转换好的数据放入按键缓存
LCALL MODI ;与最大值比较看是回一是否到最大值,如果不是按键值加

1
LCALL COMB1 ;按键值分离
MOV TEMP_DISLL, B ;个位放入按键缓存区
MOV TEMP_DISLH, A ;十位放入按键缓存区
;SETB TEMP_HL
LJMP SEC_M3


;******************************************取显示缓冲区的数处理*********************
;二数合并成一个数
COMB:

MOV R5, B
MOV B, #10
MUL AB
ADD A, R5

RET
;***************************************送入按键缓冲区******************************
COMB1:
MOV A, COUNT
MOV B, #10
DIV AB

RET
;***********************************************************************************
;OK键的数据处理
;二数合并成一个数
COMB3:
SWAP A
XRL A, B
RET
;*********************************************************************************************

;模式2时显示年月日的键功能程序
WORK_MODE2:
MOV B, YEAR1 ;把缓存区当前的时的数据送往按键缓存区
MOV A, YEAR2 ;十位
LCALL COMB
MOV COUNT, A
MOV B, #4
DIV AB ;余数放在B中
MOV A, B
JZ COMB2 ;如果被4整除
COMB4: CLR LEAP ;如果不是闰年标志位则为清零
LJMP MODE3

COMB2: SETB LEAP ;闰年标标志置1

MODE3: JB YEAR_S, YEAR_M
MODE4: JB MONTH_S, MONTH_M
MODE5: JB DAY_S, MODE7
JMP MODE6
MODE7: LJMP DAY_M ;接力
MODE6: RET

;************************************************************************
;年
YEAR_M: MOV MAX_NUM, #99
MOV B, YEAR1 ;把缓存区当前的时的数据送往按键缓存区,个位
MOV A, YEAR2 ;十位
LCALL COMB ;合并成一个单元
MOV COUNT, A ;把转换好的数据放入按键缓存
LCALL MODI ;与最大值比较看是否到最大值
LCALL COMB1
MOV YEAR1, B
MOV YEAR2, A
LJMP MODE4
;*************************************************************************
;月份的判断,根据月份值设定DAY 天数的上限
MONTH_M: MOV MAX_NUM, #12
MOV B, MONTH1 ;把缓存区当前的时的数据送往按键缓存区,个位
MOV A, MONTH2 ;十位 ;
LCALL COMB ;合并成一个单元
MOV COUNT, A ;把转换好的数据放入按键缓存
LCALL MODI1
LCALL COMB1
MOV MONTH1, B
MOV MONTH2, A
LCALL MONTH_JU
LJMP MODE5
;*************************************************************************
F_MONTH0: MOV B, MONTH1 ;把缓存区当前的时的数据送往按键缓存区,个位
MOV A, MONTH2 ;十位 ;
LCALL COMB ;合并成一个单元
MOV COUNT, A ;把转换好的数据放入按键缓存

MOV A, COUNT ;更新变化后的COUNT
XRL A, #2 ;如果月份为2
JZ F_MONTH ;跳转到闰年对应的日数
CLR FEB_MONTH
LJMP F_MONTH1

F_MONTH: SETB FEB_MONTH
LJMP MONTH_END ;如果判断是二月则结束判断

F

_MONTH1: MOV A, COUNT

XRL A, #1
JZ MAX_MONTH ;大月则标志位1
MOV A, COUNT
XRL A, #3
JZ MAX_MONTH ;大月则标志位1
MOV A, COUNT
XRL A, #5
JZ MAX_MONTH ;大月则标志位1
MOV A, COUNT
XRL A, #7
JZ MAX_MONTH ;大月则标志位1
MOV A, COUNT
XRL A, #8
JZ MAX_MONTH ;大月则标志位1
MOV A, COUNT
XRL A, #10
JZ MAX_MONTH ;大月则标志位1
MOV A, COUNT
XRL A, #12
JZ MAX_MONTH ;大月则标志位1
CLR MAX_MF ;否则清
LJMP MONTH_END

MAX_MONTH: SETB MAX_MF ;大月标志位1

MONTH_END: RET

;*****************************************************************************
;闰年判断
DAY_M:
LCALL F_MONTH0
JNB FEB_MONTH, DAY_M0 ;如果是二月
JB LEAP, LEAP_YEAR ;如果LEAP为1则为闰年跳转到LEAP_YEAR
MOV MAX_NUM, #28 ;不是闰年
LJMP DAY_M2

LEAP_YEAR: MOV MAX_NUM, #29 ;闰年
LJMP DAY_M2

DAY_M0: ;SETB MAX_MF
JB MAX_MF, DAY_M1 ;大月标志位
MOV MAX_NUM, #30
LJMP DAY_M2

DAY_M1: MOV MAX_NUM, #31

DAY_M2: MOV B, DAY1 ;把缓存区当前的时的数据送往按键缓存区
MOV A, DAY2 ; 十位
LCALL COMB ;合并成一个单元
MOV COUNT, A ;把转换好的数据放入按键缓存
LCALL MODI1
LCALL COMB1
MOV DAY1, B
MOV DAY2, A
;LCALL WEEK_ARI ;最后调用星期算法,显示星期
LJMP MODE6



;*************************************************************************
;月份判断子程序
MONTH_JU:
MOV B, MONTH1
MOV A, MONTH2
LCALL COMB
MOV R6, A
MOV B, DAY1
MOV A, DAY2
LCALL COMB ;合并成一个单元
MOV R4, A
;MOV COUNT, A ;把转换好的数据放入按键缓存
XRL A, #31 ;如果天数为31则判断月是不是2 4 6 9 11
JZ MONTH_DA
MONTH_JU1: MOV A, R4
XRL A, #30
JZ MONTH_XA
MONTH_JU2: MOV A, R4
XRL A, #29
JZ MONTH_LEAP1
MONTH_JUEND:
RET

MONTH_DA:
MOV A, R6 ;放r5中保存
CJNE A, #2, MONTH_DA1 ;相等则顺序执行,不等则跳
JB LEAP, MONTH_LEAP2
JMP MONTH_LEAP3

MONTH_LEAP2: MOV DAY1, #9
MOV DAY2, #2
LJMP MONTH_JUEND
MONTH_LEAP3: MOV DAY1, #8
MOV DAY2, #2
LJMP MONTH_JUEND

MONTH_DA1: MOV A, R6
CJNE A, #4, MONTH_DA2
LJMP MONTH_UD

MONTH_DA2: MOV A, R6
CJNE A, #6, MONTH_DA3
LJMP MONTH_UD


MONTH_DA3: MOV A, R6
CJNE A, #9, MONTH_DA4
LJMP MONTH_UD


MONTH_DA4: MOV A, R6
CJNE A, #11, MONTH_JU1 ;如果都不等则跳回
LJMP MONTH_UD


MONTH_XA:
MOV B, MONTH1
MOV A, MONTH2
LCALL COMB
MOV R6, A
CJNE A, #2, MONTH_JU2
JB LEAP, MONTH_LEAP2
LJMP MONTH_LEAP3


MONTH_LEAP1: JB LEAP, MONTH_LEAP2

LJMP MONTH_LEAP3

MONTH_UD:
MOV DAY1, #0
MOV DAY2, #3
MONTH_UD2: RET
;*************************************************************************************
;星期算法子程序
WEEK_ARI: ;JMP $
PUSH B
PUSH DPH
PUSH DPL
PUSH ACC
PUSH PSW
SETB RS0
CLR RS1
MOV B, DAY1
MOV A, DAY2
LCALL COMB ;DAY
MOV R2, A
MOV B, MONTH1
MOV A, MONTH2
LCALL COMB
MOV R3, A
MOV DPTR, #TAB
MOVC A, @A+DPTR
MOV R4, A ;MONTH

MOV B, YEAR1
MOV A, YEAR2
LCALL COMB
MOV R6, A ;YEAR
MOV A, R3
CJNE A, #2, WEEK_ARI1
LJMP WEEK_ARI3

WEEK_ARI1: JC WEEK_ARI2 ;A<2
MOV A, R6 ;否则大于2
MOV B, #4
DIV AB
INC A
MOV R7, A
LJMP WEEK_ADD

WEEK_ARI2: MOV A, R6 ;小于2
MOV B, #4
DIV AB
MOV R7, A ;L
LJMP WEEK_ADD

WEEK_ARI3: MOV A, R2
CJNE A, #29, WEEK_LEAP
MOV A, R6 ;否则大于2
MOV B, #4
DIV AB
INC A
MOV R7, A
LJMP WEEK_ADD

WEEK_LEAP: LJMP WEEK_ARI2 ;不等于则小于

WEEK_ADD: MOV A, R2 ;R5--DAY,R4--M,R6--YEAR,R7--L,R3--MONTH(月份)
ADD A, R4
ADD A, R6
ADD A, R7
MOV B, #7
DIV AB
MOV A, B
XRL A, #0
JZ WEEK_ADD1

WEEK_ADD2:
MOV WEEK_DIS, B
JMP WEEK_END

WEEK_ADD1: MOV B, #7
JMP WEEK_ADD2

WEEK_END: CLR RS1
CLR RS0
POP PSW ;恢复当前寄存器组的组号
POP ACC
POP DPL
POP DPH
POP B
RET

;*************************************************************************************
TAB:DB 00h, 05H, 01H, 01H, 04H, 06H, 02H
DB 04H, 00H, 03H, 05H, 01H, 03H

;*************************************************************************************
;OK键处理子程序
KEYWORK_OK: PUSH DPH
PUSH DPL
PUSH ACC
PUSH PSW
CLR RS1
SETB RS0

MOV B, TIME_MIAOGE ;把缓存区当前的时的数据送往按键缓存区,个位
MOV A, TIME_MIAOSHI ;十位 ;
LCALL COMB3
MOV SECOND, A
MOV B, TIME_FENGE
MOV A, TIME_FENSHI
LCALL COMB3
MOV MINUTE, A
MOV B, TIME_SHIGE
MOV A, TIME_SHISHI
LCALL COMB3
MOV HOUR, A
MOV B, DAY1
MOV A, DAY2
LCALL COMB3
MOV DAY, A
MOV B, MONTH1
MOV A, MONTH2
LCALL COMB3
MOV MONTH, A
MOV B, YEAR1
MOV A, YEAR2
LCALL COMB3
MOV YEAR, A
MOV WEEK, WEEK_DIS ;星期

CLR KMENU

LCALL SETDS1302
LCALL GET1302
LCALL DATACHULI
LCALL DISPLAY
CLR SEC_S ;设定秒标志位 (1)
CLR MIN_S ;设定分标志位 (1)
CLR HOUR_S ;设定时标志位(1)
CLR FLAG_M ;显示时间还是年月日标志,模式标志位

0为时间
CLR YEAR_S ;设定年标志位(1)
CLR MONTH_S ;设定月标志位(1)
CLR DAY_S ;设定日标志位(1)
CLR WEEK_S ;星期闪(1闪)
CLR FLAG_MS ;年月日进入闪烁标志(1闪)

CLR RS1
CLR RS0

POP PSW ;恢复当前寄存器组的组号
POP ACC
POP DPL
POP DPH
RET

;*************************************************************************************
KEYWORK_CANCEL:
CLR SEC_S ;秒标志位
CLR MIN_S ;分标志位
CLR HOUR_S ;时标志位
CLR FLAG_M ;显示时间还是年月日标志
CLR YEAR_S ;设定年标志位
CLR MONTH_S ;设定月标志位
CLR DAY_S ;设定日标志位
CLR LEAP ;闰年标志位
CLR MAX_MF ;大月标志位
CLR KMENU ;菜单键按下标志位
CLR WEEK_S
MOV COUNT_MODE, #00H ;模式计数器清零
;*************************************************************************************
;模式选择
MODE_SEL: INC COUNT_MODE ;计数器加1
MODE_SEL1: MOV A, COUNT_MODE
XRL A, #1 ;和1相等模式1,时间,默认闪时变为分
JZ SEL2
MODE_SEL2: MOV A, COUNT_MODE
XRL A, #2 ;秒
JZ SEL3

MODE_SEL3: MOV A, COUNT_MODE
XRL A, #3 ;温度上限
JZ SEL4

MODE_SEL4: MOV A, COUNT_MODE;模式2,年月日星期
XRL A, #4 ;
JZ SEL5 ;年

MODE_SEL5: MOV A, COUNT_MODE;模式2,月
XRL A, #5 ;
JZ SEL6

MODE_SEL6: MOV A, COUNT_MODE;模式2,日
XRL A, #6 ;
JZ SEL7

MODE_SEL7: MOV A, COUNT_MODE;模式2,日
XRL A, #7
JZ SEL8

MODE_SEL8: MOV A, COUNT_MODE;模式2,日
XRL A, #8
JZ SEL9

MODE_SEL9:
RET


SEL2: CLR WEEK_S
CLR FLAG_M ;模式1,显示时间温度,默认
CLR FLAG_MS
SETB MIN_S ;分标位置1,分钟闪烁
CLR HOUR_S
LJMP MODE_SEL2

SEL3: SETB SEC_S ;秒
CLR MIN_S
LJMP MODE_SEL3

SEL4: CLR SEC_S
SETB TEMP_S ;FLASH
CPL TEMP_HL ;高低位
LJMP MODE_SEL4
SEL5:
CLR TEMP_S
SETB FLAG_M ;模式2 显示
SETB FLAG_MS ;模式2时进入闪烁
SETB YEAR_S ;默认年
LJMP MODE_SEL5

SEL6:
CLR YEAR_S ;取消默认显示年
SETB MONTH_S ;月
LJMP MODE_SEL6

SEL7:
CLR MONTH_S
SETB DAY_S
LJMP MODE_SEL7

SEL8:
CLR DAY_S
SETB WEEK_S
LJMP MODE_SEL8

SEL9: CLR WEEK_S
SETB HOUR_S
MOV COUNT_MODE, #0 ;计数清零
CLR FLAG_M
CLR FLAG_MS
LJMP MODE_SEL9

;*****************************************************星期的算法**********************


;******************************************************************************时*****
;按键加减
MODI: JNB FLAG_UP,WORK_DOWN ;判断是UP还是down
;LCALL BEEP_BL ;按

键声
MOV A, COUNT
CJNE A, MAX_NUM, SET_U ;是否达到最大值
MOV COUNT, #00H
LJMP KEY_SET_END1
SET_U:
INC COUNT ;设定值加1

KEY_SET_END1: RET

WORK_DOWN:
;ACALL BEEP_BL
MOV A, COUNT
CJNE A, #00H,SET_D ;是否达到最小值
MOV COUNT,MAX_NUM
AJMP KEY_SET_END
SET_D:
DEC COUNT ;设定值减1 ,不能单纯的加减1,用求补再用DA A
KEY_SET_END:
RET

;***********************************************月日加减
;月,日 按键加减
MODI1:
MOV A, COUNT
XRL A, #0
JZ MD1
JMP MD2
MD1: MOV COUNT, #1
MD2: MOV A, COUNT
JNB FLAG_UP,WORK_DOWN1 ;判断是UP还是down
;LCALL BEEP_BL ;按键声
MOV A, COUNT
CJNE A, MAX_NUM, SET_U1 ;是否达到最大值
MOV COUNT, #01H
LJMP KEY_SET_END3
SET_U1:
INC COUNT ;设定值加1

KEY_SET_END3: RET

WORK_DOWN1:
;ACALL BEEP_BL
MOV A, COUNT
CJNE A, #01H,SET_D1 ;是否达到最小值
MOV COUNT,MAX_NUM
AJMP KEY_SET_END2
SET_D1:
DEC COUNT ;设定值减1 ,不能单纯的加减1,用求补再用DA A

KEY_SET_END2:
RET



;**************************************************************************************;
;判按键释放
WAITFREE: LCALL DISPLAY
MOV A, P1;以下程序等待键释放
ANL A, #0F0H
XRL A, #0F0H
JNZ WAITFREE
RET
;**************************************************************************************;
;10毫秒延时程序
DL10MS: MOV R3, #14H
DL10MS1: LCALL DELAY
DJNZ R3, DL10MS1
RET
;**************************************************************************************;

;**************************************************************************************

;**********************************************************

; (R5)*10MS 延时子程序

;**********************************************************
DELAY:
MOV R6, #10
DEL1:
MOV R7, #230
DEL2:
DJNZ R7, DEL2
DJNZ R6, DEL1
DJNZ R5, DELAY
RET

;**********************************************************
KEY_END:
END

相关主题