单片机中断返回指令

2024年11月14日 17:59
有4个网友回答
网友(1):

修改如下,要把中断服务子程序与主程序分开

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
.

网友(2):

程序结构错误。
……
MOV TH0,#(65536-50000)/256 ;定时50毫秒
MOV TL0,#(65536-50000)/256
MOV IE,#82H
SETB TR0--主程序,到这,就没有了,这那行?

??????

TIMER: ;--下面就是:定时器中断服务程序
MOV TH0,#(65536-50000)/256 ;初脉冲50ms
MOV TL0,#(65536-50000)/256
INC R6 ;脉冲加1
MOV A,R6
……

主程序中,还缺少:调用显示、键盘、循环,等等部分。

网友(3):

EXIT:RETI 改为 RETI 试试
不过不建议用中断法做 用查询方便 你开了中断没有关吧?

网友(4):

我感觉你的程序编译都不能过,LJMP MIN,你MIN这个标号是没有的,何况这还是一个变量。