导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→求助,关于中断,急

* 106421: 求助,关于中断,急

   mapo365 
mapo365发表的帖子 

 求助,关于中断,急
环境描述,我们先在程序中运行了一个由时钟不断触发的中断(用于产生方波——实际是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

  
回复该帖

本主题共有 2 帖,分页:>>>>>该主题的所有内容[2]条

 *树形目录 只列出部分跟帖的标题以及简单的摘要信息 该主题的部分跟帖如下:

  106423.[详细]是不是状态位的问题
摘要:在key 中断退出的时候会清除中断状态,该状态可能也是时钟中断已发生的情况。如果是这种情况,需要在退出key中断时扫描所有置位中断,并做处理。......(135字)
- [weirh98][733次] 2007年5月26日

[上一篇帖子]:是不是状态位的问题在key 中断退出的时候会清除中断状态,该状态可能也是时钟中断已发生的情
[下一篇帖子]:好~顶起来