第4章单片机汇编语言程序设计51课件_第1页
第4章单片机汇编语言程序设计51课件_第2页
第4章单片机汇编语言程序设计51课件_第3页
第4章单片机汇编语言程序设计51课件_第4页
第4章单片机汇编语言程序设计51课件_第5页
已阅读5页,还剩109页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、成都电子机械高等专科学校电气系成都电子机械高等专科学校电气系 傅林傅林 第四章 汇编语言程序设计第第4 4章章 汇编语言程序设计汇编语言程序设计4.1 4.1 概概 述述4.2 4.2 汇编语言伪指令汇编语言伪指令4.3 4.3 简单程序设计简单程序设计4.4 4.4 循环程序设计循环程序设计4.5 4.5 子程序设计子程序设计4.6 4.6 查表及散转程序设计查表及散转程序设计4.7 4.7 实用程序举例实用程序举例l 4.1.1 4.1.1 程序设计语言简介程序设计语言简介l 1.1.机器语言机器语言l 当指令和地址采用二进制代码表示时,机器能够直接识别,因此称为机器语言。l 机器指令代码

2、是0和1构成的二进制数信息,与机器的硬件操作一一对应。l 使用机器语言可以充分发挥计算机硬件的功能。l 但是,机器语言难写、难读、难交流,而且机器语言随计算机的型号不同而不同,因此移植困难。然而,无论人们使用什么语言编写程序,最终都必须翻译成机器语言,机器才能执行。4.1 4.1 概概 述述l 2. 2.汇编语言汇编语言l 汇编语言是采用易于人们记忆的助记符表示的程序设计语言,方便人们书写、阅读和检查。一般情况下,汇编语言与机器语言一一对应。l 用汇编语言编写的程序称为汇编语言源程序(源程序)。l 把汇编语言源程序翻译成机器语言程序的过程称为汇编,完成汇编过程的程序称为汇编程序,汇编产生的结果

3、是机器语言程序(目标程序).l 汇编语言源程序从目标代码的长度和程序运行时间上看与机器语言程序是等效的。不同系列的机器有不同的汇编语言,因此汇编语言源程序在不同的机器之间不能通用。l 3. 3.高级语言高级语言l 高级语言是对计算机操作步骤进行描述的一整套标记符号、表达格式、结构及其使用的语法规则。 l 它是一种面向过程的语言,使用一些接近人们书写习惯的英语和数学表达式的语言去编写程序,使用方便,通用性强,不依赖于具体计算机。目前,世界上的高级语言有数百种。l 用高级语言编写的源程序,同样需要翻译成用各种机器语言表示的目标程序,计算机才能解释执行,完成翻译过程的程序称为编译程序或解释程序。高级

4、语言程序所对应的目标代码往往比机器语言要长的多,运行时间也更多。汇编语言和高级语言相比具有下列优点:占用的内存单元和CPU资源少执行速度快有效的利用计算机的专有特性。适合实时控制 可计算程序运行时间上页下页回目录MOV P1, A如: 输出操作汇编语言程序设计的步骤:分析任务,建立数学模型确定算法制定流程图确定数据结构编写源程序代码上机调试上页下页回目录4.1.2 4.1.2 汇编语言源程序的设计步骤汇编语言源程序的设计步骤 汇编汇编l1.1.分析任务分析任务l 当我们要编写某个功能的应用程序时,首先应该详细分析给定的任务。明确哪些是任务所提供的基本条件,哪些是任务要解决的具体问题,哪些是任务

5、所期望的最终目标。l l 任务明确之后,下一步就是确定解决问题的方法。l 将给定的任务转换成计算机处理模式,即通常所说的算法。对于较复杂的任务,需要先用数学方法把问题抽象出来。往往同一个数学表达式可以用多种算法实现,我们应综合考虑寻找出其中的最佳方案,使程序所占内存小,运行时间短。l 2.2.确定算法确定算法 4.1.2 4.1.2 汇编语言源程序的设计步骤汇编语言源程序的设计步骤l3.3.画程序流程图画程序流程图l画流程图是把所采用的算法转换为汇编语言程序的准备阶段,选择合适的程序结构,把整个任务细化成若干个小的功能,使每个小功能只对应几条语句。4.1.2 4.1.2 汇编语言源程序的设计步

6、骤汇编语言源程序的设计步骤 汇编汇编流程图常用符号开始和结束符号任务处理符号判断选择符号程序连接符号程序流向符号目标:用自然语言表示算法组成:执行框(矩形框)判别框(菱形框)开始框和终止框指向线连接点三种基本结构n顺序结构n选择结构n循环结构l4.4.分配资源,确定数据结构分配资源,确定数据结构l在用汇编语言进行程序设计时,我们直接面向的是计算机的最底层资源。在编写代码之前需要对内存区域进行分配,并确定程序和数据的存放地址。4.1.2 4.1.2 汇编语言源程序的设计步骤汇编语言源程序的设计步骤 汇编汇编l 5. 5.编写代码编写代码l 在画好流程图并分配了相关资源后,就可以编写程序代码了。注

7、意: 编写完成的源程序应以“.ASM”的扩展名保存,以备汇编程序调用。l 6.6.程序修改与调试程序修改与调试l 当一个汇编语言程序编好后难免有错误或需要进一步优化的地方,必须进行调试、修改。在源程序的汇编过程中用户很容易发现程序中存在的语法错误,但查找和修改程序中的逻辑错误就不那么简单,我们需要借助开发系统所提供的程序单步操作或设置断点等调试手段予以排除。4.1.2 4.1.2 汇编语言源程序的设计步骤汇编语言源程序的设计步骤 汇编汇编汇编语言程序的结构定义有关字符名定义程序的起始地址程序主体汇编结束标志汇编语言程序设计属于结构化程序设计。结构化程序设计的特点:只有一个入口只有一个出口各功能

8、框均可执行结构中无死循环l伪指令是用于告诉汇编程序如何进行汇编的指令,它不控制机器的操作也不能被汇编成机器码,只为汇编程序所识别并指导汇编如何进行。l MCS-51MCS-51系列单片机的常用伪指令如下系列单片机的常用伪指令如下: : 4.2 4.2 汇编语言伪指令汇编语言伪指令 l l 1.ORG1.ORG起始地址定义伪指起始地址定义伪指l 令格式: ORG16位地址l 功能: 规定目标程序在程序存储器中所占空间的起始地址。l 例如: ORG1000H 表示后面的数据或程序存放在从1000H开始的程序存储单元中。l 2.END 2.END汇编程序结束伪指令汇编程序结束伪指令l 格式: END

9、l 功能: 标志源程序的结束,即通知汇编程序不再继续向下汇编。l 3.EQU 3.EQU宏代换伪指令宏代换伪指令l 格式: 符号EQU字符串l 功能: 在程序中用EQU后面的字符串去替换EQU前面的符号。l EQU后面的字符串可以是符号、数据地址、代码地址或位地址。l 说明: EQU伪指令所定义的符号必须先定义后使用。l 所以该语句一般放在程序开始。例如:l BUFFER EQU 58H ;BUFFER的值为58Hl MOV A,BUFFER ;表示内部RAM58H单元中数据送给累加器A l 4.DATA4.DATA数值赋值伪指令数值赋值伪指令l 格式: 符号名称DATA表达式l 功能: 将表

10、达式指定的数据地址或代码地址赋予符号名称。l 说明: DATA伪指令功能与EQU伪指令相似,但是DATA所定义的符号可以先使用后定义。该语句一般放在程序开始或结尾。l 例如:l BUFFER DATA58H ;BUFFER的值为58Hl MOV A,BUFFER ;表示内部RAM58H单元中数据送给累加器Al 5.DB5.DB字节存储伪指令字节存储伪指令l 格式:标号:DB8位二进制数据表l 功能: 从指定的地址单元开始,定义若干个字节存储单元的内容。 l 【例】 l ORG 100Hl FIRST:DB 01H,02Hl SECO:DB 011B,A,12l 以上伪指令经汇编后,程序存储器有

11、关单元l 如图4-1所示。l 其中伪指令中的011B为二进制数,A为字l 符A的ASCII码41H,12为十进制数。l 另外,格式中的标号为可选项。 图图4-1 4-1 例例4.14.1示意图示意图 l 6.DW6.DW字存储伪指令字存储伪指令l 格式:标号:DW16位二进制数据表l 功能: 从指定的地址单元开始,定义若干个字存储单元的内容。l 【例4.2】 l ORG 100Hl FIRST: DW 01Hl DW 1234H,AB l 以上伪指令经汇编后,程序存储器有关单元l 如图4-2所示。l 其中16位数据的高8位存入低地址单元,低8l 位存入高地址单元。l 格式中的标号为可选项。图图

12、4-2 4-2 例例4.24.2示意图示意图 l 7.DS7.DS定义空间伪指令定义空间伪指令l 格式:标号:DS表达式l 功能: 从指定的地址单元开始,保留由表达式指定的若干字节空间作为备用空间。l 例如:l ORG 1000Hl DS 0AHl DB 12H,Bl 伪指令汇编后从1000H单元开始,保留10个字节,从100AH开始连续存放12H、42H。l 8.BIT 8.BIT位地址符号伪指令位地址符号伪指令l 格式: 字符名称BIT位地址l 功能: 用规定的字符名称表示位地址。l 例如:l X0 BIT P1.0l X1 BIT 30Hl 经汇编后,P1口的第0位地址赋给X0,位地址3

13、0H赋给X1。l 在程序中可以分别用X0、X1代替P1.0和位地址30H。 结构化程序设计l 结构化程序设计(structured programming)是进行以模块功能和处理过程设计为主的详细设计的基本原则。其概念最早由E.W.Dijikstra在1965年提出的,是软件发展的一个重要的里程碑。它的主要观点是采用自顶向下、逐步求精的程序设计方法;使用三种基本控制结构构造程序,任何程序都可由顺序、选择、循环三种基本控制结构构造 。l 优点:n 整体思路清楚,目标明确。 n 设计工作中阶段性非常强,有利于系统开发的总体管理和控制。 n 在系统分析时可以诊断出原系统中存在的问题和结构上的缺陷。l

14、 缺点缺点n 用户要求难以在系统分析阶段准确定义,致使系统在交付使用时产生许多问题。 n 用系统开发每个阶段的成果来进行控制,不能适应事物变化的要求。 n 系统的开发周期长。4.3 4.3 程序设计程序设计 l 4.3.1 4.3.1 顺序程序设计顺序程序设计l 顺序结构的程序,是指程序按指令的排列顺序依次执行直至程序结束。这种结构是程序结构中最简单的一种,用程序流程图表示的顺序结构程序,是一个处理框紧接一个处理框。顺序结构表示程序中的各操作是按照它们出现的先后顺序执行的。 A B B A P A P 成立 成立 不成立 不成立 a b b b a a 最左边:顺序结构图最左边:顺序结构图 中

15、间和右边:选择结构图中间和右边:选择结构图4.3.1 4.3.1 顺序程序设计顺序程序设计l 例41 已知X、Y、Z分别为片内RAM 30H、31H、32H单元的内容,设XY,试编程完成下式的算术运算:S=(X-Y)*Z, 并将计算结果S存入片内RAM 34H(高字节)、35H(低字节)单元中。l 由于XY,所以X-Y0,不需要借位;(X-Y)*Z的结果最多占用两个字节。实现该要求的程序流程图如图右所示。开始AXAA-Y, BZB、A AB(34H)B(35H)A结束程序清单如下: ORG0030HSTART: MOVA, 30H ;(A)X SUBBA, 31H ;(A)(A)-X MOVB

16、, 32H ;(B)Z MULAB MOV34H, B ;(34H)A*B的高字节 MOV35H, A ;(35H)A*B的低字节 SJMP$例42 编写双字节无符号数乘法程序。被乘数高字节放在R2中,低字节存放在R3中,乘数高字节放在R6中,低字节放在R7中。乘积在R2、R3、R4、R5中。程序段如下:MOV A, R3 ;R3R7MOV B, R7MUL ABMOV R4, B ;暂存部分积MOV R5, AMOV A, R3MOV B, R6 ;R3R6MUL ABADD A, R4 ;累加部分积MOV R4, ACLR AADDC A, BMOV R3, AMOV A, R2 ; R2

17、R7MOV B, R7MUL AB ADD A, R4 ;累加部分积MOV R4, AMOV A, R3ADDC A, BMOV R3, ACLR ARLC AXCH A, R2 ;R2R6MOV B, R6MUL ABADD A, R3 ;累加部分积MOV R3, AMOV A, R2ADDC A, BMOV R2, A练习:将练习:将30H单元内的两位单元内的两位BCD码拆开并转换成码拆开并转换成ASCII码,存入码,存入RAM31H、32H两个单元中。两个单元中。ORG1000H MOVA,30H ;取值;取值 ANLA,#0FH ;取低;取低4位位ADDA,#30H ;转换成;转换成A

18、SCII码码MOV32H,A ;保存结果;保存结果MOVA,30H ;取值;取值SWAPA ;高;高4位与低位与低4位互换位互换ANLA,#0FH ;取低;取低4位(原来的高位(原来的高4位)位)ADDA,#30H ;转换成;转换成ASCII码码MOV31H,A ;保存结果;保存结果 SJMP$ 结束取数据低4位转换成ASCII码存ASCII码取数据高4位转换成ASCII码存ASCII码开始l 4.3.2 4.3.2 分支程序设计分支程序设计l 分支程序是按照给定的条件进行判断,根据不同的情况使程序发生转移,选择不同的程序入口。l 通常用条件转移指令形成简单分支结构。例如,判断结果是否为0(J

19、Z、JNZ)、是否有进位或借位(JC、JNC)、指定位是否为1(JB、JNB)、比较指令CJNE等都可作为分支依据。l 条件满足?AYN(a)条件满足?ABNY(b)(c)A0A1AnK=0 K=1 K=nK=?分支程序设计l 在内部RAM单元的30H和31H中各有一无符号数,试比较其大小,大数存入40H单元,小数存入41H单元,若相等则存入42H单元。程序流程框图如下图所示。开 始A(30H)A=(31H)?(A)(42H)YA(31H)?(A)(41H)(31H)(40H)(A)(40H)(31H)(41H)结 束程序如下: MOV A, 30H CJNE A, 31H, K1 MOV 4

20、2H, A AJMP WAITK1: JNC K2 MOV 41H, A MOV 40H, 31H AJMP WAITK2: MOV 40H, A MOV 41H, 31HWAIT: AJMP $4.4 4.4 循环程序设计循环程序设计l 4.4.1 4.4.1 循环结构循环结构l 顺序程序中每条指令只执行一次,分支程序则依据条件不同会跳过一些指令,执行另一部分指令。这两种程序的特点是每条指令最多只执行一次。循环结构基本流程图如右图所示。实质上,有如下图所示两种循环机制:DO_WHILE结构、DO_UNTIL结构开始结束初始化循环体循环控制循环结束?NY 循环控制条件 循环体 循环初始状态 循

21、环初始状态 循环体 循环控制条件 l 在处理实际问题时,常常要求某些程序段重复执行,此时应采用循环结构实现。l 一般包含程序初始化、循环处理、循环控制和循环结束四部分。l (1 1)初始化部分)初始化部分l 为实现程序循环做准备,如建立循环计数器、设地址指针以及为变量赋初值等。l (2 2)循环处理部分)循环处理部分l 该部分是循环程序的主体,在这里对数据进行实际的处理,是重复执行部分,所以这段程序的设计非常关键,应充分考虑程序的效率。l (3 3)循环控制部分)循环控制部分l 为下一次数据处理而修改计数器和地址指针,并判断循环是否结束。l (4 4)结束部分)结束部分l 分析、处理或存放结果

22、。循环结构补充l 循环结构循环结构l 循环结构表示程序反复执行某个或某些操作,直到某条件为假(或为真)时才可终止循环。在循环结构中最主要的是:什么情况下执行循环?哪些操作需要循环执行?循环结构的基本形式有两种:当型循环和直到型循环。 l 当型循环当型循环:表示先判断条件,当满足给定的条件时执行循环体,并且在循环终端处流程自动返回到循环入口;如果条件不满足,则退出循环体直接到达流程出口处。因为是“当条件满足时执行循环”,即先判断后执行,所以称为当型循环。 l 直到型循环直到型循环:表示从结构入口处直接执行循环体,在循环终端处判断条件,如果条件不满足,返回入口处继续执行循环体,直到条件为真时再退出

23、循环到达流程出口处,是先执行后判断。因为是直到条件为真时为止,所以称为直到型循环。l 4.4.2 4.4.2 单重循环程序设计单重循环程序设计l 1.1.循环次数已知的循环程序循环次数已知的循环程序l 【例4.8】 从60H单元开始的连续单元中有l 一个无符号数的数据块,其长度在5FH中,编程l 求数据块的最大值,存入5EH单元。l 分析分析: :l 假设累加器A中有最大值00H,然后逐个取出l 数据块中的数据与之进行比较。l 如果当前数据大于累加器A的数据,则把数l 据块中的数据送给累加器A; 图图4-4 4-4 例例4.84.8程序流程图程序流程图 l 否则累加器A的内容不变,即保证累加器

24、A中存放的是每次比较出的较大数。l 如此循环,直至比较完最后一个数。累加器A中存放的便是所有数据中的最大值。程序流程如图4-4所示。l 源程序源程序: :l ORG 1000Hl CLR Al MOV B,5FHl MOV R0,#60H l LOOP: CLR Cl SUBB A,R0l JC L1l ADD A,R0l SJMP L2l L1: XCH A,R0l L2: INC R0l DJNZ B,LOOPl MOV 5EH,A l SJMP l END l 【例4.9】 编程确定一个数据块中负元素的个数。假设数据块的长度存放在内部RAM51H单元,数据块从内部RAM52H单元开始存放

25、,要求将负元素的个数存放在50H单元中。l 分析分析: : l 判断有符号数值的正负可以通过判断该数值的最高位来完成。l 如果最高位为1,则该数为负;否则该数为正。l 另外,统计负数个数,需要在程序初始化时将存l 放负元素个数的单元清零,以便在循环中进行个l 数累计,流程图如图4-5所示。l 源程序源程序: :l ORG 1000Hl MOV R0,#52H l MOV R2,#00Hl MOV B,51H l LOOP: MOV A,R0l JNB Acc.7,NEXT l INC R2图图4-5 4-5 例例4.94.9程序流程图程序流程图 l NEXT: INC R0l DJNZ B,L

26、OOP l MOV 50H,R2l SJMP l ENDl 2.2.循环次数未知的循环程序循环次数未知的循环程序l 【例4.10】 从 60H单元开始的连续单元中有一个无符号数0FH,编程求该数据的地址并存入5FH单元。l 分析分析: :l 先取出60H单元的数据与立即数0FH比较。l 如果不相等,再取下一个单元数据进行比较;l 如此循环,直到两个数据相等时,记录数据地址,退出循环。 l 判断两数是否相等有多种方法,在此我们选择两数异或指令。如果两数相等,则异或结果为0; 否则结果为1。程序流程图如图4-6所示。l 源程序源程序: :l ORG 1000Hl MOV R0,#5FH l LOO

27、P: INC R0l MOV A,R0l XRL A,#0FH l JZ NEXT l SJMP LOOPl NEXT: MOV 5FH,R0l SJMP l END 图图4-6 4-6 例例4.104.10程序流程图程序流程图 l 【例4.11】 用 80C51单片机的 P1口作输出,经驱动电路接 8只发光二极管,如图4-7所示。l 当输出位是“1”时,发光二极管被点亮; 输出位是“0”时二极管熄灭。l 编制单灯循环亮程序,即按l P1.0P1.1P1.2P1.6P1.7P1.0P1.1顺序,每次只有一只二极管亮。l 分析分析: :l 要使每个灯轮流被点亮,必须在P1口的各l 位按指定顺序轮

28、流输出 “1”,其余位输出0,可l 以采用循环移位指令完成。l 8个灯一轮的渐次点亮由循环体完成,然l 后利用无条件转移指令反复执行循环体。图图4-7 4-7 单灯循环电路图单灯循环电路图 l 程序流程图如图4-8所示。l 源程序源程序: :l ORG 1000Hl MOV A,#01H l LOOP: MOV P1,Al RL A ;累加器A左循环一位l LCALL DELAY ;调用延时子程序l SJMP LOOPl DELAY: MOV R2,#0FAH ;延时子程序l L1: MOV R3,#0FAHl L2: DJNZ R3,L2l DJNZ R2,L1l END 图图4-8 4-8

29、 例例4.114.11程序流程图程序流程图 l 4.4.3 4.4.3 多重循环程序设计多重循环程序设计l 多重循环又称为循环嵌套,是指一个循环程序的循环体中包含另一个循环程序。理论上对循环嵌套的层数没有明确的规定,但由于受硬件资源的限制,实际可嵌套层数不能太多。l 需要注意的是循环嵌套只允许一个循环程序完全包含另一个循环程序,不允许两个循环程序之间相互交叉嵌套。l 【例4.12】 编程将内部RAM70H79H中10个无符号数按由大到小的顺序排序。排序后仍存放在70H79H中。l 分析分析: :l 排序方法有多种,本例题采用“冒泡”法完成。l 具体思路是具体思路是: : 从低地址到高地址将相邻

30、两个单元进行比较。l 若低地址的内容大于相邻高地址单元的内容,则保持原状; 若低地址的内容小于相邻高地址单元的内容,则两单元内容互换。 l 图4-9给出设标志位冒泡法排序流程图。l 设标志位冒泡法排序源程序: l ORG 1000Hl LOOP: MOV R0,#70Hl MOV B,#09H l CLR 10Hl LOOP1: MOV A,R0l MOV 20H,A l INC R0l MOV 21H,R0l CJNE A,21H,LOOP2 图图4-9 4-9 冒泡法排序流程图冒泡法排序流程图 l LOOP2: JNC LOOP3l MOV A,R0l MOV R0,20H l DEC R

31、0l MOV R0,A l INC R0l SETB 10Hl LOOP3: DJNZ B,LOOP1l JB 10H,LOOP l SJMP l ENDl 【例4.13】 编写软件延时80ms程序。l 分析分析: : 设单片机的时钟频率为6MHz,则其机器周期为2s。l 由于DJNZ指令需要2个机器周期,因此它的指令周期即指令执行时间为4s。MOV和NOP指令分别为2个机器周期和1个机器周期。 l 为了延时80ms,我们可以通过控制循环次数的方法来解决。l 执行两条 NOP指令和1条 DJNZ指令的时间是 8s,循环250次用时2000s,即程序中第2条到第5条指令完成的功能。l 若想达到延

32、时80ms的目的,只要再使用一个循环40次的DJNZ指令即可。精确计算程序运行时间的公式为:l 2+2+(1+1+2)*250+2*40*2s=80324s l 如果单片机的时钟频率为12MHz,则其机器周期为1s。为了延时80ms,我们只要把循环次数由40修改为80就可以了。l 延时程序:l MOV 20H,#40 ;2机器周期指令l BBB1: MOV 21H,#250 l BBB2: NOP ;1机器周期指令l NOP l DJNZ 21H,BBB2 ;2机器周期指令l DJNZ 20H,BBB1l SJMP 循环嵌套问题外循环外循环中循环中循环内循环内循环外循环外循环内循环内循环外循环

33、外循环内循环内循环内循环内循环(a)嵌套正确)嵌套正确(b)嵌套正确)嵌套正确(c)交叉不正确)交叉不正确4.5 4.5 子程序设计子程序设计l 在程序设计过程中,经常会遇到在不同的程序中或同一个程序的不同地方执行同一个操作的情况,例如软件延时、代码转换等。l 为了缩短程序设计周期及程序长度,可以将这些程序段从源程序中分离出来单独组成一个程序模块,我们称之为子程序。l 在需要使用这些模块的地方可以 “调用子程序”。l 调用子程序的程序被称为主程序。主程序对子程序的调用是通过ACALL或LCALL指令完成的。一个主程序可以多次调用同一个子程序,也可以调用多个子程序。子程序也可调用其他子程序(称为

34、子程序嵌套). 所谓调用子程序,暂时中断主程序的执行,而转到子程序的入口地址去执行子程序,子程序执行完后返回主程序继续执行。l 子程序的形式与要求:子程序的形式与要求:1)名称、地址、功用()名称、地址、功用(标明子程序的入口地址或名称,以方便调用);标明子程序的入口地址或名称,以方便调用);2)指出入口与出口参数,以正确进行)指出入口与出口参数,以正确进行参数传递参数传递; 参数传递参数传递 在调用子程序前,主程序应先把有关参数(即入口参数)放在调用子程序前,主程序应先把有关参数(即入口参数)放到某些约定的位置,子程序在运行结束返回前,也应该把运算结果(出口参到某些约定的位置,子程序在运行结

35、束返回前,也应该把运算结果(出口参数)送到约定的位置数)送到约定的位置/ 单元。单元。常采常采用工作寄存器或累加器、地址指针寄存器或堆栈。用工作寄存器或累加器、地址指针寄存器或堆栈。3 3)注意保护现场)注意保护现场5 5)子程序的末尾用)子程序的末尾用RET返回指令结束;返回指令结束; 有关指令:有关指令:1、进栈操作、进栈操作 PUSH direct;2、出栈操纵、出栈操纵 POP direct;3 3、子程序的调用、子程序的调用1 1)绝对调用指令)绝对调用指令ACALL ACALL addrlladdrll;断点入栈;断点入栈-PC-PC当前值,当前值, SP SP (SPSP)+2+

36、2 PC11 PC111515保持不变保持不变,addr11-PC,addr11-PC底底1111位位2)长调用指令)长调用指令 LCALL addr16;(;(PC)+3-PC , 断点入栈断点入栈 转地址转地址addr16执行执行4. 子程序返回指令子程序返回指令 RET ;PC158 (SP),),SPSP-1 ;PC70 (SP),),SPSP-1使用子程序的优点 不必重复书写同样的程序,提高编程效率 程序的逻辑结构简单,便于阅读 缩短了源程序和目标程序的长度,节省了存储器空间 使程序模块化、通用化、便于交流共享资源 便于按某种功能调试上页下页回目录l l 4.5.1 4.5.1 关于

37、子程序的几点说明关于子程序的几点说明l 1.每个子程序的起始指令前必须定义一个标号,作为该子程序的名称,以便主程序正确的调用它。子程序通常以 RET指令结束,以便正确的返回主程序。l 2.子程序应具有通用性。一般,子程序的操作对象通常采用寄存器或寄存器间接寻址等寻址方式,尽量避免采用立即寻址。l 3.子程序应保证放在存储器的任何空间都能正确运行,即具有浮动性。例如,子程序中应使用相对转移指令,避免使用绝对转移或长转移。l 4.进入子程序时需要把在主程序中使用并在子程序中也要使用的寄存器进行保存,并在返回主程序之前恢复原来状态。l 5.子程序的调用和返回指令,以及保护现场等操作均需用到堆栈,因此

38、在程序初始化时应设置堆栈指针SP,开辟堆栈保护区。l 6.设计子程序时应首先确定子程序名称,确定子程序的入口参数和出口参数,确定子程序需要使用的寄存器和存储单元,确定子程序的算法,再编写源程序。 4.5.2 4.5.2 子程序及其嵌套调用子程序及其嵌套调用l 子程序的嵌套调用是指在一个子程序中又调用另一个子程序。l 对于MCS-51单片机,子程序嵌套次数一般不受限制。l 子程序的嵌套调用过程如图4-10所示。l 当主程序执行到LCALL SB01指令时,它会将断点地址M02压入堆栈,并转去执行SB01子程序。 一、子程序嵌套调用l 在SB01子程序中执行到LCALL SB02指令时,它会将断点

39、地址SB12压入堆栈,并转去执行SB02子程序。l SB02子程序执行到最后的RET指令时,它会从堆栈中取出断点地址SB12送给指令计数器PC,程序返回SB01子程序。l SB01子程序执行到最后的RET指令时,它会从堆栈中取出断点地址M02送给指令计数器PC,程序返回主程序,继续执行。图图4-10 4-10 子程序嵌套示意图子程序嵌套示意图 二、调用子程序的要点 子程序开头的标号段必须有一个标志,该标志既是 子程序的名字又是其入口地址,以便主程序调用。在主程序中利用指令ACALL或LCALL可转入子程序。 该指令具有保护断点的功能例如:调用延时子程序LCALL(ACALL) DELY 子程序

40、结尾必须使用一条从子程序返回指令RET, 它具有恢复断点的功能LCALL addr16; PC addr16 转向子程序;(PC) (PC)+3;SP (SP)+1,(SP) PC70;SP (SP)+1,(SP) PC158;在调用子程序之前,保护断点地址RET; PC158 (SP) ,(SP) (SP) -1; PC70 (SP) ,(SP) (SP) -1主程序CALL断点子程序RET1、子程序的结构上页下页回目录2、参数传递子程序入口条件: 在调用一个子程序时,主程序应先把有关参数放到某些约定的位置,子程序运行时,可以从约定的位置得到有关参数。子程序出口条件:子程序结束前,也应把处理

41、结果送到约定位置参数传递的方法: 子程序无须传递参数 这类子程序中所需要的参数是子程序赋予,不需要主程序给出上页下页回目录2、参数传递子程序入口条件: 在调用一个子程序时,主程序应先把有关参数放到某些约定的位置,子程序运行时,可以从约定的位置得到有关参数。子程序出口条件:子程序结束前,也应把处理结果送到约定位置参数传递的方法: 子程序无须传递参数 这类子程序中所需要的参数是子程序赋予,不需要主程序给出上页下页回目录主程序:.LCALL DELY.子程序:不需主程序提供入口参数,从子程序开始到子程序返回,大约为20ms例4-23 调用延时子程序DELYDELY: MOV R7, #100DLY0

42、: MOV R6, #98NOPDLY1: DJNZ R6, DLY1DJNZ R7, DLY0RET子程序开始的标号子程序返回指令调用子程序上页下页回目录982=196s1s1s设:主频为12MHZ2s(196+2+2) 100 +3 =20003s = 20.003ms2s1s+3意味着每个机器周期为1s 用累加器和工作寄存器传递参数入口参数:放在累加器A和工作寄存器中R0 R7中出口参数:放在累加器A和工作寄存器中R0 R7中例 双字节求补子程序CPLD解:采用“变反加1”的方法,十六位数变反加1, 不仅低字节要加1,高字节要加低字节的进位。 故采用ADD指令,不采用INC指令。 INC

43、指令不影响CY位上页下页回目录入口参数:(R7R6)=16位数出口参数:(R7R6)=求补后的16位数 CPLD: MOV A,R6CPL A ADD A,#1 MOV R6,A MOV A,R7 CPL A ADDC A,#0 MOV R7,A RET上页下页回目录Cy+ CyR7R6R7R6用累加器用累加器A A或工作寄存器或工作寄存器RnRn传递参数传递参数例:把例:把A中一个十六进制数的中一个十六进制数的ASC字符转换为一位十六进制数。字符转换为一位十六进制数。主程序部分:主程序部分:START:; MOV A,#34H;设置入口参数于;设置入口参数于A中中子程序:子程序:ASCH:

44、CLRC SUBB A,#30H CJNE A,#10,$+3 ;$+3为下条指令的首址为下条指令的首址 JC NEXT ;(A)10,转,转NEXT SUBB A,#07H ;(A)0AH,则再减,则再减07H(共减(共减37H)NEXT: NOP RET R0 R0 R0 通过操作数地址传递参数入口参数:(R0)=求补数低字节指针,(R7)=n-1出口参数:(R0)=求补后高字节指针例4-25 n字节求补子程序CPLNCPLN: MOV A,R0CPL AADD A,#1MOV R0,AMOV A,R0CPL AADDC A,#0MOV R0,ARETNEXT: INC R0DJNZ R7

45、, NEXT上页下页回目录内部RAM字节1字节2字节3字节n R0 R0 通过堆栈传递参数例4-26 在HEX单元存放两个十六进制数,将它们分别 转换成ASCII码并存入ASC和ASC+1单元解: 由于要进行两次转换,故可调用查表子程序完成上页下页回目录 HEX SPSPSPSP .PUSH HEX LCALL HASCPOP ASCMOV A, HEXSWAP APUSH ACCLCALL HASCPOP ASC+1.MOVC A,A+PCHASC: DEC SPDEC SPPOP ACCANL A,#0FHADD A,#5PUSH ACCINC SPINC SPRETASCTAB: DB

46、0 1 2 7 DB 8 9 A F60H61H62H63H64H HEX *PCL *PCHPC断点SP0000 HEXL ASCAASCSPSPSPSP主程序子程序上页下页回目录 5). 5). 用寄存器作指针来传递参数用寄存器作指针来传递参数 例例2:将片内一组区域清零子程序如下:将片内一组区域清零子程序如下: ZOER: CLR A LOOP: MOV R0, A; INC R0 DJNZ R2 ,LOOP; RET 分析入口参数分析入口参数? 出口参数出口参数? 编程完成编程完成20H28H和和30H39H两段区域清零两段区域清零. 3、现场保护 如果子程序使用的寄存器与主程序使用的

47、寄存器 有冲突,在转入子程序前,特别是进行中断服务 子程序时,要进行现场保护。主程序使用的内部 RAM 内容,各工作寄存器内容, 累加器 A 和 DPTR 以及 PSW 等寄存器内容。将要保护的单元压入堆栈。上页下页回目录中断保护时:还可以用 RS1 RS0 来选择其他通用寄存器组, 以便保护主程序现场。R0 R7例如:十翻二子程序的现场保护BCDCB: PUSH ACCPUSH PSWPUSH DPLPUSH DPH.POP DPHPOP DPLPOP PSWPOP ACCRET推入与弹出应按照“先进后出”,或“后进先出”的顺序; 保护现场; 十翻二; 恢复现场;上页下页回目录三、子程序的调

48、用及嵌套1、子程序的调用 将内部RAM41H43H中内容左移4位,移出部分送 40H单元 由于多字节移位是程序设计中经常用到的,有一定的普遍性。为了程序设计的灵活性,我们编一个“n字节 左移一位”子程序,反复调用4次即为n字节左移4位。(R0)指向内部RAM的操作数地址,高字节在先(R4)= 字节长度(R0)指向内部RAM的结果地址,低字节在先上页下页回目录使用 LCALL 或 ACALL 指令主程序:RLC4: MOV R7, #4MOV A, R0ANL A, #0FHMOV R0, ARET;为进入子程序设置入口条件;R7为左移位数计数器;转子程序;未完,继续;存结果;屏蔽高四位结果上页

49、下页回目录 子程序:RLC1: CLR CMOV A, R0RLC AMOV R0, A RETR0CYA40H41H42H43HA37A30A27A20A17A10A07A00A37 A3000A37A36A36 0R0A26 A37A16 A27A06 A27上页下页回目录2、子程序的嵌套 子程序中可调用其他子程序上页下页回目录 子程序与主程序的概念是相对的,在一个子程序中又可调用其它子程序,这就是子程序的多重嵌套。多重嵌套的过程SPSP *PC0L *PC0H *PC1L*PC1H5FH60H61H62H63H64H65H*PC2H*PC2L 断点入栈断点入栈SPSP断点入栈SPSPSP

50、SP弹出断点弹出断点SPSP弹出断点SPSP上页下页回目录栈 底堆栈的设置是十分重要的l 4.6.1 4.6.1 查表程序设计查表程序设计l 查表程序是指适当的组织一些表格,跟控制程序一起事先输入到单片机的程序存储器中。使用查表指令迅速获取结果数据。该类程序主要用于代码转换、算术运算等。l 说明说明: :l 在例4.16和例4.17中分别使用了指令MOVC A,A+PC和指令MOVC A,A+DPTR实现查表。l 第一条指令是以 PC作为基址寄存器,A中存放偏移量(偏移量为当前的PC值到表格首地址之间的距离),两者的和为结果所在程序存储单元的地址。 4.6 4.6 查表及散转程序设计查表及散转

51、程序设计l 该指令执行后PC仍指向下一条指令。l 用用PCPC的内容作为基地址来查表,通常分为三步的内容作为基地址来查表,通常分为三步: :l (1)将所查表格的项数(即在表格中的位置)送入累加器A中;l (2)计算偏移量data,并在MOVC A,A+PC指令前加上指令ADD A,#data。计算公式如下:l 偏移量=表格首地址-(MOVC指令所在的地址+1)l (3)执行查表指令MOVC A,A+PC,结果存入累加器A。l 第二条指令是以 DPTR作为基址寄存器,A与DPTR两者的和为结果所在程序存储单元的地址。l 用用DPTRDPTR内容作为基地址来查表,通常也分为三步内容作为基地址来查

52、表,通常也分为三步: :l (1)将表格的项数(即在表格中的位置)送入累加器A中;l (2)将表格的首地址送入DPTR中;l (3)执行查表指令MOVC A,A+DPTR,结果存入累加器A。 l 4.6.2 4.6.2 散转程序设计散转程序设计l 在设计单片机应用程序时,经常遇到根据不同的输入或运算结果决定程序流向的问题。这就是散转程序,实际就是一种多分支程序。l 散转程序也需要一个表,但表中所列的不是普通数据,而是某些功能程序的入口地址、偏移量或转向这些功能程序的转移指令。l 程序的散转功能,主要依靠间接转移指令JMPA+DPTR完成。l 1.1.利用转移指令表进行散转利用转移指令表进行散转

53、l 假设有一个标志单元,它的可能取值为 0,1,2的自然数,每个值对应一个处理程序。我们可以利用转移指令表,使程序根据标志单元的值转向各自的处理程序。l 选择与处理程序相同数目的无条件转移指令,由这些指令组成一张指令表,且第1条转移指令转向 “0” 标志所对应的处理程序,第2条转移指令转向“1”标志所对应的处理程序,依此类推。 l 然后把指令表的起始地址和标志单元的值分别送数据指针DPTR和累加器A中,最后使用散转指令完成。l 2.2.利用转向地址表进行散转利用转向地址表进行散转l 当转向范围比较大时,可直接使用转向地址表法,即把每个处理程序的入口地址直接放到地址表内。l 用查表指令从表中查找

54、与变量值对应的处理程序的入口地址,再通过间接转移指令,使程序转向该地址指向的功能程序。l 3.3.利用利用 “RETRET” 指令进行散转指令进行散转l 此方法与转向地址表法基本相同。l 两者的惟一区别是:l 转向地址表法,将表中取出功能程序的入口地址直接送给数据指针; l 而返回指令法,则把入口地址压入堆栈进行保存,并随后便执行一条RET指令,使程序转向功能程序。l 当程序出现多重分支时,常用无条件间接转移指令实现散转当程序出现多重分支时,常用无条件间接转移指令实现散转。JMP A+DPTR利用散转指令JMP A+DPTR可转向任一处理程序间接转移指令(又称散转指令)间接转移指令(又称散转指

55、令) JMP A+DPTR ;PC (A) + (DPTR 目的地址由指针目的地址由指针DPTR和变址和变址A的内容之和形成,的内容之和形成,范围达范围达 64K 。散转程序设计散转程序设计根据根据R0中的内容,转向各个子程序。中的内容,转向各个子程序。 R00,转入,转入Pr0 R01,转入,转入Pr1 R02,转入,转入Pr2 R0n,转入,转入Prn ORG 0030HJUMP1: MOV DPTR, #TAB CLR A MOV A, R0 ADD A, R0 JMP A+DPTR ORG 0100HTAB: AJMP Prog0 ;(2个字节个字节) AJMP Prog1 ;(2个字

56、节个字节) AJMP Prog2 ;(2个字节个字节) Prog0: Prog1: Prog2: 处理 0处理 1处理 nR0= ?01n 思考:为什么A(R0)中的内容要乘以2? 例 1 根据工作寄存器R0 内容的不同, 使程序转入相应的分支。程序如下: LP0: MOV DPTR, TAB ; 取表头地址 MOV A, R0 ADD A, R0 ; R0内容乘以2 JNC LP1 ; 无进位转移,当(A)80H(128D)时有 进位,当(A)80H(128D)时无进位,进位 应加到高位DPH中. INC DPH ; 加进位位LP1: JMP A+DPTR; 跳至散转表中相应位置 TAB:

57、AJMP PR0 ;占2个字节 AJMP PR1 AJMP PRN PRO: 例2: MOV DPTR, TAB MOV A, R0 MOV B, 03H ; 长跳转指令占 3 个字节 MUL AB XCH A, B ADD A, DPH MOV DPH, A XCH A, B JMP A+DPTR; 跳至散转表中相应的位置 TAB: LJMP PR0 ; 跳至不同的分支 LJMP PR1 ;占3个字节 LJMP PRN PR0: PR1: 4.7 4.7 实用程序举例实用程序举例l 设计单片机的应用程序,不仅要掌握几种基本结构程序的设计步骤、设计方法,还要熟悉一些常用子程序的基本功能和使用方

58、法。l 典型的子程序:u 代码转换类子程序u 运算类子程序u 数据块处理和数据比较类子程序u 延时子程序例例1 将单字节16进制整数转换成单字节BCD码整数的子程序。入口条件:待转换的单字节16进制整数在累加器A中。出口状态:转换后的BCD码整数(十位和个位)仍在累加器A中,百位在R3中。CHBCD: PUSH PSW ;保护现场 PUSH B MOV B, #100 DIV AB ;(A)BCD码的百位 MOV R3, A ; (R3)BCD码的百位 MOV A, #10 ;余数继续分离十位和个位 XCH A, B DIV AB ;(A)BCD码的十位 SWAP A ORL A, B ;将十

59、位和个位拼装成BCD码 POP B ;恢复现场 POP PSW RET4.7.1 4.7.1 代码转换类子程序代码转换类子程序例例3 将4位二进制数转换成ASCII码。入口条件:待转换的4位二进制数存入R2中。出口状态:转换后的ASCII码存R2中。ASCB: PUSH PSW ;保护现场 PUSH A MOV A, R2 ANL A, #0FH ;取出四位二进制数 PUSH A ;存入堆栈 CLR C SUBB A, #0AH POP A ;弹回A中 JC LOOP ;该数小于10,则转LOOP ADD A, #07H ;否则加07HLOOP: ADD A, #30H ;加30H MOV R

60、2, A ;转换后的ASCII码存入R2 POP A ;恢复现场 POP PSW RETnZHENFA: MOV A,R2n MOV B,R4n MUL ABn MOV R5,An MOV R6,Bn MOV A,R2n MOV B,R3n MUL ABn ADD A,R6n MOV R6,An MOV A,Bn ADDC A,#00Hn MOV R7,An RET 被乘数:被乘数:R3、R4 (16位)位) 乘数:乘数: R2 (8位)位) 乘积:乘积: R5、R6、R7算法:算法: R3 R4 R2 ( R4R2 )H ( R4R2)L +( R3R2 )H ( R3R2 )L R7 R6

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论