基于51单片机的数字电子表的设计
发布网友
发布时间:2022-04-20 10:33
我来回答
共1个回答
热心网友
时间:2023-08-16 18:31
Second EQU R0
Minute EQU R1
Hour EQU R2
Times EQU R3
KeyVal EQU 21H ;储存键值
Key_Res BIT KeyVal.0
Key_Sta BIT KeyVal.1
Key_Add BIT KeyVal.2
Key_Sub BIT KeyVal.3
Key_Sto BIT KeyVal.4
Key_Shift BIT KeyVal.5
;——————————————————————————————————————
ORG 0000H ;主函数入口
SJMP MAIN ;跳转到主函数
ORG 000BH ;定时器0中断入口
LJMP INT_Timer50 ;断定时50ms服务程序;///////////主函数部分//////////;—————初始化部分————
MAIN:
MOV DPTR,#Table ;共阴字型码表首地址
MOV Second,#0 ;秒单元值零{Second,Minute,Hour
MOV Minute,#0 ;分单元值零{定义为秒
MOV Hour,#0 ;时单元值零{分,时变量
MOV IE,#082H ;打开定时器0中断
MOV TMOD,#01H ;让定时器0工作在1方式 Start:
MOV KeyVal,#0FFH ;初始化键值为ffh
MOV Times,#0 ;记录调用中断的次数,20次为1s
MOV TH0,#3CH
MOV TL0,#0B0H ;时间常数50ms
;——————初始化完成————
LOOP:
LCALL DisplayTime ;显示当时的时间
MOV A,P0
CJNE A,#0FFH,Read_Key ;按下键时读键
LCALL Deal_Key ;抬起键时处理按键消息
SJMP LOOP
Read_Key :
MOV KeyVal,A ;记下按键值
SJMP LOOP ;//////////////主程序结束///////////;/////////按键处理子程序///////////
Deal_Key:
JB Key_Shift,KEY00 ;没按shift转向复位键
INC R4 ;当按加减时首先调整小时,按下shift后
MOV A,R4 ;调整分,再按shift后调整秒,再按shift后
MOV B,#3 ;回到调整小时
DIV AB ;实现按键循环控制
MOV R4,B
SJMP EXIT
KEY00:
JB Key_Res,KEY01
SJMP MAIN
KEY01:
JB Key_Sta,SetHour
SETB TR0
SJMP Start
SetHour:
CJNE R4,#0,SetMinute
LCALL DealHour
SJMP EXIT
SetMinute:
CJNE R4,#1,SetScond
LCALL DealMinute
SJMP EXIT
SetScond:
CJNE R4,#2,EXIT
LCALL DealSecond
EXIT:
MOV KeyVal ,#0FFH ;退出时复位键值,不然影响下次判断
RET
;//////////////////////////////////////
DealHour:
JB Key_Add,KEY04
CLR TR0
INC Hour
KEY04:
JB Key_Sub,KEY05
CLR TR0
DEC Hour
KEY05:
JB Key_Sto,EXIT
CLR TR0
RET
;/////////////////////////////////////
DealMinute:
JB Key_Add,KEY004
CLR TR0
INC Minute
KEY004:
JB Key_Sub,KEY005
CLR TR0
DEC Minute
KEY005:
JB Key_Sto,EXIT
CLR TR0
RET
;////////////////////////////////////
DealSecond:
JB Key_Add,KEY040
CLR TR0
INC Second
KEY040:
JB Key_Sub,KEY050
CLR TR0
DEC Second
KEY050:
JB Key_Sto,EXIT
CLR TR0
RET
;//////////////计时子程序//////////
DisplayTime: ;//实现对时间的进位处理
CJNE Second,#60,Min
MOV Second,#0 ;六十秒到后秒单元清零
INC Minute ;且分单元加一
Min:CJNE Minute,#60,HOU
MOV Minute,#0 ;六十分钟到后分单元清零
INC Hour ;且时单元加一
HOU:CJNE Hour,#24,DIS
MOV Hour,#0 ;24小时到后时单元清零
DIS:MOV A,Second
LCALL Display ;动态显示时间
RET;////////显示子程序////////////
;显示秒的部分
Display:
MOV A,Second ;秒送累加器
MOV B,#10
DIV AB ;除10,A=十位,B=个位
MOV P1,#0EFH ; 打开秒的十位数码管
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#1 ;传递给延时函数的参数
LCALL delay ;调用延时函数
MOV P1,#0DFH ;打开秒的个位数码管
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#2
LCALL delay
;显示分的部分
MOV A,Minute
MOV B,#10
DIV AB
MOV P1,#0FBH; P1控制显示哪个数码管
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#1
LCALL delay
MOV P1,#0F7H;
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#2
LCALL delay
;显示小时的部分
MOV A,Hour
MOV B,#10
DIV AB
MOV P1,#0FEH; P1控制显示哪个数码管
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#1
LCALL delay
MOV P1,#0FDH;
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#2
LCALL delayRET
;///////////延时子程序//////////
delay:
MOV R7,#15 ;1T
DEL1:MOV R6,20H ;1T
DEL2:NOP ;1T
NOP ;1T
DJNZ R6,DEL2 ;2T
DJNZ R7,DEL1 ;2T
RET ;2T
;//////////中断服务子程序/////////
INT_Timer50:
MOV TH0,#3CH
MOV TL0,#0B0H ;重置时间常数
INC Times ;次数加一
CJNE Times,#20,ExitS ;不等20直接返回
INC Second ;一秒到,秒加{大家在处理秒时尽量放到中断函数
MOV Times,#0 ;次数清零 {,这样处理更准却,不信你可以放外面试试
ExitS: RETI
;////////////////////////////////////////// Table:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END