1 / 70

本章学习目标 : 了解汇编语言的特点,明确程序设计的基本思路 熟悉汇编语言的语句结构,能正确书写汇编语言程序 理解伪指令的功能,能正确使用 80C51 常用伪指令 熟悉几种基本的程序结构

第 3 章 单片机的编程技术. 本章学习目标 : 了解汇编语言的特点,明确程序设计的基本思路 熟悉汇编语言的语句结构,能正确书写汇编语言程序 理解伪指令的功能,能正确使用 80C51 常用伪指令 熟悉几种基本的程序结构 能读懂教材中的程序实例,学会编写同等难度的应用程序. 3.1 程序设计的方法和技巧. 3.1.1 程序设计流程. 单片机与一般集成电路的区别在于可编程应用,程序是单片机应用系统的灵魂。. 由于汇编语言是面向机器的语言,因此对单片机系统进行程序设计时必须考虑硬件资源的配置。当硬件系统设计完成后,可从以下几方面进行程序设计:.

Download Presentation

本章学习目标 : 了解汇编语言的特点,明确程序设计的基本思路 熟悉汇编语言的语句结构,能正确书写汇编语言程序 理解伪指令的功能,能正确使用 80C51 常用伪指令 熟悉几种基本的程序结构

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第3章 单片机的编程技术 • 本章学习目标: • 了解汇编语言的特点,明确程序设计的基本思路 • 熟悉汇编语言的语句结构,能正确书写汇编语言程序 • 理解伪指令的功能,能正确使用80C51常用伪指令 • 熟悉几种基本的程序结构 • 能读懂教材中的程序实例,学会编写同等难度的应用程序

  2. 3.1 程序设计的方法和技巧 3.1.1程序设计流程 单片机与一般集成电路的区别在于可编程应用,程序是单片机应用系统的灵魂。 由于汇编语言是面向机器的语言,因此对单片机系统进行程序设计时必须考虑硬件资源的配置。当硬件系统设计完成后,可从以下几方面进行程序设计:

  3. 1. 分析问题——针对现有条件,明确在程序设计时应该“做什么” • 2. 确定算法——解决“怎样做”的问题 • 3. 绘制程序流程图——用图形的方法描绘解决问题的思路 (常用的程序流程图符号如图3-1所示) • 4. 分配内存单元——确定程序和数据区的起始地址 • 5. 编写源程序——用指令的形式将程序流程图实现出来 • 6. 汇编——用开发机或仿真器将源程序转换成机器码,便于单片机识别 • 7. 在线仿真调试——查错、改错,对程序进行优化。

  4. 常用的程序流程图符号如图3-1所示。 图3-1 常用的程序流程图符号

  5. 3.1.2 汇编语言编程技巧 • 尽量采用模块化程序设计方法 ;这种设计方法是把一个完整的程序分成若干个功能相对独立的、较小的程序模块,对各个程序模块分别进行设计、编制程序和调试,最后把各个调试好的程序模块装配起来进行联调,最终成为一个有实用价值的程序。 • 模块化程序设计的优点是:对单个程序模块设计和调试比较方便、容易完成,一个模块可以被多个任务共用。 • 尽量采用循环结构和子程序结构;采用循环结构和子程序结构,可以使程序的总容量减小,提高程序的效率,节省内存。

  6. 尽量少用无条件转移指令;少用无条件转移指令,可以保证程序的条理更加清晰,从而减少错误发生。尽量少用无条件转移指令;少用无条件转移指令,可以保证程序的条理更加清晰,从而减少错误发生。 • 充分利用累加器;累加器是主程序和子程序之间信息传递的桥梁,利用累加器传递入口参数或返回参数比较方便。这时,一般不要把累加器内容压入堆栈。 • 对于通用子程序要保护现场;由于子程序的通用性,除了保护子程序入口参数的寄存器内容外,还要对子程序中用到的其它寄存器内容一并入栈保护。 • 对于中断处理,还要保护程序状态字在中断处理程序中,既要保护处理程序中用到的寄存器内容,还要保护程序状态字PSW。否则,当中断服务程序执行结束返回主程序时,整个程序的执行可能会被打乱。

  7. 3.1.3汇编语言的语句格式 80C51单片机汇编语言的语句行由4个字段组成,汇编程序能对这种格式正确地进行识别。这4个字段的格式为: [标号:] 操作码 [操作数][;注释] 括号内的部分可根据实际情况取舍,各字段之间要用分隔符分隔。可用作分隔符的符号有冒号、空格、逗号、分号等。如: MAIN:MOV A,#68H ;A←68H

  8. 1.标号 • 标号是指令的符号地址。有了标号,程序中的其它语句才能很方便地访问该语句。有关标号的规定为: • 标号要由1~8个ASCII码字符组成,但必须以字母开 头,其余字符可以是字母、数字或其它特定字符。 • 不能使用汇编语言已经定义了的符号作为标号,如指令 助记符MOV、伪指令记忆符END以及寄存器的符号名 称R1等。 • 标号后边必须跟冒号。 • 同一标号在一个程序中只能定义一次,不能重复定义。

  9. 2.操作码 • 操作码用于规定语句执行的操作。它用指令助记符或伪指令助记符表示,是汇编语句中唯一不能空缺的部分。 • 3.操作数 • 操作数用于给指令的操作提供数据或地址。在一条语句中,可能没有操作数,也可能只有1个操作数,还可能同时包含2~3个操作数。各操作数之间要以逗号分隔。操作数一般以下面几种形式出现: • 常数 • 工作寄存器名 • 特殊功能寄存器名

  10. 标号名 • 符号“$”,表示程序计数器PC的当前值。如:SJMP $ • 表达式 • 4.注释 • 注释不属于语句的功能部分,它只是对语句的解释说明,只要用“;”开头,就表明以下为注释内容。使用注释可使程序文件的编制显得更加清楚,便于编程人员的阅读和维护。注释的长度不限,一行不够可以换行接着书写,但换行后仍要以“;”开头。

  11. 3. 2 源程序的编制 用户根据系统要求用汇编语言或高级语言编好的程序,叫源程序。 3.2.1 源程序的编辑和汇编 由于通用微型计算机的普及,现在单片机应用系统的程序设计都借助于通用微型计算机。全过程可概括为“机器编辑→交叉汇编→串行传送”三个部骤,如图3-2所示。

  12. 1. 编辑 将源程序输入计算机并进行修改的过程就是编辑。编辑工作一般在通用微型计算机上利用各种编辑软件完成,故又称其为机器编辑。编辑完成后,生成一个由汇编指令和伪指令共同组成的ASCII码文件,其扩展名为“.ASM”。 图3-2 单片机汇编语言程序的生成过程

  13. 2. 汇编 计算机只能识别机器语言,但程序编制人员通常以汇编语言或高级语言编制源程序。这样,要让计算机能听从程序编制人员的指挥,就必须要将汇编语言或高级语言转换成机器语言,供计算机识别,这个过程称为汇编(或编译)。 汇编工作常由汇编软件来完成。汇编软件通常具有指令的错误识别与提示能力,为编程者迅速查找源程序中的错误提供了方便。在汇编过程中,我们只能发现源程序中的语法错误和一般性的逻辑错误,但不能检查程序结构上的错误。如果有错误,汇编软件会报告,指出错误位置及错误类型。程序错误被纠正后,要重新进行编译调试,直至程序汇编无误为止。 现在常用的汇编方法是交叉汇编,即用PC机中的汇编程序去汇编80C51单片机中的源程序。汇编后生成的机器码称为目标程序,扩展名为“.OBJ”。该目标程序可通过PC机的串行通信接口直接传送到开发系统的RAM中。

  14. 3.2.2 伪指令 在前面的课题与实训环节中用到的ORG和END命令就是典型的伪指令,它们是为下一步的汇编工作提供起始地址和结束地址的。 我们知道,汇编语言程序的机器汇编是由计算机自动完成的,因此在源程序中应该有向汇编程序发出的命令。 这种在源程序中出现,通知汇编程序应该如何完成汇编工作的指令,就是伪指令。 下面介绍80C51单片机常用的伪指令。

  15. 1. ORG(Origin)汇编起始命令 格式为:ORG 16位地址或标号 该命令总是出现在源程序的开始位置。用来规定目标程序(即此命令后面的程序或数据块)的起始地址。ORG后面通常是16位地址,也可以是已定义的标号地址或表达式。如ORG 1000H。 在程序中如果不用ORG规定起始地址,则汇编得到的目标程序将从0000H开始存放。在一个源程序中,ORG指令可以多次使用,但要求地址值要由小到大依序排列,且不能出现空间上的重叠。 2. END 汇编结束命令 格式为:END 该命令用于中止源程序的汇编工作。END是汇编语言源程序的结束标志,因此在整个源程序中只能有一条END指令,且位于程序的最后。如果END命令出现在源程序中间,对其后面的源程序,计算机将不予汇编。

  16. 3. EQU(Equate)等值命令 格式为: 标号名 EQU 表达式 该命令用来给标号赋值。赋值以后,其标号值在整个程序中有效。例如: DAT EQU 30H 4. DB (Define Byte) 定义字节命令 格式为: [标号:] DB 字节数据表 该命令用于从标号指定的地址开始,连续存放字节数据表,常与查表指令MOVC配合使用。其中字节数据表可以是一个或多个字节数据、字符串或表达式。例如: DB “hello”

  17. 5. DW (Define Word)定义字命令 格式为: [标号:] DW 字数据表 该命令用于从标号指定的地址开始,连续存放16位字数据表。该数据表在程序存储器中存放的格式为:高8位存放在低地址单元,低8位存放在高地址单元。例如: ORG 1000H TABLE: DW 1234H, 66H … … 汇编后,(1000H)=12H, (1001H)=34H, (1002H)=00H, (1003H)=66H。 DB和DW定义的数据表,数的个数不能超过80个。如遇数目较多时,可以使用多个定义命令。在80C51程序设计中,常用DB来定义数据,DW来定义地址。

  18. 6. BIT 定义位命令 格式为:标号名 BIT 位地址 该命令用来将位地址赋值给指定的标号名。例如: KAIGUAN BIT P1.0 将P1.0的位地址赋值给标号KAIGUAN,在后面编程时就可以用KAIGUAN来代替P1.0。 7. DS (Define Storage)定义空间命令 格式为: [标号:] DS 表达式 该命令用于从指定单元开始,预留一定数目的字节单元作存储区,供程序运行使用。

  19. 3.3 基本程序结构 程序结构通常分为三种形式:顺序结构、分支结构、循环结构。形式如图3-3所示。 图3-3 三种程序结构

  20. 3.3.1顺序程序 顺序程序是最简单的程序结构,它既无分支,又无循环,在执行时单片机是按程序中指令的顺序逐条进行的。编程注意事项: 正确选择程序存放的地址:通常主程序起始地址在0100H之后,但由于80C51单片机上电后从0000H开始执行,所以必须在0000H设一条转移指令,转至主程序首址。 要注意检查所用指令是否合法,在没有把握的情况下,最好查一下指令表。如,下面的指令是非法的:MOVX 2002H,2000H 为使程序运行结束时不至于跑飞,可在程序最后加一条暂停指令,如:SJMP $。

  21. 例1 将地址为2000H、2001H、2002H的片外数据存储单元的内容分别传送到2002H、2003H和2004H单元中去。 ORG 0000H AJMP 0100H ;转到主程序起始地址 ORG 0100H MOV DPTR, #2002H ;最后一个数据的起始地址 MOVX A,@DPTR ;2002H单元的数据送A MOV DPTR, #2004H ;最后一个数据的目的地址 MOVX @DPTR,A ;2002H单元的数据送2004H单元 MOV DPTR, #2001H ;中间数据的起始地址

  22. MOVX A,@DPTR ;2001H单元的数据送A MOV DPTR, #2003H ;中间数据的目的地址 MOVX @DPTR,A ;2001H单元的数据送2003H单元 MOV DPTR, #2000H ;第一个数据的起始地址 MOVX A,@DPTR ;2000H单元的数据送A MOV DPTR, #2002H ;第一个数据的目的地址 MOVX @DPTR,A ;2000H单元的数据送2002H单元 SJMP $ END <想一想> 还可以怎样修改?

  23. 2.查表程序 例2 已知30H单元存有8位二进制数的BCD码,请将其转换为共阴显示的字形码,然后从P1 口输出。 设这些字形码存放在标号为TABLE 的存储单元。程序如下: ORG 0000H AJMP MAIN ;转到主程序起始地址 ORG 0100H MAIN:MOV DPTR, #TABLE ;字形码表首地址送DPTR MOV A,30H ;取数 MOVC A,@A+DPTR ;查表取值送A MOV P1, A ;字形码送P1 SJMP $ TABLE:DB 3FH,06H,5BH,4FH,66H;0~4共阴字形码 DB 6DH,7DH,07H,7FH,6FH;5~9共阴字形码 END

  24. 3.3.2 分支程序 通常情况下,程序是顺序执行的,但我们也可以根据需要,在程序中安排一些控制转移指令,改变程序的执行方向,这就是分支程序。分支程序可以分为单分支和多分支等情况。单分支程序结构如图3-3(b)所示。当条件满足时顺序执行程序段A,否则执行程序段B。多分支结构如图3-4所示。先将分支按序号排列,然后按照分支的值来实现多分支选择。 图3-4 多分支结构

  25. 分支程序在单片机系统中应用较多,在编程时有许多技巧,设计要点如下:(1)先建立可供条件转移指令测试的条件。 (2)选用合适的条件转移指令。(3)在转移的目的地址处设定标号。

  26. 1.单分支程序 3 已知内RAM30H单元存有一个ASCII码,试对其进行判断,如果是“$”(24H),将其存入40H,否则存入31H单元。程序如下:ORG 0000H AJMP MAIN ORG 0100H MAIN:MOV A,30H CJNE A,#24H,DY31 ; 不是“$”,转去ZY31 MOV 40H,A ;是“$”,存入40H单元AJMP END0 DY31:MOV 31H,A ; 不是$,存入31H单元END0:SJMP $ END

  27. 2.多分支程序 (1) 位操作程序例4 已知某信号灯电路如图3-5,试编程实现如下功能: ⑴S0单独按下,红灯亮,其余灯灭; ⑵S1单独按下,绿灯亮,其余灯灭; ⑶S0、S1均按下,红、绿、黄灯全亮; ⑷都不按下黄灯亮。 参考程序如下: ORG 0000H LJMP START ORG 0100H START:ORL P1,#11000111B ;P1.6、P1.7设为输入,红绿黄灯灭 图3-5 某信号灯电路

  28. SS0: JB P1.7,SS1 ;S0未按,转判S1 JB P1.6,RED ;S0按下,S1未按,转红灯亮 DL:CLR P1.2 ;红灯亮 CLR P1.1 ;绿灯亮 CLR P1.0 ;黄灯亮 SJMP SS0 ;重新检测 SS1:JB P1.6,YELLOW ;S0未按,S1未按,转黄灯亮GREEN:CLR P1.1 ;绿灯亮 SETB P1.2 ;红灯灭 SETB P1.0 ;黄灯灭 SJMP SS0 RED:CLR P1.2 ;红灯亮 SETB P1.1 ;绿灯灭 SETB P1.0 ;黄灯灭 SJMP SS0

  29. YELLOW:CLR P1.0 ;黄灯亮 SETB P1.2 ;红灯灭 SETB P1.1 ;绿灯灭 SJMP SS0 END 说明:该程序只是说明位操作指令在分支程序中的应用方法,如果真要实现信号灯的点亮,还要在每段灯亮灭指令后加一段延时程序。

  30. (1)字节操作程序 例5 有一巡回检测报警装置,需对16路输入信号进行控制,每路设有一个报警上限值(等于或超出此值即报警,置报警标志F0),设16路输入信号存放在以50H为首地址的内RAM中,16路报警上限值存在以2000H为首地址的ROM中,试编制该程序。 程序如下: START: MOV DPTR,#2000H ;置16路报警上限值首地址 MOV R0 ,#50H ;置16路输入信号数据区首地址 MOV R7,#0 ;置16路输入信号的序号0 LOOP :MOV R1,@R0 ;检测信号存R1 MOV A,R7 ;读输入信号序号 MOVC A,@A+DPTR;查找该序号对应的报警上限值 CJNE A,R1,NEXT ;与对应的输入信号比较 AJMP ALAM ;输入信号等于报警上限值,转报警

  31. NEXT: JC ALAM ;输入信号超出报警上限值,转报警 INC R0 ;输入信号小于报警上限值,指向下 一路输入信号 INC R7 ;指向下一路输入信号序号 CJNE R7,#16,LOOP ;看16路是否全查完? 未完继续 CLR F0 ;16路全查完,清报警标志 AJMP $ ;暂停 ALAM:SETB F0 ;置报警标志 RET

  32. 3.3.3 循环程序 1.循环结构 在程序设计时,常常遇到需要反复执行的某种操作,这时可编写一个程序段重复执行,这就是循环。循环程序一般包括4部分,如图3-6所示。对这4部分的含义,我们以例题的形式加以说明。 例6 编程实现以下数据传送功能:将BUF为起始地址的50个数取反后,传送到以DATA为起始地址的内存单元中。

  33. 分析:如果采用顺序结构编写,程序会很麻烦,要执行50次从源地址中取数的MOV指令,50次数据取反的CPL指令,50次向目的地址送数的MOV指令。经过观察,我们发现,可以把顺序结构中重复执行的部分提取出来,编成一个独立的小程序段(即循环体部分),然后对这个小程序段重复执行50次(循环次数),这就构成了循环。分析:如果采用顺序结构编写,程序会很麻烦,要执行50次从源地址中取数的MOV指令,50次数据取反的CPL指令,50次向目的地址送数的MOV指令。经过观察,我们发现,可以把顺序结构中重复执行的部分提取出来,编成一个独立的小程序段(即循环体部分),然后对这个小程序段重复执行50次(循环次数),这就构成了循环。 图3-6 循环结构

  34. 1.初始化 规定循环体中各控制变量的初始状态。 2.循环体 这是循环程序需要重复执行的部分。对这部分编程的时候要注意两个问题: • 指令要具有通用性,程序要便于修改。 • 程序尽可能简化。

  35. (3)循环修改 循环程序每执行一次,都要对数据的地址指针、循环次数等作一次修改,这就是循环修改。 (4)循环控制 根据循环结束条件,判断循环是否结束。常用作循环控制的变量是循环次数。

  36. 参考程序如下: START:MOV R0,#SBUF ;数据的源地址 MOV R1,#DATA ;数据的目的地址 MOV R7,#50 ;循环次数 LOOP:MOV A,@R0 ; 源地址中数据送A CPL A ;取反 MOV @R1 , A ;取反后的数据送目的地址 INC R0 ;源地址加1,准备取下一个数 INC R1 ;目的地址加1,准备接收下一个数 DJNZ R7 ,LOOP ;循环结束?未结束重新取数 RET 循环程序按结构分,有单重循环与多重循环。在多重循环中,只允许外重循环嵌套内重循环;不允许循环相互交叉,也不允许从循环程序的外部跳入循环程序的内部。

  37. 2.循环结构的典型应用——定时 在单片机控制系统中,常有定时的需要,如定时中断、定时检测、定时扫描等。定时功能可以使用定时/计数器实现,但更多的是使用定时程序完成。 定时程序是典型的循环程序,它通过执行一个具有固定延时时间的循环体来实现时间的推移,因此,又常把定时程序叫做延时程序。定时程序的延时时间不受器件的限制,只要选择好循环初值,就可以实现几秒、几分、乃至几年的时间延迟。

  38. (1)单循环延时 单循环延时是最简单的定时程序。如: DELAY: MOV R7,#TIME ;TIME是循环程序控制变 ;量,可以取任意值 LOOP: NOP NOP NOP DJNZ R7,LOOP 其中的NOP是空操作指令,它不做任何操作,只是消磨时间。该程序段的延时时间可以这样计算: NOP指令的机器周期是1,DJNZ指令的机器周期是2,因此循环一次共需5个机器周期。如果单片机的晶振频率采用12MHz,则一个机器周期是1μs,因此循环一次的延迟时间是5μs。

  39. 延时程序中总的延时时间为5×TIME(μs),根据程序的需要,TIME可以任意取值(不超过8位二进制的表示范围)。因此该程序的最长延时时间是(TIME=0时)延时程序中总的延时时间为5×TIME(μs),根据程序的需要,TIME可以任意取值(不超过8位二进制的表示范围)。因此该程序的最长延时时间是(TIME=0时) 5×256=1280 (μs) (2)较长时间的延时 单循环延时的延迟时间较短,为了延长定时时间,可以采用多重循环的方法。 例7 编写延时1s子程序,要求:晶振采用12MHz,用三重循环编写。 分析:用12MHz晶振,机器周期是1μs, 程序如下: DELAY:MOV R7,#20 ;1μs D1:MOV R6,#200 ;1μs D2:MOV R5,#123 ;1μs

  40. NOP ;1μs DJNZ R5,$ ;2μs,共(2×123)μs DJNZ R6,D2 ;2μs,共〔(2×123+2+2) ×200〕μs,即50ms DJNZ R7,D1 ;2μs,共〔(2×123+2+2) ×200+2+1〕×20+2=1000062μs≈1s RET ;2μs 在该程序中,改变不同的寄存器初值,可以实现不同的定时要求。 (3)以一个基本的延时程序满足不同的定时要求 如果系统中有多个定时需要,我们可以先设计一个基本的延时程序,通过对这个基本延时程序的调用,实现所需的不同定时。如将例7延时1秒的DELAY作为基本的延时程序,则实现5秒、10秒的调用情况如下:

  41. MOV R0,#5 ;5s LOOP1:ACALL DELAY ;1s DJNZ R0,LOOP1 …… MOV R0,#10 ;10s LOOP2:ACALL DELAY ;1s DJNZ R0,LOOP2 …… 例8 已知某单片机温控系统每隔50ms测一次温度,测得的8位温度值存在特殊功能寄存器SBUF中,请编程求其1s的平均值,并存于60H中。(设1s采样温度总和不超过255) 程序如下: AVR1S: MOV R2,#0 ;温度初值为0 MOV R4,#20 ;平均次数为20

  42. LOOP: MOV A,SBUF ;读温度值 ADD A,R2 ; 温度求和 MOV R2,A ;回存 LCALL DELAY50 ;延时50ms,延时子程序略 DJNZ R4,LOOP ;20次采样完否?未完继续 MOV A, R2 ;和存入A MOV B,#20 ;除数存入B DIV AB ;求均值 MOV 60H,A RET 请尝试编写延时50ms子程序。

  43. 3.4 程序设计实例 3.4.1 数据极值查找程序 极值查找就是在指定的数据区中挑出最大值或最小值。 例9 从内部RAM30H单元开始存有8个无符号8位二进制数,请编程查找到最大值,并将其存放于40H单元。 分析:假定在比较过程中,用A存放大数,与之逐个比较的另一个数存放在2AH单元。流程图见图3-7。 图3-7最大值查找程序流程图

  44. 程序如下: MOV R1,#30H ;数据区首址 MOV R5,#08H ;数据区长度 MOV A,@R1 ;读第一个数 DEC R5 ;修改数据长度 LOOP: INC R1 MOV 2AH,@R1 ;读下一个数 CJNE A,2AH,BJ ;数值比较 AJMP LOOP1 BJ: JNC LOOP1 ;A值大,转移 MOV A,@R1 ;大数送A LOOP1:DJNZ R5,LOOP ;继续 MOV 40H,A ;最大值送40H SJMP $

  45. 3.4.2 数码转换程序 数码转换通常采用子程序调用的方法进行,即由子程序完成具体的转换功能,而由主程序组织数据和安排结果。 例10 在内部RAM的SHU16 单元存有两位十六进制数,请将其转换成ASCII码,并存放于ASCL(低位的ASCII码)和ASCH(高位的ASCII码) 两单元。 主程序如下: MAIN:MOV SP,#5FH ;设堆栈指针 PUSH SHU16 ;16进制数进栈 ACALL ASC16 ;调转换子程序 POP ASCL ;第一位转换结果送ASCL MOV A,SHU16 ;再取原16进制数 SWAP A ;高低半字节交换 PUSH ACC ;交换后的16进制数进栈 ACALL ASC16 ;转换 POP ASCH ;第二位转换结果送ASCH SJMP $

  46. 子程序如下: ASC16:DEC SP ;跳过断点保护内容PC DEC SP POP ACC ;弹出转换数据 ANL A,#0FH ;屏蔽高位 ADD A, #7 ;修改变址寄存器指针 MOVC A, @A+PC ;查表 PUSH ACC ;2字节,查表结果进栈 INC SP ;2字节,修改断点指针回到断点保护内容 INC SP ;2字节, RET ;1字节, ASCTAB:DB '012345678' ;ASCII码表 DB '9ABCDEF' END

  47. 这是一个很典型的程序,在阅读时应注意这样两个问题:这是一个很典型的程序,在阅读时应注意这样两个问题: (1)该程序强化了堆栈的使用,这对于大家加深理解堆栈的概念十分有利。在程序中用到了两种使用堆栈的方法: • 用堆栈传递数据。使要转换的16进制数在主程序中进栈(PUSH SHU16)而在子程序中出栈(POP ACC),最后再通过堆栈把转换结果返回主程序 (POP ASCL)。低位转换其堆栈的变化见图3-8; • 系统在调用子程序时自动完成的PC入栈操作。由于 要转换的16进制数是在主程序中先于断点值PC (ACALL ASC16下一条指令的地址)入栈,这样在 子程序中要取出转换数据,就得修改堆栈指针SP, 以指向该数据。

  48. (2)在ASCII码表中,是以字符串的形式列出的16进制数,但在汇编的过程中,写入存储单元的是该字符串的ASCII码形式。(2)在ASCII码表中,是以字符串的形式列出的16进制数,但在汇编的过程中,写入存储单元的是该字符串的ASCII码形式。 图3-8 数码转换程序的堆栈变化图

  49. 3.4.3课题与实训4 程序设计 一.实训目的 1.熟悉汇编语言的基本格式、伪指令的使用方法。 2.学习单片机应用程序的设计方法。 二.课题要求 1.将60H~69H单元存放的10个无符号数按照从小到大的顺序重新排列。 2.选择课后思考题与习题的部分程序运行并调试出来。 三.背景知识 可采用冒泡排序法。冒泡排序法把一批数据想象成纵向排列,采用自下而上的方法比较相邻两个数据,如果这两个数据的大小顺序符合要求,则保持原样,否则交换它们的位置。这样比较一轮后,最小的数据就像气泡一样浮到最顶上,故称冒泡排序法。

  50. 实际编程设计时,每一轮操作都从数据区的首地址开始,向末端推进。一般来讲,N个数据要进行N-1轮次比较和交换排序。表3-1表示了60H~65H单元存储数据的冒泡排序的执行过程。实际编程设计时,每一轮操作都从数据区的首地址开始,向末端推进。一般来讲,N个数据要进行N-1轮次比较和交换排序。表3-1表示了60H~65H单元存储数据的冒泡排序的执行过程。 表3-1 冒泡排序过程说明

More Related