打印

求助,51中断问题,急急

[复制链接]
2956|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mapo365|  楼主 | 2007-5-25 23:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ov, AC, vr, AN, se
环境描述,我们先在程序中运行了一个由时钟不断触发的中断(用于产生方波——实际是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
            ;本程序由xwj设计的UltraEdit脚本加亮显示,如需要脚本请访问我的Blog或联系xwjfile@21cn.com
            

相关帖子

沙发
conwh| | 2007-5-26 00:44 | 只看该作者

PX0默认就是最高级的

使用特权

评论回复
板凳
computer00| | 2007-5-26 01:17 | 只看该作者

中断没有使用RETI返回.结果一直处于中断模式。

使用特权

评论回复
地板
conwh| | 2007-5-26 02:38 | 只看该作者

怎么半夜又上来了,呵呵

使用特权

评论回复
5
HotPower| | 2007-5-26 03:56 | 只看该作者

xwj的颜色配得不错~~~

使用特权

评论回复
6
mapo365|  楼主 | 2007-5-27 00:07 | 只看该作者

问题已解决

51有两级中断,在51内核中有两个状态触发器,表明高低级中断是否发生,当低级中断发生则其中一个硬件置1,此时只能允高级中断!当高级中断发生时,另一个置1。注意的是此标志用户是不可见的,只能由reti指令清除!

例如:
clr a                      //清除ACC=0

push acc               //压0到堆栈——8位

push acc               //再压0到堆栈——再8位

reti                        //返回到0地址,从而执行。
这样复位是有问题的!一般51有两级中断优先级!假如执行低级中断时又被高级中断中断!
这样复位仅只清除高级中断状态寄存器标志,从而造成复位后低级中断,不能中断!代码应
如下:
reset: clr ea
       mov dptr,reset1
       push dpl
       push dph
       reti
reset1:clr acc
       push acc
       push acc
       reti

使用特权

评论回复
7
maychang| | 2007-5-27 08:56 | 只看该作者

就是,退两次才可以清除所有中断标志

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

6

帖子

1

粉丝