muteM EQU 10h 静音键 闹铃开/关
timerT EQU 0Ch 菜单键 进入/退出设置状态
leftL EQU 46h 左移键
rightR EQU 47h 右移键
upU EQU 19h 增加键
downD EQU 1dh 减少键
d_off EQU 16H 显示键 LED数码管显示/关闭
recall EQU 44H 日历键 DS1302初始化 *** 作
K_on BIT P3.0 闹铃输出
LED1 BIT P3.3
LED2 BIT P3.4
LED3CLK BIT P3.5 DS1302
LED4IO BIT P3.7
RST BIT P3.1
SECOND EQU 60H
60H 秒
61h 分
62h 时
63h 日
64h 月 65h DAY
66h 年
6Ah 闹分 from 00(1302)
6BH 闹时 from 01(1302)
***************************
ORG 0000H
AJMP START
ORG 0003H
LJMP S_INT IRF
ORG 000BH 200Us
LJMP P_INT
ORG 001BH display LED
LJMP DISPLAY
**************************** main program
ORG 0030H
START: CLR RST
MOV SP,#2AH
SETB 05H
CLR 06H
SETB 07HCLR 07H
CLR 08H
CLR 09H
CLR 0AH
CLR 0BH
CLR 0CH
SETB 0DH
CLR 0EH
CLR 0FH
CLR 10H
CLR 11H
MOV R2,#00H
MOV R3,#00H
MOV TMOD,#12H
MOV TL1,#0e5H wait
MOV TH1,#0BeH
MOV TH0,#3FH 200uS 3f
MOV TL0,#3FH
SETB ET0
SETB ET1
setb pt0
SETB TR0
SETB TR1
SETB IT0
SETB EX0
CLR PX0 LCALL SET1302 初始化
MOV R1,#0C1H 取定时参数从1302中
acall T_6061
MOV 6AH,A M
MOV R1,#0C3H
ACALL T_6061
MOV 6BH,A H
MOV 61H,#0
MOV 62H,#0
SETB EA
sjmp $
********************************
DISPLAY: PUSH ACC
PUSH PSW
MOV TL1,#0e0H wait how long to display (20ms)
MOV TH1,#0b0H
MOV dptr,#tab1
JB 0EH,DIS2
JB 0FH,DIS3
JB 10H,DIS4
JB 11H,DIS5
JNB 0DH,D_OUT
JNB 08H,D_GO 定时到时,显示闪烁
JNB 07H,D_OUT
D_G MOV DPTR,#TAB1
MOV A,62H
ANL A,#0FH
MOV B,A
MOV A,62H
SWAP A
ANL A,#07H
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV C,07H
MOV acc.7,C 秒灯闪烁
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
MOV dptr,#tab2 倒装LED字段表
MOV A,61H
ANL A,#0FH
MOV B,A
MOV A,61H
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV C,07H
MOV acc.6,C 秒灯闪烁
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV dptr,#tab1
MOV A,B
MOVC A,@A+DPTR
MOV C,06H
cpl c
MOV acc.7,C 闹铃指示灯
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
D_OUT: SETB TR1
POP PSW
POP ACC
RETI
*********************
DIS2: AJMP DIS_2
DIS3: AJMP DIS_3
DIS4: AJMP DIS_4
DIS5: AJMP DIS_5
********************
DIS_2: MOV dptr,#tab1 显示设置小时
MOV 6FH,62H
ACALL BCD_HEX
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
SETB TR1
POP PSW
POP ACC
RETI
*****************
DIS_3: MOV DPTR,#TAB2 显示设置分
MOV 6FH,61H
ACALL BCD_HEX
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV A,B
MOV DPTR,#TAB1
MOVC A,@A+DPTR
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
SETB TR1
POP PSW
POP ACC
RETI
*****************
DIS_4: MOV dptr,#tab1 显示设置闹时
JNB 07H,D4_OUT 显示时闪烁
MOV A,6BH
MOV B,#0AH
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
D4_OUT: SETB TR1
POP PSW
POP ACC
RETI
***********************
DIS_5: MOV DPTR,#TAB2
JNB 07H,D5_OUT 显示时闪烁
MOV A,6AH 显示设置闹分
MOV B,#0AH
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV DPTR,#TAB1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
D5_OUT: SETB TR1
POP PSW
POP ACC
RETI
*****************************
DL2M: MOV 43H,#14H every LED(2ms)
DL2: MOV 44H,#14H
DL1: NOP
NOP
DJNZ 44H,DL1
DJNZ 43H,DL2
RET
************************定时读取1302时间及判断闹铃时间是否到*******
P_INT: PUSH ACC
PUSH PSW
INC R2
CJNE R2,#250D,P_OUT
MOV R2,#00H
INC R3
CJNE R3,#10D,P_OUT
MOV R3,#00H
CPL 07H
MOV P1,#0FFH
ACALL R_1302
OUT: JNB 06H,P_OUT
MOV A,6BH
MOV B,#10
DIV AB
SWAP A
ADD A,B
CJNE A,62H,PP_OUT
MOV A,6AH
MOV B,#10
DIV AB
SWAP A
ADD A,B
CJNE A,61H,PP_OUT
SETB 08H 定时到标志
MOV C,07H
cpl c
MOV K_ON,C
P_OUT: POP PSW
POP ACC
RETI
PP_OUT: SETB K_ON
CLR 08H
POP PSW
POP ACC
RETI
************************有接收到遥控器信号*******
S_INT:CLR EA
PUSH ACC
PUSH PSW
PUSH DPH
PUSH DPL
PUSH 02H
PUSH 03H
MOV R6,#10D
SB: ACALL YS1
JB P3.2,EXIT
DJNZ R6, SB
JNB P3.2, $
ACALL YS2
JB P3.2,EXIT
MOV R1,#1AH
MOV R2,#4D
PP: MOV R3,#8D
JJJJ: JNB P3.2,$
ACALL YS1
MOV C,P3.2
JNC UUU
JB P3.2,$
UUU: MOV A,@R1
RRC A
MOV @R1,A
DJNZ R3,JJJJ
INC R1
DJNZ R2,PP
-------------------------------------
MOV A,1AH
XRL A,#40h 判断1AH的值是否等于遥控器低8位地址(40h)
JNZ EXIT
MOV A,1bH
XRL A,#0bfh 再判断高8位地址是否正确(0bfh)
JNZ EXIT
MOV A,1CH
CPL A
XRL A,1DH 将1CH的值取反后和1DH比较 不同则无效丢弃(核对数据是否准确)
JNZ EXIT
ACALL DO 相应按键的处理
EXIT: SETB EA
POP 03H
POP 02H
POP DPL
POP DPH
POP PSW
POP ACC
RETI
--------------------delay-----------------------
YS1: MOV 70H,#16D 延时1
D1: MOV 71H,#21D
DJNZ 71H,$
DJNZ 70H,D1
RET
YS2: MOV 70H,#09D 延时2
D2: MOV 71H,#220D
DJNZ 71H,$
DJNZ 70H,D2
RET
---------------------------------------------------------
TAB: DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H TAB1 LED数码管显示表 TAB遥控器键值表(未用)
TAB1: DB 3FH,11H,5EH,5BH,71H,6BH,6FH,19H,7FH,7bH,77H,7CH,39H,5EH,79H,71H
tab1: DB 0C0H,0F9H,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,88h,83h,0a7h,0a1h,86h,8EH
TAB2: DB 0c0H,0f9H,64H,70H,59H,52H,42H 倒装LED段码表
0CH 为设置标志,0DH为全显示标志,0EH为显示设置小时标志,0FH为显示设置分标志
10H 为显示设置闹时标志,11H为显示设置闹分标志
增加闹时静音功能
mute-10h,timer-0eh,left-46h,right-47h,up-19h,down-1dh
D MOV A,1CH
CJNE A,#TIMERT,REDO 代码不是设置/退出键
JNB 0CH,SET1 是,则进入
CLR 0CH 是,已经进入,则退出
SETB 0DH 恢复正常显示
CLR 0EH
CLR 0FH
CLR 10H
CLR 11H
RET
SET1: SETB 0CH
SETB 0EH
CLR 0DH
CLR 0FH
CLR 10H
CLR 11H
RET
RED CJNE A,#MUTEM,REDO1 不是设置键的处理REDO1,2,3,4...
LJMP MUTE MUTE?
REDO1: CJNE A,#D_OFF,DO_SET2
LJMP DIS_OFF 关闭显示
DO_SET2:JB 0CH,SET2 时间设置的处理
RET
SET2: CJNE A,#UPU,SET2A
LJMP INC1 +加(^)
SET2A: CJNE A,#DOWND,SET2B
LJMP DEC2 - 减
SET2B: CJNE A,#RIGHTR,SET2C
LJMP RIGHT RIGHT右移(>)
SET2C: CJNE A,#LEFTL,SET2D LJMP LEFT LEFT左移(<)
SET2D: CJNE A,#RECALL,SET2EXT DS1302初始化
LJMP SET1302
SET2EXT:RET
--------------------------------INC------------------------
INC1: JB 0EH,INCH
JB 0FH,INCM
JB 10H,INC_H
JB 11H,INC_M
RET
INC_H: INC 6BH 闹钟小时增加
MOV A,6BH
CJNE A,#24D,INCH3
MOV 6BH,#0
INCH3: MOV R1,#0C2H
MOV R0,6BH
ACALL SETONE 写入DS1302
RET
INC_M: INC 6AH 闹钟分增加
MOV A,6AH
CJNE A,#60D,INCH4
MOV 6AH,#0
INCH4: MOV R1,#0C0H
MOV R0,6AH
ACALL SETONE
RET
INCH: INC 62H
MOV 6FH,62H
ACALL BCD_HEX
INC A
CJNE A,#24D,INCH1
MOV A,#0
INCH1: MOV 6FH,A
ACALL HEX_BCD
MOV 62H,A
MOV R1,#84H
MOV R0,62H
ACALL SETONE
RET
INCM: INC 61H
MOV 6FH,61H
ACALL BCD_HEX
INC A
CJNE A,#60D,INCH2
MOV A,#0
INCH2: MOV 6FH,A
ACALL HEX_BCD
MOV 61H,A
MOV R1,#82H
MOV R0,61H
ACALL SETONE
RET
----------------------------------DEC----------------------
DEC2: JB 0EH,DECH
JB 0FH,DECM
JB 10H,DEC_H
JB 11H,DEC_M
RET
DECH: MOV 6FH,62H
ACALL BCD_HEX
DEC A
CJNE A,#0FFH,DECH1
MOV A,#23
DECH1: MOV 6FH,A
ACALL HEX_BCD
MOV 62H,A
MOV R1,#84H
MOV R0,62H
ACALL SETONE
RET
DECM: MOV 6FH,61H
ACALL BCD_HEX
DEC A
CJNE A,#0FFH,DECM1
MOV A,#59
DECM1: MOV 6FH,A
ACALL HEX_BCD
MOV 61H,A
MOV R1,#82H
MOV R0,61H
ACALL SETONE
RET
DEC_H: DEC 6BH
MOV A,6BH
CJNE A,#0FFH,DECH3
MOV 6BH,#23D
DECH3: MOV R1,#0C2H
MOV R0,6BH
ACALL SETONE
RET
DEC_M: DEC 6AH
MOV A,6AH
CJNE A,#0FFH,DECH4
MOV 6AH,#59D
DECH4: MOV R1,#0C0H
MOV R0,6AH
ACALL SETONE
RET
--------------------------------RIGHT----------------------
RIGHT: JB 0EH,RIGHT1
JB 0FH,RIGHT2
JB 10H,RIGHT3
JB 11H,RIGHT4
RET 右移
RIGHT1: CLR 0EH
SETB 0FH
RET
RIGHT2: CLR 0FH
SETB 10H
RET
RIGHT3: CLR 10H
SETB 11H
RET
RIGHT4: CLR 11H
SETB 0EH
RET
--------------------------------LEFT-----------------------
LEFT: JB 0EH,LEFT1
JB 0FH,LEFT2
JB 10H,LEFT3
JB 11H,LEFT4
RET 左移
LEFT1: SETB 11H
CLR 0EH
RET
LEFT2: SETB 0EH
CLR 0FH
RET
LEFT3: SETB 0FH
CLR 10H
RET
LEFT4: SETB 10H
CLR 11H
RET
------------------------------MUTE--------------
MUTE: setb k_ON
CPL 06H 静音
CLR 08H
RET
-----------------------------DISPLAY OFF--------
DIS_OFF:CLR ET1
CPL 05H
JNB 05H,REDORE
SETB ET1
REDORE: RET
------------------------------------初始化1302
SET1302: CLR RST 2002年1月1日12:00:00
CLR LED3CLK
MOV SECOND,#0
MOV 61H,#0
MOV 62H,#18
MOV 63H,#1
MOV 64H,#1
MOV 65H,#1
MOV 66H,#2
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#00H
LCALL R_BIT
SETB LED3CLK
CLR RST
MOV R0,#SECOND
MOV R7,#7
MOV R1,#80H
SET1302A:CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
MOV A,@R0
LCALL R_BIT
INC R0
INC R1
INC R1
SETB LED3CLK
CLR RST
DJNZ R7,SET1302A
CLR RST
CLR LED3CLK
sETB LED3CLK
nop
CLR RST
nop
clr led3clk
SETB RST
MOV A,#90H
LCALL R_BIT
MOV A,#10100101B 充电器设置
LCALL R_BIT
SETB LED3CLK
CLR RST
CLR LED3CLK
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#80H
LCALL R_BIT
SETB LED3CLK
CLR RST
RET
----------------------读取一RAM ------
T_6061: CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
LCALL W_BIT
SETB LED3CLK
CLR RST
RET
-----------------------------
R_1302: MOV R0,#SECOND
MOV R7,#7
MOV R1,#81H
R_1302A: CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
LCALL W_BIT
MOV @R0,A
INC R0
INC R1
INC R1
SETB LED3CLK
CLR RST
DJNZ R7,R_1302A
RET
------------------R_BIT------------------
R_BIT: MOV R4,#8
R_BIT1: RRC A
MOV LED4IO,C
SETB LED3CLK
CLR LED3CLK
DJNZ R4,R_BIT1
RET
-------------------W_BIT-----------------------
W_BIT: MOV R4,#8
W_BIT1: MOV C,LED4IO
RRC A
SETB LED3CLK
CLR LED3CLK
DJNZ R4,W_BIT1
RET
--------------------------------------------------
BCD_HEX:
MOV A,6FH
ANL A,#0FH
MOV B,A
MOV A,6FH
MOV 6FH,B
SWAP A
ANL A,#0FH
MOV B,#0AH
MUL AB
ADD A,6FH
MOV 6FH,A
RET
HEX_BCD:
MOV A,6FH
MOV B,#10
DIV AB
SWAP A
ADD A,B
MOV 6FH,A
RET
-----写一地址---R1 为地址,R0 为数据----------
SETONE: CLR LED3CLK
CLR RST
CLR LED3CLK
NOP
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#00H
LCALL R_BIT
SETB LED3CLK
CLR RST
CLR LED3CLK
NOP
CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
MOV A,R0
LCALL R_BIT
NOP
SETB LED3CLK
CLR RST
NOP
NOP
CLR RST
CLR LED3CLK
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#80H
LCALL R_BIT
SETB LED3CLK
CLR RST
RET
*********************************************************带有时间设置和秒显示的数字闹钟
Date : 2007.10.26 12MHZ晶振
Create by :星星 缘木求鱼
P3.2设置键 P3.3小时调整键 P3.5分钟调整键 P3.7定时输出指示
**************************************************************
*********************************************************
变量地址分配
*********************************************************
SwDelay equ 2 设置按键时去抖动时间
DisplayBuffer equ 30h设置显示缓冲区的地址为30h-35h共6个字节
BeepVal equ 38h蜂鸣时间长短存储器地址
OneSecondCounterequ 39h设置1秒计数器的地址,1秒计数器是用来计数1秒内计时器的中断次数
Hourequ 3ah设置小时计数器的地址
Minute equ 3bh设置分钟计数器的地址
Second equ 3ch设置秒计数器的地址
Yearequ 3dh设置月日年计数器的地址
Month equ 3eh
Day equ 3fh
P1Val equ 40h设置数码管位驱动值的地址
ClockMode equ 20h.0 模式(正常走时/闹时)设置寄存器地址,值为0时正常走时,为1时闹时设定
AlarmOnOff equ 20h.1 闹钟开启/关闭标志,为0关闭,为1开启
AlarmTimeOn equ 20h.2 此位为1时表示闹时时间到
DataModeequ 20h.3
DispHourequ 21h设置小时显示寄存器的地址
DispMinute equ 22h设置分钟显示寄存器的地址
DispSecond equ 23h设置秒显示寄存器的地址
Dnumequ 24h
AlarmHour equ 2eh设置闹时小时计数器的地址
AlarmMinute equ 2fh设置闹时分钟计数器的地址
AlarmSetKey bit P3.2 闹钟设置键
MinuteKey bit P3.3 定义分设置键
HourKey bit P3.4 定义小时设置键
DataSetKey bit p3.5
RelayOutequ P3.7 定义输出引脚
**********************************************************************
程序开始
**********************************************************************
org 00h
ajmp Reset程序开始
org 0bh Timer0中断向量地址
ajmp TimeInt跳到中断处理程序
org 0020h
Reset: 以下为初始化程序,为各个变量赋初值
mov sp,#70h
setb RelayOut
mov OneSecondCounter,#125
mov Hour,#23
mov Minute,#59
mov Second,#30设置上电时时钟显示的初值
mov Year,#07
mov Month,#12
mov Day,#27
mov AlarmHour,#00
mov AlarmMinute,#00设置上电时闹时时间的初值
clr AlarmOnOff 上点复位后闹时功能处于关闭状态
clr ClockMode 正常走时模式
clr AlarmTimeOn
setb RelayOut 清闹时输出
clr DataMode
mov 36h,#10
mov 37h,#11
************************************
Use Timer 0 Mode 1
400us interrupt
************************************
mov tmod,#00000001b
mov th0,#0E3h
mov tl0,#5Dh
mov ie, #82h开全局中断
SETB EA
SETB ET0
setb tr0 开定时中断
*****************************************
以下为主程序
*****************************************
MainLoop:
jb AlarmSetKey,CheckMinuteKey 闹时设置键按下了吗?没有则转去检测秒设置键
call Delay
jb AlarmSetKey,CheckMinuteKey 按下的时间超过500ms吗?
setb ClockMode 置为闹时设置模式
call AlarmSet
CheckMinuteKey:
jb MinuteKey,CheckHourKey 分设置键按下了吗?没有则转去检测小时设置键
如按下调用蜂鸣器发音程序
mov a,Minute
add a,#1 如果按下则将分钟加一 十进制调整
mov Minute,a
cjne a,#3ch,NotOver1 到60分钟了吗?
mov Minute,#0 到60分钟则将分钟清0
NotOver1:以下等待按键释放及防抖动
jnb MinuteKey,$
CheckHourKey:
jb HourKey,CheckDataKey
如按下调用蜂鸣器发音程序
mov a,Hour
add a,#1 如果按下则将小时加1
mov Hour,a
cjne a,#18h,NotOver2
mov Hour,#0 到24小时则将小时清0
NotOver2:以下等待按键释放及防抖动
jnb HourKey,$
CheckDataKey:
jb DataSetKey,CheckAlarm
call Delay
jb DataSetKey,CheckAlarm
setb DataMode
call Dataset
CheckAlarm:
jnb AlarmTimeOn,ToReturn
call AlarmProcess
ToReturn:
ajmp MainLoop
**********************************************
定时器Timer0中断服务程序(此程序每8ms执行一次)
**********************************************
TimeInt:
mov th0,#0E3h 重新加载定时参数
mov tl0,#5Dh
push acc
push psw 保护累加器及程序状态字的内容
setb rs0 选择工作寄存器组1,
clr rs1 这样可保护原工作寄存器组(0组)的内容
djnz OneSecondCounter,NotoneSecond中断了125次了吗?即够1秒了吗?
mov OneSecondCounter,#125 如够1秒则重新设置"OneSecondCounter"计数器
call Clock调用将时钟内容加1秒的子程序
call Daynum
call ConvertoBuffer 调用将时钟内容转换到显示缓冲区子程序
NotoneSecond:
call ScanDisplay 调用扫描显示子程序
pop psw
pop acc 恢复累加器及程序状态字的内容
reti 中断返回
*********************************************
扫描显示子程序
*********************************************
ScanDisplay:
MOV R1,#DisplayBuffer指向显示数据首址
MOV R5,#0FEH扫描控制字初值
PLAY:
MOV A,R5 扫描字放入A
MOV P2,A 从P2口输出
MOV A,@R1取显示数据到A
MOV DPTR,#TAB取段码表地址
MOVC A,@A+DPTR查显示数据对应段码
MOV P1,A 段码放入P1口
LCALL Delay
INC R1 指向下一地址
MOV A,R5扫描控制字放入A
JNB ACC.7,ENDOUT 扫到第六位时结束
RL A A中数据循环左移
MOV R5,A 放回R5内
AJMP PLAY 跳回PLAY循环
ENDOUT: MOV P2,#0FFH一次显示结束,P2口复位
MOVP1,#00HP1口复位
RET子程序返回
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H,39h
共阴段码表"0""1""2" "3""4""5""6""7" "8""9""-""c"
****************************************************
时钟内容加1秒的子程序
****************************************************
Clock:
mov a,Second将原秒值送入a
add a,#1加1秒
mov Second,a
cjne a,#3cH,NotOverFlow 够60秒了吗?
mov Second,#0 够了则将秒值清0
mov a,Minute
add a,#1
mov Minute,a分钟加1
cjne a,#3cH,NotOverFlow 够60分了吗?
mov Minute,#0 够了则将分值清0
mov a,Hour
add a,#1
mov Hour,a 小时加1
cjne a,#18H,NotOverFlow 够24小时吗?
mov Hour,#0 够了则将小时值清0
mov a,Day
add a,#1
mov Day,a
cjne a,Dnum,NotAlarm
mov Day,#1
mov a,Month
add a,#1
mov Month,a
cjne a,#13,NotAlarm
mov Month,#1
mov a,Year
add a,#1
mov Year,a
cjne a,#11,NotAlarm
mov Year,#0
NotOverFlow:
jnb AlarmOnOff,NotAlarm 闹钟开启了吗?如没有开启则无需理会是否到闹时时间
mov a,Second
jnz NotAlarm秒为零吗?
mov a,Minute
cjne a,AlarmMinute,NotAlarm 时间分钟值和闹时设置分钟值相等吗?
mov a,Hour
cjne a,AlarmHour,NotAlarm 时间小时值和闹时设置小时值相等吗?
setb AlarmTimeOn到了闹时时间则将“闹时时间到”标志设为1
NotAlarm:
ret
**************************************************************************
将时钟内容或闹时设置值转换到显示缓冲区子程序
**************************************************************************
ConvertoBuffer:
mov r1,#DisplayBuffer
jnb dataMode,TimeDisp
mov a,Day
mov DispSecond,a
mov a,Month
mov DispMinute,a
mov a,Year
mov DispHour,a
ajmp Convert
TimeDisp: jb ClockMode,DispAlarmSet 判断时钟模式,以决定是显示实时时间还是闹时时间
mov a,Second
mov DispSecond,a
mov a,Minute
mov Dispminute,a
mov a,Hour
mov DispHour,a 显示实时时间
ajmp Convert
DispAlarmSet:
jb AlarmOnOff,AlarmOn
mov DispSecond,#00h
ajmp Next
AlarmOn:
mov DispSecond,#11 显示闹时时间及显示闹钟状态:显示“00”表示关闭闹钟,
Next: “11”表示开启闹钟
mov a,AlarmMinute
mov Dispminute,a
mov a,AlarmHour
mov DispHour,a
Convert:
mov a,DispSecond 取秒值
mov b,#10
div ab
mov @r1,b
inc r1 缓冲寄存器的地址加1
mov @r1,a 将秒值的十位值存入缓冲区
inc r1
mov a,DispMinute
mov b,#10
div ab
mov @r1,b
inc r1 缓冲寄存器的地址加1
mov @r1,a 将秒值的十位值存入缓冲区
inc r1
mov a,DispHour
mov b,#10
div ab
mov @r1,b
inc r1 缓冲寄存器的地址加1
mov @r1,a 将秒值的十位值存入缓冲区
ret
*******************************************************
天数判断,平年,闰年
*******************************************************
Daynum:mov a,Month
mov dptr,#TABL
movc a,@a+dptr
mov Dnum,a
mov a,Year
mov b,#4
div ab
mov a,b
cjne a,#0,BB
mov a,Month
cjne a,#2,BB
inc Dnum
BB: RET
TABL: DB 31,32,29,32,31,32,31,32,32,31,32,31,32
**************************************************
闹时设置子程序
**************************************************
AlarmSet:
jnb AlarmSetKey,$
call Delay等待“AlarmSetKey”键释放
CheckArmMinuteKey:
jb MinuteKey,CheckArmHourKey 分设置键按下了吗?没有则转去检测小时设置键
setb AlarmOnOff
mov 37h,#0
mov a,AlarmMinute
add a,#1 如果按下则将分钟加1十进制调整
mov AlarmMinute,a
cjne a,#3ch,ArmNotOver1 到60分钟了吗?
mov AlarmMinute,#0到60分钟则将分钟清0
ArmNotOver1: 以下等待按键释放及防抖动
jnb MinuteKey,$
CheckArmHourKey:
jb HourKey,AlarmSetEnd小时设置键按下了吗?没有则返回反复检测
setb AlarmOnOff
mov a,AlarmHour
add a,#1 如果按下则将小时加1
mov AlarmHour,a
cjne a,#18h,ArmNotOver2
mov AlarmHour,#0 到24小时则将小时清0
ArmNotOver2: 以下等待按键释放及防抖动
jnb HourKey,$
AlarmSetEnd:
jb AlarmSetKey,AlarmSet 设置完毕了吗?
jnb AlarmSetKey,$
clr ClockMode 从设置模式转为走时模式
ret
*********************************************
日期调整
*********************************************
DataSet:
jnb DataSetKey,$
call Delay
CheckDataYearKey:
jb HourKey,CheckDataMonthKey
mov a,Year
add a,#1
mov Year,a
cjne a,#11,DataNotOver1
mov Year,#0
DataNotOver1:
jnb HourKey,$
CheckDataMonthKey:
jb MinuteKey,CheckDataDayKey
mov a,Month
add a,#1
mov Month,a
cjne a,#13,DataNotOver2
mov Month,#1
DataNotOver2:
jnb MinuteKey,$
CheckDataDayKey:
jb AlarmSetKey,DataSetEnd
mov a,day
add a,#1
mov Day ,a
cjne a,Dnum,DataNotOver3
mov Day,#1
DataNotOver3:
jnb AlarmSetKey,$
DataSetEnd:
jb DataSetKey,DataSet
jnb DataSetKey,$
clr DataMode
ret
**************************************************
闹时服务子程序
**************************************************
AlarmProcess:
clr RelayOut
jb AlarmSetKey,AlarmReturn 停止闹时键(即闹时设置键)按下了吗?
clr AlarmOnOff
jnb AlarmSetKey,$
setb RelayOut 如停止闹时键按下则停止闹时
clr AlarmTimeOn
mov 37h,#11
mov AlarmMinute,#00
mov AlarmHour,#00
AlarmReturn:
ret
**************************************************
延时子程序
**************************************************
Delay:
mov r6,#2
Del:
mov r7,#124
djnz r7,$
djnz r6,Del
ret
DL1s: mov r3,#4
dd: call Delay
djnz r3,dd
ret
end
基于c8051f020单片机最小系统的实时时钟显示程序c8051f020 FYD12864-0402B LCD显示,按键电子时钟//
#include <c8051f020.h>
#include<lcd.h>
#include <intrins.h>
#define uchar unsigned char
void lcd_ini()
void DISPInitial()
void ascii_change(void)
void delay()
void wri_add(uchar com)
void wri_dat(uchar com1)
void shan(void)
void disp()
void tkey(void)
void PORT_Init (void)
sbit cs=P1^7
sbit sid=P1^6
sbit sclk=P1^5
bit flag=1
uchar dat,count,f=1//f测试哪个单元为当前闪烁状态
uchar data clock[3]={24,00,00}
uchar code clockname[10]={"北京时间:"}
uchar data num[6]
/*******主程序*************/
void main()
{
lcd_ini()
count=10//机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1秒
TMOD=0x01
TL0=0XB0
TH0=0X3C
EA=1
ET0=1
IT0=1
EX0=1
TR0=1
while(1)
{
back:ascii_change()
disp()
delay()
if(flag==1)
goto back
tkey()
shan()
delay()
}
}
/****lcd初始化*******/
/*void lcd_ini()
{
wri_add(0x30)
delay()
wri_add(0x0c)
delay()
wri_add(0x01)
delay()
wri_add(0x06)
delay()
}*/
void PORT_Init (void)
{
XBR0= 0x00//不让他连上IO口
XBR1= 0x14 //允许外部中断连在端口上
XBR2= 0x40// Enable crossbar and weak pull-ups
P0MDOUT |= 0x00 // enable TX0 as a push-pull output
// P1MDOUT |= 0x07 // enable P1.6 (LED) as push-pull output
P2MDOUT=0xfe //为了驱动步进电机的控制线
//P3MDOUT = 0xFF
P74OUT=0x00//配置成漏极方式可以让LCD显示成功 ,我试了配置成推挽方式不能正常显示
}
/********定时程序*************/
void timer1() interrupt 1 using 2
{
TL0=0XB0
TH0=0X3C
count--
if(count==0)
{
count=10
clock[2]++//秒//
}
else
goto out
if(clock[2]==60)
{
clock[2]=0
clock[1]++//分//
}
if(clock[1]==60)
{
clock[1]=0
clock[0]++
}
if(clock[0]==24)//时//
clock[0]=0
out:_nop_()
}
/*******十位个位转换成ASCII码************/
void ascii_change(void)
{
num[5]=clock[2]-(clock[2]/10)*10+0x30
num[4]=clock[2]/10+0x30
num[3]=clock[1]-(clock[1]/10)*10+0x30
num[2]=clock[1]/10+0x30
num[1]=clock[0]-(clock[0]/10)*10+0x30
num[0]=clock[0]/10+0x30
}
/********廷时程序*************/
void delay()
{
uchar i,j
for (i=250i>0i--)
for (j=250j>0j--)
}
/*****Write address*********/
void wri_add(uchar com)
{
uchar i,j,k
cs=0
cs=1
dat=0xf8
for(i=1i<=8i++)
{
sid=(bit)(dat&0x80)
sclk=0
sclk=1
sclk=0
dat=dat<<1
}
dat=com
dat=dat&0xf0
for(j=1j<=8j++)
{
sid=(bit)(dat&0x80)
sclk=0
sclk=1
sclk=0
dat=dat<<1
}
dat=com
dat=_cror_(dat,4)// 此为高低四位交换
dat=dat&0xf0
for(k=1k<=8k++)
{
sid=(bit)(dat&0x80)
sclk=0
sclk=1
sclk=0
dat=dat<<1
}
}
/*********Write data*************/
void wri_dat(uchar com1)
{
uchar i,j,k
cs=0
cs=1
dat=0xfa
for(i=1i<=8i++)
{
sid=(bit)(dat&0x80)
sclk=0
sclk=1
sclk=0
dat=dat<<1
}
dat=com1
dat=dat&0xf0
for(j=1j<=8j++)
{
sid=(bit)(dat&0x80)
sclk=0
sclk=1
sclk=0
dat=dat<<1
}
dat=com1
dat=_cror_(dat,4)// 此为高低四位交换
dat=dat&0xf0
for(k=1k<=8k++)
{
sid=(bit)(dat&0x80)
sclk=0
sclk=1
sclk=0
dat=dat<<1
}
}
/******display program***********/ //显示时间
void disp()
{
uchar i,k=0
wri_add(0x80)
for (i=1i<=9i++)
wri_dat(clockname[i-1])
wri_add(0x90)
for (i=1i<=6i++)
{
k++
if(k==3||k==5)
wri_dat(clockname[8])//时间之间的冒号。
wri_dat(num[i-1])
}
}
/*******闪烁程序*************************/
void shan(void)
{
uchar i,k=0
wri_add(0x90)
if(f==1)
{
num[0]=' '
num[1]=' '
}
else
goto next
for (i=1i<=6i++)
{
k++
if(k==3||k==5)
wri_dat(clockname[8])//时间之间的冒号。
wri_dat(num[i-1])
}
goto return1
next: if(f==2)
{
num[2]=' '
num[3]=' '
}
else
goto next1
for (i=1i<=6i++)
{
k++
if(k==3||k==5)
wri_dat(clockname[8])//时间之间的冒号。
wri_dat(num[i-1])
}
goto return1
next1: if(f==3)
{
num[4]=' '
num[5]=' '
}
else
goto return1
for (i=1i<=6i++)
{
k++
if(k==3||k==5)
wri_dat(clockname[8])//时间之间的冒号。
wri_dat(num[i-1])
}
return1:_nop_()
}
/*******外部中断***********/
void intr0() interrupt 0 using 2
{
flag=~flag//判断是否闪烁位//
TR0=~TR0//闪关定时否则开定时
f=1
}
/**********按键程序************/
void tkey(void)
{
uchar judcekey
judcekey=P1&0x0f
if(judcekey==0x0f)
goto return2
/*******移位键*********/
if (judcekey==0x0e)
f++
if (f==4)
f=1
/**********加一键*********/
if(judcekey==0x0d)
{clock[f-1]++}
if (f==1)
{ if (clock[f-1]==24){
clock[f-1]=0}
}
else{ if (clock[f-1]==60)
clock[f-1]=0
}
/******减一键***********/
if(judcekey==0x0b)
{clock[f-1]--}
if (f==1)
{ if (clock[f-1]==0xff){
clock[f-1]=23}
}
else
{ if (clock[f-1]==0xff)
clock[f-1]=59
}
return2:_nop_()
}
//本程序已经调试成功并能够正确执行
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)