中断的应用中对断点的保护

上传人:豆浆 文档编号:11368397 上传时间:2017-10-13 格式:DOC 页数:8 大小:75KB
返回 下载 相关 举报
中断的应用中对断点的保护_第1页
第1页 / 共8页
中断的应用中对断点的保护_第2页
第2页 / 共8页
中断的应用中对断点的保护_第3页
第3页 / 共8页
中断的应用中对断点的保护_第4页
第4页 / 共8页
中断的应用中对断点的保护_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《中断的应用中对断点的保护》由会员分享,可在线阅读,更多相关《中断的应用中对断点的保护(8页珍藏版)》请在金锄头文库上搜索。

1、【016】中断的应用中对断点的保护 51点击数:430 发布日期:2006-8-22 20:37:00 【收藏】 【评论】 【打印】 【编程爱好者论坛】 【关闭】实验参考: 笨笨工作室-实验八、按键控制跑马灯(中断)。(查看)实验板: FB51A。(查看)实验目的: 掌握堆栈在中断程序中的作用。掌握让程序保护现场的方法。实验现象: 二极管作左右跑马灯,当按下外部按键 K1 时, 8 个二极管全部闪烁 5 次后从 K1 按下之前的位置继续作跑马灯。 在应用中断时,若主程序在正常运行的过程中响应了中断就要转而去执行中断服务程序。那如何在执行完中断服务程序之后完全恢复原来的主程序呢?这就需要在执行中

2、断服务程序之前将相关的状态保护起来,在中断完成后再将这些状态恢复,从而继续执行主程序。51单片机中允许我们从内部 RAM 中指定一个空间专门保存这些断点处的状态,这个空间就是堆栈。并且还专门给了我们一个 8 位的堆栈指针,让我们用它来开辟堆栈空间。例如我们给堆栈指针赋值: mov sp, #70h ,就表示我们把内部数据 RAM 的地址为 70H 开始的单元设为堆栈。 MCS51 的片内存储器(RAM)共有 256字节,高 128字节是特殊功能寄存器,地址范围 80HFFH。这一部分可看作系统资源,不能随便利用。而剩下的低 128字节区分如下:7FH 用户 RAM区 (数据缓冲区、堆栈区) 3

3、0H 80 byte 2FH 可位寻址区 20H 16 byte 1FH 第 3组工作寄存器区 18H 8 byte 17H 第 2组工作寄存器区 10H 8 byte 0FH 第 1组工作寄存器区 08H 8 byte 07H 第 0组工作寄存器区 00H 8 byte 在这低 128字节中,工作寄存器区和位寻址区的地址已分配好,我们可以利用的只有 30H 7FH 的数据缓冲区。所以我们的堆栈指针只能设在这个区域。在主程序中,让程序作左右跑马灯(参考 【004】流水灯实验),。程序中通过把寄存器 a中的数进行左环移来实现的。而 a又是最常用的一个寄存器,在中断服务程序中也多数会用到,所以在响

4、应中断时要将其保存起来(压入堆栈)。由于程序状态字寄存器 PSW(位于特殊功能寄存器区)的不同位包含了程序运行状态的不同信息,所以进入中断时也要将 PSW的值保护起来。在返回主程序之前,再把它们取出来,这样就可以使得程序从进入中断之前的位置开始,继续作跑马灯。键识别部分参考 【015】中断方式按键一文。所用电路如下:显示部分:键盘部分:程序如下:org 0000h ljmp startorg 0013hljmp ext1org 0020hstart: setb ea ; CPU开中断setb ex1 ; 允许外部中断 1申请中断setb it1 ; 设置外部中断 1为跳变方式触发mov sp,

5、 #70h ; 设置堆栈入口loop1: lcall led_flow ; 调用左右流水灯程序ljmp loop1 ext1: ; 中断服务程序clr ea ; CPU关中断push acc ; a 入栈push psw ; psw 入栈lcall key ; 调用键识别子程序pass: pop psw ; 恢复现场(与入栈顺序相反)pop accsetb ea ; CPU开中断reti ; 中断返回led_flow: mov a, #0ffh ; 左右流水灯子程序clr c ; 清 Cy进位标志位mov r7, #08h ; 左循环次数lloop: rlc a ; a循环左移mov p0,

6、a ; a送 P0口lcall del100ms ; 延时 100msdjnz r7, lloop ; 左移 8次mov r6, #06h ; 右循环次数rloop: rrc amov p0, alcall del100msdjnz r6, rloopretkey: mov a, p1 ; 键识别子程序anl a, #0fhcjne a, #0dh, passlcall del10msmov a, p1anl a, #0fhcjne a, #0dh, passlcall key_flash ; K1按下则调用灯闪程序retkey_flash: mov a, #00h ; 灯闪 5次子程序mov

7、 r5, #10 ; 闪一次有一亮一灭loop2: mov p0, acall del100mscpl a ; 取反djnz r5, loop2retdel10ms: ; 10ms延时子程序(12M) mov r4, #20 ; 2机器周期temp1: mov r3, #248 ; 2机器周期djnz r3, $ ; 2机器周期 22248498djnz r4, temp1 ; 2机器周期 22040ret ; 2204984010002 即 10ms del100ms: mov r2, #0c3h ;100.036mstemp2: mov r1, #0ffh ;511usdjnz r1, $

8、djnz r2, temp2ret end 实验结果: 最终下载到 FB51A实验板上得到预计结果。但在用 Porteus仿真时却出现问题,流水灯正常运行时按下 K1键后,8 只 LED闪烁 5次后所有 LED全灭,并未继续运行。在 LED正常流水时按下 K0、K2、或 K3键时,则停在当前状态(一只 LED亮)。经过调试后仍未解决,由于这个板上的键盘设计的有些不同,每个键都通过一个 4148连到 P3.3,而在 Proteus中仿真时用 4148行不通,所以用 4001代替的。所以怀疑是这里的问题, 于是又试着用另一块板(AS系统)试了一下, 将外部中断 1(P3.3)直接接一个开关后接地,

9、 这样就可以直接触发中断了, 程序中去除了键识别的部分, 试验结果还是一样, 板上实测通过,仿真仍然会停在中断服务程序中。后来又试着换了个中断源,原来用的外部中断 1,现在改用外部中断 0,程序中作相应的修改后再仿真就 OK了。又翻了翻书,外部中断 1和外部中断 0好像没什么不同,只是外部中断 0的优先级要比外部中断 1高。而在板上实测二者均通过,只是在仿真的时候出现问题,难道是 Porteus软件本身对这两个中断源的优先级有所区别? 还是软件本身有问题还是感觉这块板上的键盘结构在这个实验中很别扭,所以还是改为直接用一个开关控制,电路如下:程序如下:org 0000hljmp startorg

10、 0003hljmp ext1org 0030hstart: setb ea ; CPU开中断setb ex0 ; 允许外部中断 1申请中断setb it0 ; 设置外部中断 1为跳变方式触发mov sp, #70h ; 设置堆栈入口loop1: lcall led_flow ; 调用左右流水灯程序ljmp loop1 ext1: ; 中断服务程序clr ea ; CPU关中断push acc ; a 入栈push psw ; psw 入栈lcall key_flash ; K1按下则调用灯闪程序pass: pop psw ; 恢复现场(与入栈顺序相反)pop accsetb ea ; CPU

11、开中断 reti ; 中断返回led_flow: mov a, #0ffh ; 左右流水灯子程序clr c ; 清 Cy进位标志位mov r7, #08h ; 左循环次数lloop: rlc a ; a循环左移mov p0, a ; a送 P0口lcall del100ms ; 延时 100msdjnz r7, lloop ; 左移 8次mov r6, #06h ; 右循环次数rloop: rrc amov p0, alcall del100msdjnz r6, rloopretkey_flash: mov a, #00h ; 灯闪 5次子程序mov r5, #10 ; 闪一次有一亮一灭loop2: mov p0, acall del100mscpl a ; 取反djnz r5, loop2retdel10ms: ; 10ms延时子程序(12M)mov r4, #20temp1: mov r3, #248djnz r3, $djnz r4, temp1retdel100ms: mov r2, #0c3h ;100.036mstemp2: mov r1, #0ffhdjnz r1, $djnz r2, temp2ret end 引用地址:http:/

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号