单片机原理与接口技术44_第1页
单片机原理与接口技术44_第2页
单片机原理与接口技术44_第3页
单片机原理与接口技术44_第4页
单片机原理与接口技术44_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

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

文档简介

1、第第4章章 MCS-51单片机汇编语言程序设计单片机汇编语言程序设计n4.1 程序设计的基本方法n4.2 汇编语言程序的基本形式与设计举例14.1 程序设计的基本方法 程序设计就是编写计算机程序,任务是利用计算机语言对所要实现的功能进行描述和规定。80C51单片机程序设计主要采用2种语言: 一种是汇编语言,另一种是高级语言。 本章介绍单片机汇编语言程序设计。21.程序设计的步骤 分析问题 对需要解决的问题进行分析,以求对问题有一个正确的理解。在处理比较简单的问题时,问题的要求往往是显而已见的,无需多加分析。 确定解决问题的算法思想 解决一个问题常有多种方法可供选择。从数学的角度来描述,可能有几

2、种不同的算法。所谓的算法,就是解决问题的方法。3 程序结构设计 程序结构设计是把研究课题转化为程序的准备阶段。如果程序较小且简单,此阶段可能仅仅是绘制一张流程图。如果程序较大或较复杂,设计者就要考虑较完善的方法,例如模块化程序设计、结构式程序设计及自顶向下设计等方法。 4 流程图一般是利用一些带方向的线段,框图等把解决问题的先后次序等直观地描述出来。这样便于对程序的编写、检查和修改,当程序较为简单时,也可以不画出流程图。流程图的种类比较多,如逻辑流程图、算法流程图、程序流程图等。对于复杂的问题可以画几级流程图,程序还常要分成一个一个的模块,画出模块间的结构图。 5 编写程序编写程序 按所使用的

3、指令系统逐条编写汇编语言程序按所使用的指令系统逐条编写汇编语言程序, ,力求简单明力求简单明了了, ,层次清楚层次清楚, ,运行时间短运行时间短, ,占用内存数量少。占用内存数量少。常用的流程图符号如图常用的流程图符号如图4.1所示。所示。62.汇编语言源程序的编辑和汇编 源程序的编辑和汇编对一个单片机的应用系统,首先要根据它应具有的功能编制相应的程序,这就是源程序的编辑。把源程序翻译成单片机所能识别的机器码的过程称为对源程序的汇编。源程序的编辑和汇编可通过手工或通过机器来完成。7 MCS-51汇编语言的伪指令汇编语言程序的机器汇编是由微型计算机通过汇编程序自动完成的。为此,在源程序中应该有向

4、汇编程序发出指示的信息,告诉它应该如何完成汇编工作。伪指令就是汇编程序能够识别的汇编命令,它是程序员发给汇编程序的命令,只在汇编过程中起作用,它不是单片机要执行的指令,所以它没有机器码,在目标程序中也就不存在与伪指令相对应的机器码。 8MCS-51汇编程序中常用的伪指令有以下几条: ORG(ORIGIN)汇编起始地址命令 该命令常出现在源程序的开头,用于规定目标程序存放的起始地址。 在一个源程序中,可以多次使用ORG伪指令,但要求ORG定位从小到大,不能有重叠的情况。 其命令格式为: 标号:ORG地址9 END(END OF ASSEMBLY)汇编终止命令本命令用于终止源程序的汇编工作。在此命

5、令后面的源程序汇编程序一律不予处理,所以一个源程序只有一条END命令,而且位于源程序的最后。其命令格式为: 标号: END 表达式10 DB(DEFINE BYTE)定义字节命令 本命令用于从指定的地址开始,在程序存储器的连续单元中定义字节数据,其命令格式为: 标号: DB 8位数表11 DW(DEFINE WORD)定义数据字命令 本命令用于从指定地址开始,在程序存储器的连续单元中定义16位的数据字。该命令将字数据表中的数据依从左到右的顺序存放在指定的存储单元中,数据字的高8位放在低地址单元,低8位放在高地址单元。其命令格式为: 标号: DW16位数表12 DS(DEFINE STONAGE

6、)定义存储区命令 本命令用于从指定地址开始,保留指定数目的空白字节单元作为存储区,供程序运行时使用,汇编时,对这些单元不赋值。其命令格式为: 标号: DS表达式13 EQU(EQUATE)赋值命令 本命令用于给标号赋值,赋值以后,其标号值在整个程序中有效。其命令格式为: 字符名称EQU赋值项14.BIT位定义命令 本命令用于给字符名称赋以位地址。其命令格式为: 字符名称BIT位地址上层目录154.2 汇编语言程序的基本形式与设计举例 程序设计是为了解决某一个问题,将指令有序地组合在一起。程序有繁有简,有些复杂的程序往往是由简单的基本程序所构成的,程序设计的基本形式包括不同类型程序的设计方法和技

7、巧,掌握了这些方法和技巧将有利于熟练地编制单片机的各种应用程序。1. 顺序程序 顺序程序是指无分支、无循环结构、也不调用子程序的程序,这是最简单的程序结构。顺序程序执行的流程是依指令在存储器中的存放顺序进行的。 16 例1:把累加器中的8位无符号二进制数转换成3位(2个字节)BCD码形式。百位数存入片内的21H单元,十位数和个位数存入相邻的22H单元。 这个题目实际上是数制转换的问题,要把二进制数转换为十进制数(BCD码形式)。一个8位的二进制数最大为11111111B,转换结果为255,共有3位,所以在编程时要考虑最多存放3个BCD码的情况。题目要求把最高位放在21H,而十位数和个位数以压缩

8、BCD码的形式放在于22H。 我们采用除法指令来实现。 17实现程序如下:BINBCD:MOV B,#100 DIV AB ;A除以100,商为百位数 MOV 21H,A ;保存百位数 MOV A,#10 XCH A,B ;余数送入A中,除数送入B中 DIV AB ;余数除以10,得十位数 SWAP A ;将十位数交换到高半字节 ADD A,B ;十位数加个位数 MOV 22H,A ;转换结果的十位数和个位数存22H RET18 例2:设在片内RAM中,20H和21H单元各存放有一个8位数据,要求拼装一个新字节并送30H保存,其低5位取自20H单元中的低5位,高3位取自21H单元中的低3位。

9、实现程序如下: MOV 30H,20H ;20H单元中的数据送入30H单元 ANL 30H,#00011111B ;屏幕高3位 MOV A,21H ;21H单元中的数据送入A SWAP A ;将A中的数据高低3位交换,即循环左移4次 RL A ;将A中的数据再循环左移1次 ANL A,#11100000B ;屏蔽A中数据的低5位 ORL 30H,A ;完成拼装19 例3:做3个字节的无符号数的加法。设一个加数存放在内部RAM的50H、51H、52H单元,另一个加数存放在内部RAM的53H、54H、55H单元,相加结果存放在内部RAM的50H、51H、52H单元,均从高字节开始存放,进位存放在位

10、寻址区的00H位中。 20实现程序如下: MOV R0,#52H ;低字节相加,结果存52H MOV R1,#55H MOV A, R0 ADD A,R1 MOV R0,A DEC R0 ;中间字节带进位相加,结果存51H DEC R1 MOV A,R0 ADDC A,R1 MOV R0,A DEC R1 DEC R0 ;高字节带进位相加,结果存52H MOV A,R0 ADDC A,R1 MOV R0,A MOV 00H,C ;存进位212.分支程序 在程序设计中,有时根据实际需要可以通过判断、比较等结果,改变程序执行的顺序,转向不同的分支。分支程序是通过转移指令实现的,可分成单分支、双分支

11、和多分支三种结构。例1:设在外部RAM的3个连续存储单元ST1、ST2和ST3中,ST1和ST2存放着两个不带符号的二进制数,请找出其中的大数并存ST3单元中。 22实现程序如下: START:CLR C ;进位位清0 MOV DPTR,#ST1 ;设置数据指针 MOVX A,DPTR ;取第一个数 MOV R7,A ;暂存R7 INC DPTR ;数据指针加1 MOVX A,DPTR ;取第二个数 SUBB A,R7 ;比较两数的大小 JNC BIG1 ;第二个数大转移 XCH A,R7 ;第一个数大送ABIG0:INC DPTR ;数据指针加1 MOVX DPTR,A ;存大数 RETBI

12、G1:MOVX A,DPTR ;第二个数送A SJMP BIG023 例2:某温度控制系统,采集的温度值T存放在累加器A中,此外在内部RAM的54H单元中存放控制温度的下限值Ta,在55H单元中存放控制温度的上限值Tb。若TTb,程序转向降温处理程序JW;若TTa,则程序转向升温处理程序SW;若TaTTb,则程序返回主程序。24实现程序如下: CJNE A,55H,LOOP1 ;TTb,程序转向LOOP1 AJMP ZUCG ;TTb,返回主程序LOOP1:JNC JW ;若(CY)0,表明TTb,转降温处理程序JW CJNE A,54H,LOOP2 ;TTa,程序转向LOOP2 AJMP Z

13、UCG ;TTa,返回主程序LOOP2:JC SW ;若(CY)1,表明TTa,转升温处理程序SWZUCG: RET ;若TaTTb,返回主程序25 例3:根据R7的内容转向相应的处理程序。设R7的内容为处理程序的序号0N,对应的处理程序的入口地址分别为A0AN。 实现程序如下:START:MOV DPTR,#TAB ;处理程序入口地址表的首地址送数据指针 MOV A,R7 ;处理程序的序号送A ADD A,R7 ;处理程序的序号加倍(因地址表中的入口地址占2个字节) MOV R3,A ;将所求得的地址偏移量暂存R3 MOVC A,A+DPTR ;取处理程序入口地址的高8位 XCH A,R3

14、;将暂存的地址偏移量交换到A中 INC A ;地址偏移量加1 26MOVC A,A+DPTR ;取处理程序入口地址的低8位 MOV DPL,A ;低8位地址送DPL MOV DPH,R3 ;高8位地址送DPH CLR A ;A清0 JMP A+DPTR ;程序转向相应的处理程序TAB: DW A0 DW A1 DW AN273.循环程序 在程序设计中,经常需要连续多次地重复执行某段程序,这时可以设计循环程序,这种结构有助于用简短的程序完成大量的处理任务。我们把这种按某一规律重复执行的程序称为循环程序。 循环程序的设计中一般包含有循环体设计、循环结束条件设置和循环初态设置3个内容。 循环程序的操

15、作流程有先执行后判断和先判断后执2种结构。 例1:长度为10H的字符串存放在首地址为inbuf的内部RAM中,从inbuf地址开始将字符串向片外RAM的outbuf地址开始的存储单元传送,一直进行到遇见回车符(ODH)或整个字符串传送完毕。28实现程序如下: MOV R7, #10H ;置转送次数 MOV R0, #inbuf ;送字符串首地址 MOV DPTR, #outbuf ;送传送单元起始地址LOOP: CJNE R0, #ODH, NEXT ;不是回车符则转移 SJMP EDNEXT: MOV A, R0 ;取字符 MOVX DPTR, A ;送字符 INC R0 ;地址加1 INC

16、 DPTR ; DJNZ R7, LOOP ;未送完返回ED: SJMP 29例2:在外部RAM首地址为table的数据表中,有10个字节的数据,编程将每个字节的最高位无条件的置1。实现程序如下: MOV DPTR,#table ;送数据表首地址 MOV R7,#OAH ;置处理次数LOOP: MOVX A,DPTR ;取数据 ORL A,#10000000B ;最高位置1 MOVX DPTR,A ;送回 INC DPTR ;地址加1 DJNZ R7,LOOP ;未处理完返回 SJMP 30 例3:把片内RAM中地址为30H到39H单元中的10个无符号数逐一比较,并按从小到大的顺序依次排列在这

17、片单元中。 数据排序常用冒泡排序法。此题可从30H开始从前向后进行相邻两数的比较,若两数的大小次序与要求的顺序不符,则将两数的顺序互换,并置位标志位,否则就不互换,也不置位标志位。从头到尾进行1次相邻数比较并按要求调整两数的顺序后(进行1次冒泡),就会把最大的数换到最后,再进行1次这样的比较和调整,就会把次大的数排在倒数第2的位置。在多次比较和调整后中,若出现相邻两数从头到尾不再有互换的情况(互换标志始终为0),就说明从30H29H单元中的数已经从小到大排列完毕。31实现程序如下:START:CLR 00H ;互换标志清0 MOV R7,#09H ;置循环控制初值 MOV R0,#30H ;地

18、址指针置数据首地址 MOV A,R0 ;取前一个数LOOP: INC R0 ;地址指针加1,指向后一个数的存储单元 MOV R2,A ;暂存前一个数 SUBB A,R0 ;前数减后数(比较相邻两数) MOV A,R2 ;前数送A JC NEXT ;若前数小于后数,转移 32 SETB 00H ;若前数大于后数,互换标志位置1 XCH A,R0 ;前数(大数)送后数的存储单元 DEC R0 ;地址指针减1,指向前一个数的存储单元 XCH A,R0 ;后数(小数)送前数的存储单元,完成了相邻两数的互换 INC R0 ;地址指针加1,指回原后数的存储单元NEXT: MOV A,R0 ;取出大数 DJ

19、NZ R7,LOOP ;循环次数未到转移到LOOP,否则往下执行 JB 00H,START ;若有互换(标志位为1)则转 ; START,否则往下执行 SJMP ;结束334.子程序 子程序是单片机应用程序必不可少的部分。在实际应用中,有些通用性的问题在一个程序中可能要使用多次,而编写出来的程序段是完全相同的。为了避免重复,使程序结构紧凑,阅读和调试更加方便,往往将其从主程序中独立出来,设计成称为子程序的形式,供程序运行时随时调用。 子程序的结构与主程序基本相同,其区别在于它的执行是由其它程序来调用的,执行完后仍要返回到调用它的主程序去。 34在调用子程序时,有以下几点应予以注意:l对于在调用

20、前主程序已经使用了的某些存储单元和寄存器,若在调用时需要将它们作其它用途,那么应先把这些单元或寄存器中的内容压入堆栈保护起来(现场保护),调用完后再从堆栈中弹出(现场恢复)。保护和恢复可在主程序中实现,也可在子程序中实现。l在调用子程序时,主程序应通过某种方式把有关的参数(子程序的入口参数)传给子程序,当子程序执行完毕后,又需要通过某种方式把有关的参数(子程序的出口参数)传给主程序。入口参数和出口参数的传递可通地过累加器、寄存器、存储单元和堆栈来实现。l子程序中还可以包括对另外子程序的调用。 35 例1: 主程序 PUSH PSW ;保护现场 PUSH A ; PUSH B ; MOV PSW

21、,#10H ;采用换工作寄存器组保护 LCALL addr16 ;调用子程序 POP B ;恢复现场 POP A ; POP PSW ; 36例2:子程序 SUB1:PUSH PSW ;保护现场 PUSH A ; PUSH B ; MOV PSW,#10H ;采用换工作寄存器保护 POP B ;恢复现场 POP A ; POP PSW ; RET37例3:编写程序将片内RAM从30H开始的10个存单元的内容清0。 MAIN: ;主程序 MOV R0,#30H MOV R7,#0AH ACALL SUBRT SUBRT:MOV A,#00H ;子程序 LOOP: MOV R0,A INC R0

22、DJNZ R7,LOOP RET 此例利用寄存器完成参数的传递38 例4:编写程序将片内RAM的某数据区清0。设该数据区的起始地址存放在70H单元中,要被清0的存储单元的个数存放在71H单元中。 实现程序如下: MAIN: ;主程序 PUSH 70H ;起始地址送堆栈 PUSH 71H ;存储单元个数送堆栈 ACALL SUBRT ;调用清0子程序 39SUBRT:POP DPH ;将主程序断口地址暂存DPTR POP DPL ; POP R7 ;取清0单元个数 POP R0 ;取数据区起始地址 SUB1:MOV A,#00H ; INC R0 ; DJNZ R7,LOOP ; PUSH DP

23、L ;将主程序断口地址送回堆栈 PUSH DPH RET ;返回 此例通过堆栈来完成参数的传递。对于这个简单的例子而言,这种方法显得有点笨,但从参数的传递而言,不失为一种可取的方法 。40例5:把十进制数1234与片内RAM56H和57H单元中的两个字节BCD变量相加,所得之和存入78H和79H单元。 实现程序如下: ;主程序 LCALL ADDBCD ;调用子程序 DW 1234H ;BCD常数 DB 56H ;BCD变量地址 DB 57H ;和数存入地址 ADDBCD:POP DPH ;取主程序断口地址,即BCD常数首地址 POP DPL MOV A,#2 ;取BCD变量存储单元地址56H

24、 MOVC A,A+DPTR MOV R0,A ;建BCD变量地址指针 MOV A,#3 ;取和数存入地址78H MOVC A,A+DPTR MOV R1,A ;建和数地址指针41 MOV A,#1 ;取BCD常数低字节34H MOVC A,A+DPTR ADD A,R0 ;求两低字节和 DA A ;十进制调整 MOV R1,A ;存低字节和 INC R0 ;BCD变量地址指针加1 INC R1 ;和数地址指针加1 CLR A ;累加器清0 MOVC A,A+DPTR ;取常数高字节 ADDC A,R0 ;求两高字节和 DA A ;十进制调整 MOV R1,A ;存高字节和 MOV A,#4

25、;准备返回主程序传递参数后的第一条指令 JMP A+DPTR ;返回 此例是利用存储器来实现参数的传递的,子程序不用RET指令返回。这是因为子程序开头的两条POP指令已将主程序的断口地址送入DPTR,堆栈指针的内容也因此作了调整,而且程序返回不应该在原来的断口。425.其它实用程序 1、算术运算程序 例1.有N个单字节无符号数(N255),依 次存放在外部RAM的addr1开始的连续单元中。求和并要求把计算结果存放R1和R2中(设相加的和是二字节数),R1中存高8位,R2中存低8位。43实现程序如下: MOV DPTR,#addr1 ;设置数据指针 MOV R7,#N ;字节个数 MOV R1

26、,#00H ;和的高8位清0 MOV R2,#00H ;和的低8位清0LOOP: MOVX A,DPTR ;取一个加数 ADD A,R2 ;单字节数相加 MOV R2,A ;和的低位送R2 JNC LOOP1 ;无进位准备与下一个数相加 INC R1 ;有进位将和的高位加1LOOP1:INC DPTR ;指向下一个单元 DJNZ R7,LOOP ;末加完再循环 SJMP 44例1.设20H单元中有一个8位数据: (20H)=x7x6x5x4x3x2x1x0 现在要将20H单元的低4位送到21H单元,并按相反的次序装排,高4位置0,即要求: (21H)=0000 x0 x1x2x32、数据的拼拆

27、45 实现程序如下: MOV C,00H ;20H单元中位0的位地址是00H RLC A ;将x0移入A中 MOV C,01H ;20H单元中位1的位地址是01H RLC A ;将x1移入A中 MOV C,02H RLC A ;将x2移入A中 MOV C,03H RLC A ;将x3移入A中 ANL A,#00001111B ;屏蔽高4位 MOV 21H,A ;完成拼装46例2.设片内RAM单元7CH中的数据是两个BCD码,现在要将它们分开,并将高位BCD码送到R6中,将低位BCD码送到R5中。 实现程序如下: MOV R1,#7CH ;R1作地址指针 MOV A,#00H ;将A清0 XCH

28、D A,R1 ;将7CH单元的低4位与累加器中的低4位互换 MOV R5,A ;将低位BCD码送存 MOV A,7CH ;取7CH单元中的内容 SWAP A ;累加器的高4位与低4位互换 MOV R6,A ;将高位BCD码送存473、数据的转换例1.十六进制数的ASCII代码转换成4位二进制数。 对于这种转换,只要注意到下述关系便不难编写出转换程序: 字符09的ASCII码值为30H39H,它们与30H之差恰好为00H09H,结果0AH;字符AF的ASCII码值为41H46H,它各自减去年37H恰好为0AH0FH,结果0AH。 设十六进制数的ASCII代码存放于R2中,转换后的二进制数仍放回R

29、2。48实现程序如下:ASCHEX:MOV A,R2 ;取ASCII码 CLR C SUBB A,#30H ;减30H MOV R2,A ;差暂存R2 SUBB A,#0AH ;差减0AH JC SBIO ;小于0AH则转移 XCH A,R2 ;取回暂存差 SUBB A,#07H ;差减07H SBIO: MOV R2,A ;存转换结果 RET49例2.将一位十六进制数转换成ASCII码。 设十六进制数存放于R1中,转换后的ASCII码存放于R3中。 实现程序如下: HEXASC:MOV A,R1 ;取数 ANL A,#0FH ; PUSH A ;入栈暂存 CLR C SUBB A,#0AH

30、;减0AH POP A ;暂存数出栈 JC JAFA ;小于0AH则转移 ADD A,#07H ;被转换数加07H JAFA: ADD A,#30H ;被转换数加30H MOV R3,A ;结果送R3 RET504、查表程序在MCS-51中,查表时的数据表格是存放在程序存储器中的,所以用于查表的指令有两条: MOVC A,A+DPTR MOVC A,A+PC 这两条指令中,使用DPTR作为基址寄存器查表比较简单,可通过以下三步操作来完成: 将所查表格的首地址存入数据指针DPTR; 将所查表的项数(即在表中的位置是第几项)送累加 器A; 执行查表指令MOVC A,A+DPTR读取表中的数据,并将其送入累加器A。51 若用PC作为基址寄存器查表,则操作有所不同,也可分为三个步骤: 将所查表的项数(即在表中的位置是第几项)送累加器A; 对A进行加调整量data的调整。调整量是紧接查表指令MOVC A,A+PC之后的那条指令的首地址与所查表格的首地址之间的地址差(用字节数表示); 执行查表指令MOVC A,A+PC读取表中数据,并将其送入累加器A。 52例1:将多位十六进制数转换成ASCII码。 设R0中存放多位十六进制数的最低两位存储单元地址(一个单元存放两

温馨提示

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

评论

0/150

提交评论