
K1 BIT P1.0 秒按键设定
K2 BIT P1.1 分按键设定
K3 BIT P1.2 小时控设定
SECOND EQU 30H 定义秒为30H
MIN EQU 31H 定义分为31H
HOUR EQU 32H 定义时为32H
ORG 00H
SJMP START
ORG 0BH
LJMP TIMER
ORG 0040H
START: 开始
MOV DPTR,#TABLE 显示初始值
MOV HOUR,#0 时清零
MOV MIN,#0 分清零
MOV SECOND,#0 秒清零
MOV R6,#0 初始脉冲清零
MOV TMOD,#01H 定时器工作方式1
MOV TH0,#(65536-50000)/256 定时50毫秒
MOV TL0,#(65536-50000)/256
MOV IE,#82H
SETB TR0
KEY: 秒、分、时的按键设置
JNB K1,ADD_SECOND 按一下,秒加1
JNB K2,ADD_MIN 按一下,分加1
JNB K3,ADD_HOUR 按一下,时加1
LJMP KEY若无按键按下,返回按键设置KEY
ADD_SECOND: 秒按键,子程序
LCALL DELAY 延时子程序,去抖动
JB K1,KEY 若K1=1,则跳转到KEY
INC SECOND 秒值加1
MOV A,SECOND 秒的值传入A
CJNE A,#60,J0 判断是否加到60秒
MOV SECOND,#0 秒清零
LJMP MIN 跳转到分
ADD_MIN: 分按键,子程序
LCALL DELAY 延时子程序,去抖动
JB K2,KEY 若K2=1,则跳转到KEY
INC MIN 分钟值加1
MOV A,MIN
CJNE A,#60,J1 判断是否加到60分
MOV MIN,#0 分清零
LJMP HOUR 跳转到小时
ADD_HOUR: 时按键,子程序
LCALL DELAY 延时子程序,去抖动
JB K3,KEY 若K3=1,则跳转到KEY
INC HOUR 小时值加1
MOV A,HOUR
CJNE A,#24,J2 判断是否加到24小时
MOV HOUR,#0 时清零
MOV MIN,#0 分清零
MOV SECOND,#0 秒清零
LJMP KEY
J0: 等待按键抬起
JB K1,KEY
SJMP J0
J1:JB K2,KEY
SJMP J1
J2:JB K3,KEY
MOV A,SECOND 把秒的当前计时传入A
MOV B,#10 把数字10传送到B
DIV AB A除以B,高位为十位,低位为个位
CLR P3.6 秒十位
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.6 显示秒十位
MOV A,B
CLR P3.7 秒个位
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.7 显示秒个位
MOV A,MIN
MOV B,#10
DIV AB
CLR P3.3 分十位
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.3 显示分十位
MOV A,B
CLR P3.4 分个位
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.4 显示分个位
MOV A,HOUR
MOV B,#10
DIV AB
CLR P3.0 时十位
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.0 显示时十位
MOV A,B 时个位
CLR P3.1
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
SETB P3.1 显示时个位
RET
TABLE: DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH
DELAY: MOV R7,#250
DJNZ R7,$
RET
ORG 1000H;(如果程序存储器为4KB,就改成 ORG 0E00H)
TIMER: 定时器中断服务程序
MOV TH0,#(65536-50000)/256 初脉冲50ms
MOV TL0,#(65536-50000)/256
INC R6 脉冲加1
MOV A,R6
CJNE A,#20,EXIT 脉冲计满20次
INC SECOND 秒加1
MOV R6,#0 脉冲清零
MOV A,SECOND
CJNE A,#60,EXIT 秒满60,返回显示
INC MIN 分加1
MOV SECOND,#0 秒清零
MOV A,MIN
CJNE A,#60,EXIT 分满60,返回显示
INC HOUR 时加1
MOV MIN,#0 分清零
MOV A,HOUR
CJNE A,#24,EXIT 时满24,返回显示
MOV HOUR,#0 时清零
MOV MIN,#0 分清零
MOV SECOND,#0 秒清零
MOV R6,#0 脉冲清零
EXIT:RETI
END
.
每个单片机都会有PC(程序计数器)值,每执行一条语句PC值加一,当中断来临的时候,PC值会被压入堆栈(有些单片机是硬件自动压入,有些是需要软件压入),当中断函数执行完毕的时候,PC值会被d出堆栈,这样程序会跳到PC值所指向的那条程序继续执行。当然这个是单片机的运行机制,如果仅从表面现象来看的话就是:单片机在运行某条程序的时候,忽然来中断了,中断完了,程序又跳回这条程序继续往下执行。 欢迎追问当然可以强行跳回主程序,不影响中断标志位的清零,只要进入中断,该硬件清零的就自动清零,但强行跳回主程序,单片机会认为一直在执行中断程序,因此以后有中断发生时也不会再进入中断程序。所以不能这样做,用RETI就会跳回主程序。欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)