求助,关于中断,急
环境描述,我们先在程序中运行了一个由时钟不断触发的中断(用于产生方波——实际是PWM波),此中断为低优先级,然后我们又设置了一个高优先级的按键中断,在中断退出前,我们对中断返回地址进行了重定向,可是返回后,经过了时钟初始化程序,时钟中断不再产生了。然后我们把按键中断优先级改为低级(就是把SETB PX0那句去掉),一切正常,不知何故?
;*******************************************************************
; 全国大学生电子设计大赛
; (c)Copyright 2007-2008 Liu Cunxian
; All Rights Reserved
;文件名:ndcs.asm
;作 者:刘存显
;功 能:数控直流电流源
;*******************************************************************
ORG 0000H
AJMP START
ORG 0003H
AJMP KEY
ORG 000BH
AJMP TIME0832
ORG 0013H
AJMP A0809
ORG 0030H
I EQU R6 ;电流标识(以实际的100倍标识)
;***********************主程序***************************
;********************************************************
START:
MOV SP,#5FH ;初始化堆栈
;0832初始化
MOV DPTR,#0BFFFH ;0832地址
MOV A,#00H
MOVX @DPTR,A ;0832输出0V
MOV I,#20 ;电流初始化,显示电流为0.2A
ACALL DISPLAY ;显示
;开启中断
SETB EX1
SETB IT1 ;采用负跳变触发方式
SETB ET0
MOV TMOD,#01H ;定时/计数器0工作在方式一
SETB PX0 ;外部中断0设置为高优先级
SETB EA ;开启总中断
;********************A0809取样计算************************
;********************************************************
;0809取样
A0809_5:
MOV DPTR,#0DFF8H ;0809首地址
SETB F0 ;标志第一次取样
MOV R1,#100 ;取样100次
A0809AD:
MOVX @DPTR,A ;启动AD转换
A0809_4:
CJNE R1,#0,A0809_4 ;R1为0时启动计算程序
AJMP JISUAN ;等待中断
;0809中断响应--求平均
A0809:
; PUSH
DEC R1
CLR C ;清空标志位
MOVX A,@DPTR ;读数
JZ CHU_SHI_HUA ;A为0则初始化
JBC F0,A0809_1 ;第一次取样
ADD A,R0 ;求和
RRC A ;取平均
; CLR C
A0809_1:
MOV R0,A ;存数
CJNE R1,#0,A0809_2 ;相等时不再启动AD
RETI
A0809_2:
MOVX @DPTR,A ;启动AD转换
RETI
;计算--公式:Ton=I*92/R0-1
;被除数:R2R3
;商:R4R5
JISUAN:
CLR C
MOV R4,#0 ;商初始化
MOV R5,#0
MOV R1,#9 ;限定左移次数
MOV A,#92
MOV B,I
MUL AB
MOV R2,B ;存被除数
MOV R3,A
SETB F0 ;标志第一次做除法
JISUAN2:
JBC CY,JISUAN1
MOV A,R2 ;存被除数
MOV B,R0 ;除数
DIV AB
JZ RL1 ;左移
MOV R2,B ;存被除数
JBC F0,JISUAN3 ;第一次做除法
INC R5 ;商加一
RL1:
DEC R1
MOV A,R1
JZ JISUAN_END
MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
MOV A,R2
RLC A
MOV R2,A
AJMP JISUAN2
JISUAN1:
INC R5
SUBB A,R0
CLR C
MOV R2,A
AJMP RL1
JISUAN3:
MOV R5,A ;存商
AJMP RL1
JISUAN_END:
MOV A,R5
SUBB A,#1
MOV R5,A
MOV A,R4
SUBB A,#0
MOV R4,A
CLR EX1
;******************A0832PWM波初始化程序*******************
;********************************************************
A0832:
CLR C
MOV A,#0 ;计算定时器初值
SUBB A,R5
MOV R5,A
CLR C
MOV A,#255
SUBB A,R4
MOV R4,A
CLR C
MOV TL0,R5 ;计时器0定时时间设定
MOV TH0,R4
SETB F0 ;Ton/Toff选择标志
SETB TR0 ;定时开始
MOV DPTR,#0BFFFH
MOV A,#255
MOVX @DPTR,A ;输出高电平
;************************A0809取样************************
;********************************************************
A0809TEST:
MOV DPTR,#0DFF8H ;A0809首地址
MOVX @DPTR,A ;启动AD转换
A0809TEST1:
JBC IE1,A0809TEST2 ;查询方式检测中断标志位
AJMP A0809TEST1 ;循环等待
A0809TEST2:
MOVX A,@DPTR ;取电压
JZ CHU_SHI_HUA ;A为0则初始化
AJMP A0809TEST
;***********************部分子程序***********************
;********************************************************
;重新初始化程序
CHU_SHI_HUA:
CLR EA
CLR TR0
AJMP START
DELAY:
PUSH 07H
PUSH 06H
MOV R7,#250
D1:
MOV R6,#2
D2:
DJNZ R5,$
DJNZ R6,D2
DJNZ R7,D1
POP 06H
POP 07H
RET
;********************键盘中断响应************************
;********************************************************
KEY:
PUSH 04H
PUSH 05H
PUSH PSW
PUSH ACC
MOV R4,#0
MOV A,P1
CPL A
ANL A,#07H
JZ KEYEND2
MOV R5,#10 ;延迟10ms
ACALL DELAY
MOV A,P1
CPL A
ANL A,#07H
JZ KEYEND2
JB ACC.0,DOWN
JB ACC.1,UP
JB ACC.2,RESET
AJMP KEYEND2
;按键DOWN
DOWN:
ACALL KEYCHECK
JZ DOWN1 ;当按键不满1s时运行
CJNE R4,#200,DOWN ;按键时间超过1s顺序执行
DOWN2:
DEC I ;电流减一
ACALL KEY1 ;程序段复用
CJNE I,#20,DOWN2 ;循环减一直到I=20
DOWN3:
ACALL KEYUP ;等待按键释放
JZ KEYEND
AJMP DOWN3
DOWN1:
CJNE I,#20,DOWN1_1
AJMP KEYEND
DOWN1_1:
DEC I ;电流减一
ACALL DISPLAY
AJMP KEYEND
;按键UP
UP:
ACALL KEYCHECK
JZ UP1 ;当按键不满1s时运行
CJNE R4,#200,UP ;按键时间超过1s顺序执行
UP2:
INC I ;电流加一
ACALL KEY1 ;程序段复用
CJNE I,#200,UP2 ;循环加一直到I=200
UP3:
ACALL KEYUP ;等待按键释放
JZ KEYEND
AJMP UP3
UP1:
CJNE I,#200,UP1_1
AJMP KEYEND
UP1_1:
INC I ;电流加一
ACALL DISPLAY
AJMP KEYEND
;RESET键的算法不知道有没有人有更好的方法??????????????????????????????
;按键RESET
RESET:
MOV SP,#5FH
MOV DPTR,#CHU_SHI_HUA
PUSH DPL
PUSH DPH
AJMP KEYEND1
;按键子程序
KEYEND2:
POP ACC
POP PSW
POP 05H
POP 04H
RETI
KEYCHECK:
MOV R5,#5 ;延迟5ms
ACALL DELAY
MOV A,P1
CPL A
ANL A,#07H
INC R4
RET
KEY1:
ACALL DISPLAY
ACALL KEYUP ;检测按键释放
JZ KEYEND
RET
KEYUP:
MOV A,P1
CPL A
ANL A,#07H
RET
KEYEND:
MOV SP,#5FH
MOV DPTR,#JISUAN ;PC值是16位的,#JISUAN应该也是16位的,不应该用A??????????????????????????????????????????????????
PUSH DPL
PUSH DPH
KEYEND1:
CLR TR0
CLR EX0
RETI
;********************A0832中断响应程序********************
;********************************************************
TIME0832:
CLR EX0 ;关闭外部中断0
PUSH DPL ;保存状态值
PUSH DPH
PUSH ACC
MOV DPTR,#0BFFFH
JBC F0,Toff
MOV TL0,R5 ;计时器0定时时间设定
MOV TH0,R4
MOV A,#255
MOVX @DPTR,A
CPL F0 ;取反
AJMP TIME0832END
Toff:
MOV TL0,#156 ;计时器0定时时间设定
MOV TH0,#0FFH
MOV A,#0
MOVX @DPTR,A
TIME0832END:
POP ACC ;恢复状态值
POP DPH
POP DPL
SETB EX0 ;允许外部中断0
RETI
;***********************显示部分*************************
;********************************************************
DISPLAY:
PUSH PSW ;保护数据
PUSH DPL
PUSH DPH
PUSH ACC
PUSH B
PUSH 00H
PUSH 01H
MOV DPTR,#TAB
MOV A,I
MOV R0,#30H ;初始化显示缓冲区
MOV R1,#3 ;显示位数
DISPLAY1: ;BCD码的转化与存储
INC R0
MOV B,#10
DIV AB
MOV @R0,B
DJNZ R1,DISPLAY1
DISPLAY2:
MOV R0,#30H ;显示缓冲
MOV R1,#3 ;三个字
DISPLAY3:
INC R0 ;地址加一
MOV A,@R0
MOVC A,@A+DPTR
MOV SBUF,A ;显示输出
ACALL CHECK ;输出完毕
DJNZ R1,DISPLAY3 ;三个字
POP 01H ;退出保护
POP 00H
POP B
POP ACC
POP DPH
POP DPL
POP PSW
RET
CHECK:
JNB TI,CHECK ;检测是否发送完毕
CLR TI
RET
TAB: ;字模表
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
发表时间:2007年5月25日23:48:45