第3章51单片机对中断的控制
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
;R0 为计数变量 ;A 为流水灯初值 ;将 A 的值传递给 P1 ;循环左移指令,只能对 A 执行 ;判断是否完成了 8 次循环
;延时一秒子程序
该程序相较于第 2 章的流水灯程序语句减少了很多。实际上这段程序的执行效率和占 用 ROM 空间要远小于第 2 章所讲的流水灯程序。
·81·
简简单单学通 51 单片机开发
图 3-10
新流水灯汇编项目界面
(1)将程序进行一次编译,如图 3-11 所示。这个步骤必不可少,必须保障编译成功才 可仿真。编译的输出结果如图 3-12 所示,可以看到项目中没有警告,也没有错误。
图 3-11
将程序重新编译
图 3-12 ·82·
编译输出结果
第3章
51 单片机对中断的控制
(2)设置程序调试,按照图 3-13 所示的操作步骤打开调试设置选项。
图 3-21
程序执行的效果图
(7)当执行完语句“MOV P1,A”,在主程序执行窗口的黄色箭头就会指向下一条程 序“CALL DELAY1S”,如图 3-22 所示。此时可以观察一下 P1 窗口和 watch 窗口中 P1 的值,它们都指示 P1 的值为 0XFE。因为前一条语句将 0XFE 传送给 A,所以执行完此条 语句 P1 的值就变成了这样。
第3章
51 单片机对中断的控制
来完成整个过程呢?请看流程图,如图 3-4 所示。
P1.7 1 1 1 1 1 1 1 0 P1.6 1 1 1 1 1 1 0 1 P1.5 1 1 1 1 1 0 1 1 P1.4 1 1 1 1 0 1 1 1 P1.3 1 1 1 0 1 1 1 1 P1.2 1 1 0 1 1 1 1 1 P1.1 1 0 1 1 1 1 1 1 P1.0 0 1 1 1 1 1 1 1 P1 值(16 进制) FEH FDH FBH F7H EFH DFH BFH 7FH
RRC
假设当前累加器 A 的状态和进位标志位 C 的状态分别为:
C V C Bit0 v Bit7 Bit7 Bit6 ACC Bit5 Bit5 Bit3 Bit2 Bit1 Bit0
当移位以后它们的状态为:
ACC Bit6 Bit5 Bit4 Bit3 Bit2 Bit1
执行完一次位循环左移指令,C 的状态移位给累加器的最高位,而累加器的最低位移 位给 C。 2.减1条件转移指令: (1)寄存器减 1 条件转移指令:
3.1
流水灯汇编程序的改进
也许很多读者疑惑不解,本章明明学习的是 51 单片机的中断,为什么还要再去讨论 流水灯呢?因为中断程序的执行,还是在流水灯的基础上实现的。另外,在本章给大家提 供一组更灵巧的流水灯编程方法。而本节中非常重要的一点是讲解软件仿真的方法。无论 是单片机编程,还是其他软件类的编程,软件仿真将会帮助我们快捷地调试出程序。
图 3-2
端口 P1 数值变化的规律 1
图 3-3
P1 口循环变化的规律 2
图 3-4
改进流水灯执行方案
图 3-4 给出了程序设计方案的流程图。在这里运用了一个计数变量来帮助我们统计循
·77·
简简单单学通 51 单片机开发
环的次数。首先,给 P1 赋初值,给计数变量赋值 8,表示执行循环 8 次。然后 P1 移位一 次,调用延时子函数,计数变量减 1,并判断计数变量是否为 0,如果不为 0,就继续移位; 如果为 0,表示完成了 8 次移位,再回到程序起始位置重新赋值,开始下一次的循环。
DJNE direct,rel
第二条指令和第一条非常相似,只不过 用了直接的地址来表示。Direct 表示的是直 接的 RAM 地址,主要指低 128 单元数据寄 存器,除了我们当前用的工作寄存器组,其 他都可以是 Direct 的区域。如图 3-6 所示, 假设使用工作组 1 作为我们当前的寄存器 组,其他的区域都为 Direct 区。 该指令的执行流程图,如图 3-7 所示。 3.改进流水灯汇编语言编程思路 列出了流水灯改进的两条重要的汇编
3.1.2 改进后的汇编语言流水灯
谈到了新方法,就得用到新的语句,在编程之前先介绍几条汇编指令。 1.汇编语言移位指令组 (1)循环左移:
RL A
这里的 A 就是在第 2 章中讲到的累加器 A 或 ACC,这条指令只能使用累加器 A。假 设当前累加器 A 的状态为:
A.7 Bit7 A.7 Bit6 A.6 Bit6 A.6 Bit5 A.5 Bit5 A.5 Bit4 A.4 Bit4 A.4 Bit3 A.3 Bit3 A.3 Bit2 A.2 Bit2 A.2 Bit1 A.1 Bit1 A.1 Bit0 A.0 Bit0 A.0 Bit7
则移位以后它的值为:
这条语句和循环左移是对应的,所有的数据位都向右移,数据 0 位移到数据 7 位。 (3)带进位循环左移:
RLC A
这条指令就有所不同了。第 2 章讲到了程序状态字寄存器 PSW,它的最高位为进位标 志位 CY 或 C。在这条指令中,进位标志位 C 和累加器 A 共同参与了移位。 假设当前累加器 A 的状态和进位标志位 C 的状态分别为:
将程序整理一下,完整的汇编程序如下所示。
ORG 0000H JMP MAIN ORG 0030H MAIN: MOV R0,#08h MOV A,#0FEh loop: MOV P1,A CALL DELAY1S RL a DJNZ R0,loop LJMP MAIN DELAY1S: MOV R4,#4 LOOP3: MOV R5,#255 LOOP2: MOV R6,#245 LOOP1: NOP NOP DJNZ R6,LOOP1 DJNZ R5,LOOP2 DJNZ R4,LOOP3 RET
图 3-13
目标项目设置选项 1
按照图 3-14 所示的操作步骤来设置软件仿真,一般情况下这样的设置为 Keil 的默认 选项,但为了保险起见,我们还是要重新设置一下。
2 点选“Use Simulator”
1 选择“Debug”
图 3-14
软件仿真设置方法
(3)单击仿真按钮,开始仿真。如图 3-15 所示的箭头所指处为仿真按钮,此按钮的快 捷键为 Ctrl+F5。
·86·
第3章
51 单片机对中断的控制
3.1.1 流水灯程序改进的思路
流水灯程序是按如图 3-1 所示的顺序执行的,第 2 章的关于流水灯的编程也是根据这 个图编写出来的。程序虽然直观,但是代码就显得有点臃肿,可以说,第 2 章的流水灯是 重复性的引用相同的语句,这样的代码效率是非常低的。那么怎样写出优质的程序呢?
图 3-1
流水灯执行流程
如图 3-2 所示,从中能不能找出 P1 口数值变化的规律呢?按照箭头的指示,在图中 0 是在不断地向左移动,而 P1 的状态从 FEH 变化至 7FH,每次都是执行向右移动一位,右 边最高位重新返回到第 0 位,这种移动方法称之为循环右移。 如图 3-3 所示,归纳了 P1 端口的变化情况,经过此循环左移,程序完成了一次流水, 让这个过程不断的重复下去,就可以实现流水灯功能了。 非常幸运的是,汇编语言和 C 语言都有关于左移的程序语句来供我们使用,那么怎样
图 3-16
仿真界面
(4)添加 P1 的观察窗口。流水灯项目主要观察的是 P1 口的变化情况,可以添加一个 P1 口的观察窗口,按如图 3-17 所示的步骤操作。
·84·
第3章
51 单片机对中断的控制
图 3-17
设置 P1 口观察窗口
当然,其他端口的寄存器也可以调出来。在后面的章节讲到定时器和串口等外设的时 候,也可以调出相应的寄存器。 (5)在观察窗口时,可以观察 P1 的状态,如图 3-18 所示。输入 P1 以后,效果如图 3-19 所示。
DJNE Rn,rel
指令中的 Rn 就是我们第 2 章介绍的寄存器区的 R0~R7, 这条指令可以随便使用 R0~R7 中的任何一个。rel 表示的是程序跳转的地址,注意两个操作数之间必须有一个逗号隔开。 该指令的执行流程,如图 3-5 所示。
图 3-5
指令执行过程
(2)直接地址减 1 条件转 51 单片机开发
图 3-15
仿真按钮
单击仿真按钮以后,就会出现如图 3-16 所示的界面,这就是仿真界面。程序执行窗口 表示当前程序执行的情况,黄色箭头所指处是当前将要执行的语句。 反汇编窗口是将程序重新汇编,让我们更直观地看到每条语句在程序寄存器的位置。 黄色箭头指示的是当前将要执行的语句。 寄存器窗口显示的是 51 单片机最常用的寄存器, 在图中可以看到累计器 A、 寄存器 B、 R0~R7 等寄存器。 信息输出窗口表示的是一些仿真信息。通过窗口,可以观察一些有用的变量,仿真过 程中这个窗口是很重要的。
第3章
51 单片机对中断的控制
中断的概念很容易理解,例如我们在看书的时候,电话铃突然响了,这时我们在书中 夹一个书签,然后去接电话,接完电话以后,根据书签的指示,重新开始阅读。可以说这 个电话铃响是一个中断源,中断了我们的阅读。当中断任务完成以后,继续进行阅读,这 就是一个中断响应的过程。 单片机处理的方式与此是非常类似的, 本章就来学习 51 单片机 如何处理这一过程。
图 3-8
改进流水灯汇编语言程序流程图
在流程图 3-8 中,我们用 R0 作为减 1 判断的寄存器,当然我们也可以用 R1~R7 中的 任何一个,也可以用直接地址。 4.根据流程图来编写程序 根据流程图来编写程序,如图 3-9 所示。
·80·
第3章
51 单片机对中断的控制
图 3-9
利用流程图来编写程序
则移位以后它的值为:
这个左移方法和上一节讲到的流水移位过程是一样的。说明运用这条语句可对原流水 灯程序进行改进。 (2)循环右移:
RR A
假设当前累加器 A 的状态为:
A.7 Bit7 A.7 Bit0 A.6 Bit6 A.6 Bit7 A.5 Bit5 A.5 Bit6 A.4 Bit4 A.4 Bit5 A.3 Bit3 A.3 Bit4 A.2 Bit2 A.2 Bit3 A.1 Bit1 A.1 Bit2 A.0 Bit0 A.0 Bit1
图 3-18
观察窗口设置 1
图 3-19
观察窗口设置 2 ·85·
简简单单学通 51 单片机开发
(6)进行单步仿真。如图 3-20 所示的菜单为单步仿真按钮,单击这个按钮程序就会模 拟内部执行的方法向前走一步,也可按快捷键 F11 来完成这个操作。
图 3-20
单步执行按钮
单步仿真,并观察各个窗口的变化。当程序执行完“MOV R0,#08h”这条语句时,如 图 3-21 所示,在寄存器窗口,我们可以看到 R0 已经变成 0X08,在反汇编和主程序执行窗 口,黄色的指示箭头已经指向了下一条语句“MOV A,#0FEh”。 注意一个重要的寄存器——PC,在第 2 章讲到它表示程序计数器。在反汇编窗口,PC 的值随着程序的走向在不断地递增,这个寄存器同时也可以表示每段程序在程序存储器中 的位置。
3.1.3 软件仿真介绍
程序编写好后,建立一个汇编语言项目,进行程序的编译,生成可执行程序文件,然 后在 Proteus 中重新仿真一次,观察程序走向是否正确,在这里就不再赘述了。 在本节将向大家介绍一种调试软件的方法,在 Keil 环境下进行软件仿真,这种方法非 常实用, 希望大家好好掌握。 假设已将改进后的流水灯汇编程序建立了一个项目, 如图 3-10 所示。
图 3-6 Direct 区域描述
·79·
简简单单学通 51 单片机开发
指令,大家注意到移位指令只能对累加器进行操作,所以特殊寄存器 P1 不能直接参与运 算,只可以通过累加器用做数据传送。
图 3-7
指令功能描述
DJNZ 指令既可以在完成变量的减 1 指令,又可以完成跳转指令,所以根据这两条指 令的特点来对流程图进行修改,如图 3-8 所示。
C v C Bit7 ·78· Bit6 Bit5 Bit7 Bit6 Bit5 ACC Bit5 Bit3 Bit2 Bit1 Bit0
当移位以后它们的状态为:
ACC Bit4 Bit3 Bit2 Bit1 Bit0 v
第3章
51 单片机对中断的控制
可以看到,累加器 A 的最高位移动到 C 上,而 C 的状态则传送给累加器的最低位。 (4)带进位循环右移: