《C单片微机的程序设计课件.ppt》由会员分享,可在线阅读,更多相关《C单片微机的程序设计课件.ppt(110页珍藏版)》请在三一办公上搜索。
1、第四章 80C51单片微机的程序设计,4.1概述4.1.1 汇编语言格式,1.计算机语言机器语言、汇编语言与高级语言 程序:为计算某一算式或完成某一工作的若干指令的有序集合。计算机的全部工作概括起来,就是执行这一指令序列的过程。程序设计:为计算机准备这一指令序列前的过程。机器语言机器语言系统:用二进制代码表示的指令系统,简称为机器语言。直接用机器语言编写的程序称为手编程序或机器语言程序。,汇编语言 在机器语言,这些英文字符被称为助记符。用这种助记符表示指令系统的语言称为汇编语言或符号语言,用汇编语言编写的程序称为汇编语言程序。特点:助记符指令与机器指令是-对应的,用汇编语言编写的程序效率高,占
2、用存储空间小,运行速度快,而且能反映计算机的实际运行情况,所以用汇编语言能编写出最优化的程序。汇编语言是“面向机器”的语言,编程比使用高级语言困难。汇编语言能直接访问存储器、输入与输出接口及扩展的各种芯片(比如A/D、D/A等),也可直接处理中断,汇编语言能直接管理和控制硬件设备。,汇编语言通用性差,汇编语言和机器语言一样,都面向一台具体的机器,不同的单片微机具有不同的指令系统,并且不能通用。不能直接识别在汇编语言中出现的字母、数字和符号,需要将其转换成用二进制代码表示的机器语言程序,才能够识别和执行。通常把这一转换(翻译)工作称为汇编。人工汇编:由程序员通过查指令表把汇编指令程序转换为机器语
3、言程序的过程。由专门的程序来进行汇编,这种程序称为汇编程序。经汇编程序汇编而得到的机器语言程序,计算机能够识别和执行,这一机机器语言程序称为目的程序或目标程序,而汇编语言程序称为源程序。这3者之间的关系如图41所示。,高级语言 比如BASIC、FORTRAN、COBOL及PASCAL等,都是一些参照数学语言而设计的、近似于人们日常用语的语言。通用性强,易于移植到不同类型的机器中去。计算机也不能直接识别和执行高级语言,需要将其转换为机器语言才能识别和执行。对于高级语言,这一转换工作通常称为编译或者解释。进行编译或者解释的专用程序称为编译程序或者解释程序。由于高级语言不受具体机器的限制,而且使用了
4、许多数学公式和习惯用语,从而简化了程序设计的过程,因此是一种面向问题或者面向过程的语言。比如,APT、PROLOG、LISP、PL/M以及C语言等。而80C51系列单片微机作为工业标准地位,从1985年开始就有C语言编译器,简称C51。,汇编语言 汇编语言语句的种类和格式 汇编语言语句的种类 指令语句:每1个指令语句都在汇编时产生1个目标代码,对应着机器的1种操作。例如:MOV A,#0 伪指令语句:主要是为汇编语言服务的,在汇编时没有目标代码与之对应。例如:ONE EQU 1 宏指令语句:用以代替汇编语言源程序中重复使用的程序段的1种语句,由汇编程序在汇编时产生相应的目标代码。,汇编语言语句
5、的格式 指令语句的格式为:【标号(名字)】:助记符(操作码)【操作数(参数)】;【注释】伪指令语句的格式:名字 定义符 参数;注释各字段之间用1个空格或字段定界符分隔,常用的字段定界符有冒号“:”、逗号“,”和分号“;”。其中方括号括起来的是可选择部分。,标号域:说明指令的地址。标号可以作为LJMP、AJMP、LCALL及ACALL等指令的操作数。在指令语句中,标号位于一个语句的开头位置,由字母和数符组成,字母打头,冒号“:”结束。标号中的字符个数一般不超过8个,若超过8个,则以前面的8个为有效,后面字符不起作用。不能使用本汇编语言中已经定义了的符号作标号,比如指令助记符(如ADD)、伪指令(
6、如END)一条语句可以有标号,也可以没有标号,操作码域:是指令的助记符或定义符,用来表示指令的性质,规定这个指令语句的操作类型。伪指令语句中的定义符规定这个指令语句的伪操作功能。对于标号缺省的语句,操作码域作为一行的开始。但在书写时,应与上一行的操作码对齐。,操作数域:给出的是参与运算或进行其它操作的数据或这些数据的地址。操作数与操作码之间用空格“”分隔,若有两个操作数,这两个操作数之间必须用逗号“,”分开。对于操作数域出现的常数:若采用十六进制数表示,其末尾必须加“H”说明;若十六进制数以A、B、C、D、E、F开头,其前面必须添1个“0”进行引导说明。若采用二进制数表示,其末尾必须用“B”说
7、明。若采用十进制数表示,可以不加后缀或加“D”说明。,注释域由分号“;”引导开始,是说明语句功能、性质以及执行结果的文字。以分号“;”引导。,例:把片外存储器2200H单元中的数送入片内70H单元中。标号域 操作码域 操作数域 注释域BEGIN:MOV DPTR,#2200H;(DPTR)=2200H MOV R0,#70H;(R0)=70H MOVX A,DPTR;(A)=(DPTR)MOV R0,A;(R0)=(A),伪指令:为了便于编程和对汇编语言程序进行汇编,各种汇编程序都提供一些特殊的指令,供人们编程使用。由伪指令确定的操作称为伪操作。伪指令又称汇编程序控制译码指令。“伪”体现在汇编
8、时不产生机器指令代码,不影响程序的执行,仅指明在汇编时执行一些特殊的操作。,4.1.2 伪指令语句,ORG(ORiGIN)汇编起始地址伪指令指令格式为:ORG 表达式 含义:向汇编程序说明,下述程序段的起始地址由表达式指明。表达式通常为16进制地址码。一般规定,在由ORG伪指令定位时,其地址应当由小到大,不能重叠。它的有效范围一直到下一条ORG伪指令出现为止。跟在ORG伪指令后面的程序段或数据段是绝对地址还是浮动地址段,依赖于ORG右边的表达式性质。,ORG 1000H START:MOV A,12H含义:通知汇编程序,从 START开始的程序段,其起始地址由1000H开始。由于1000H是立
9、即数型地址码,所以还隐含地指明该程序段是绝对地址段。假定ORG右边的表达式是浮动程序段中定义的标号RELOCA,则 ORG RELOCA SUBROU:表明 SUBROU起始于 RELOCA(它是相对地址)浮动地址的程序段。,END(END of assembly)汇编结束伪指令汇编结束伪指令一般有以下两种格式:主程序模块:标号 END 表达式 子程序模块:标号 END 含义:通知汇编程序,该程序段汇编至此结束。END语句应设置在整个程序(包括伪指令在内)的后面。当源程序为主程序时,END伪指令中可有标号,这个标号应是主程序第一条指令的符号地址。若源程序为子程序,则在 END伪指令中不需要带标
10、号。,EQU(EQUate)赋值伪指令 指令格式为:标号 EQU 表达式 含义:把表达式赋值于标号,这里的标号和表达式是必不可少的。例如:LOOP EQU2002H是向汇编程序表明,标号LOOP的值为2002H。又如:LOOP1 EQULOOPLOOP已赋值为2002H,则相当于LOOP1LOOP,即LOOPI也为2002H,在程序中LOOP和LOOP1可以互换使用。用EQU语句给一个标号赋值以后,在整个源程序中该标号的值是固定的,不能更改。,DL定义标号值伪指令 指令格式为:DL 含义:说明标号等值于表达式。同样,标号和表达式是必不可少的。例如;COUNT DL 3000H;S定义标号COU
11、NT的值为;3000H COUNT DL COUNT十1;重新定义COUNT的值为;3000Hl可用DL语句在同一源程序中给同一标号赋予不同的值,即可更改已定义的标号值;而用EQU语句定义的标号,在整个源程序中不能更改。,DB(Define Byte)定义字节伪指令指令格式为:标号 DB 表达式或表达式表 含义:将表达式或表达式表所表示的数据或数据串存入从标号开始的连续存储单元中。标号为可选项,它表示数据存储单元地址。表达式或表达式表是指一个字节或用逗号分开的字节数据。可以是用引号括起来的字符串。字符串中的字符按ASCII码存于连续的ROM中。例如:ORG2000H TABLE DB 73H,
12、04,100,32,00,2,“ABC”表示字节串数据存入由TABLE标号为起始地址的连续存储器单元中。即从2000H存储单元开始依次连续存放数据为:73H,04H,64H,20H,00H,FEH,41H,42H,43H。,若不采用ORG伪指令专门规定数据区的起始地址,则数据区的起始地址即根据DB命令前一条指令的地址确定。这时DB所定义的数据字节的起始地址为DB命令前一条指令的地址加上该指令的字节数。,DW(Define Word)定义字伪指令指令格式为:标号 DW 表达式或表达式表含义:把字或字串值存入由标号开始的连续存储单元中,且把字的高字节数存入低地址单元,低字节数存入高地址单元。按顺序
13、连续存放。DW100H,3456H,814表示按顺序存入01H,00H,34H,56H,03H,2EH注:DB和DW定义的数表,数的个数不得超过80个。若数据的数目较多时,可以使用多个定义命令。一般以DB来定义数据,以DW来定义地址。,DS(Define Storage)定义存储区伪指令 指令格式为:DS 含义:通知汇编程序,在目标代码中,以标号为首地址保留表达式值的若干存储单元以备源程序使用。汇编时,对这些单元不赋值。例如:BASE DS 100H通知汇编程序,从标号BASE开始,保留100H个存储单元,以备源程序另用。注意,对于80C51单片微机,DB、DW、DS等伪指令只能应用于程序存储
14、器,而不能对数据存储器使用。,BIT 位定义伪指令命令格式为:BIT 含义:给字符名称赋予位地址。其中,位地址可以是绝对地址,也可以是符号地址。例:ABCBITP3.1把P3.1位地址赋值给ABC,在后面的编程中,ABC即可作为位地址P3.1使用。,例1.伪指令应用ORG 8100HBUFFER DS 10H DW“A B”DW 100H,1ACH,-814说明:从8100H至810FH为缓冲区空间(8110H)=41H(A)(8111H)=42H(B)8112H单元起存放01H、00H、01H、ACH、FCH、D2H,4.2 80C51汇编语言程序设计,汇编语言程序设计,就是采用汇编指令来编
15、写计算机程序。在实际编程中,如何正确选择指令、寻址方式和合理使用工作寄存器,包括数据存储器单元,如何对扩展的I/O端口进行操作等,都是基本的汇编语言程序设计技巧。程序结构一般采用以下3种基本控制结构,即顺序结构、分支结构和循环结构来组成,再加上使用广泛的子程序及中断服务子程序,共有5种基本结构。,按照逻辑操作顺序,从某一条指令开始逐条顺序执行,直至某一条指令为止。例2.数据传送和交换。将R0与R7内容互换,R4与内存20H单元内容互换。XCHR:MOVA,R0 XCH A,R7 XCHA,R0;R0与R7内容互换 MOVA,R4 XCHA,20H XCHA,R4;R4与20H单元内容互换,4.
16、2.1 顺序结构程序设计,设被加数存放于片内RAM的20H(低位字节)、21H(高位字节),加数存放于22H(低位字节)和23H(高位字节),运算结果的和数存放于20H(低位字节)和21H(高位字节)中。实现16位相加。START:PUSH ACC;将A中内容进栈保护MOV R0,20H;将20H地址送R0 MOV R1,22H;将22H地址值送R1 MOV A,R0;被加数低字节内容送A ADD A,R1;低字节数相加 MOV R0,A;低字节数和存20H中,例3.不带符号多字节加法。,INC R0;指向被加数高位字节 INC R1;指向加数高位字节 MOV A,R0;被加数高位字节送A A
17、DDC A,R1;高字节数带进位相加MOV R0,A;高字节数和存21H中CLRAADDCA,#00HMOV10H,A;进位暂存于10H中 POP ACC;恢复A原内容,注意:对于对带符号数原码的减法运算,只要先将减数原码的符号位取反,即可把减法运算按加法运算的原则来处理。对于带符号数的加法运算,首先要进行两数符号的判定,若两数符号相同,则进行两数相加,并以被加数符号为结果的符号。如果两数符号不同,则进行两数相减。如果相减结果为正,则该数即为最后结果,并以被减数符号为结果的符号。如果两数相减的结果为负,则应将其差数取补,并把被减数的符号取反后作为结果的符号。,多字节乘法的基础是加法。分别相乘后
18、对应字节相加(个位、十位、百位等分别相加,并考虑低字节向高字节的进位)。选用工作寄存器暂存中间积。分析:设被乘数低字节(addrl)用A表示,高字节(addr2)用B表示;乘数低字节(addr3)用L表示,高字节(addr4)用M表示。,例.双字节乘法。,双字节相乘的过程如下:,工作寄存器用来存放部分积,R2存放(HALLBLLMA),R3存放(HBL+CY HMALBM),R4存放(HBM十CY)。START:PUSH PSW;PSW、A、B入栈PUSH ACCPUSH B MOV PSW,18H;选用工作寄存器组 3 MOV R0,addrl;被乘数低字节地址送R0 MOV R1,addr
19、3;乘数低字节地址送R1 MOV A,R0;被乘 数低字节内容送APUSH A;被乘 数低字节内容A压栈,MOV B,R1;乘数低字节内容送B MUL AB;(1)AL MOV R0,A;积的最低字节存入addrl中 MOVR2,B;HAL送R2中 INC R0;指向被乘数高字节 MOV A,R0;被乘数高字节送A MOV B,R1;乘数低字节送B MUL AB;(2)BL,ADD A,R2;HAL十LBL MOV R2,A;HAL十LBI之和送R2 MOV A,B;HBL送A ADDC A,00H;HBLCY MOV R3,A;HBL送R3 POP A;被乘 数低字节内容L出栈INCR1;指
20、向ddr4MOV B,R1;M送B,MUL AB;(3)MA ADD A,R2;LMA(R2)MOV R2,A;LMAHAL十LBL之和送R2 MOV A,B;HMA送A ADDC A,R3;HMA十HBLCY MOV R3,A;HMAHBLCY之和送R3 MOV R4,0;清R4,JNC LOOP;CY0,转LOOP INC R4;CY1,则(R4)R4l LOOP MOV A,R0;B送 A MOV B,R1;M送B MUL AB;(4)MB ADD A,R3;HMA十HBLLBM MOV R3,A;HMAHBLLBM之和送R3 MOV A,B;HBM送A ADDCA,R4;R4HBMRE
21、S3,MOV R1,A;RES3存入 addr4中 MOVA,R2;RES1存入addr2中MOV R0,A DEC R1;指向addr3 MOV A,R3;RES2存入addr3中 MOVR1,A POP B;B、A、PSW出栈POP ACC POP PSW,对于带符号数的乘法,其原则为:原码相乘,乘积的符号位为被乘数与乘数符号位的“异或”,查表:根据变量x,在表格中查找对应的y值,使yf(x)。y与x的对应关系可有各种形式,而表格也可有各种结构。一般表格常量设置在程序存储器的某一区域内。MOVC A,ADPTR;远程查表MOVC A,A+PC;近程查表,例.查表,设有一个巡回检测报警装置,
22、需对4 路输入进行控制,每路设有一个最大额定值,为双字节数。控制时需根据检测的路号找出该路对应的最大额定值。设R2用于寄存检测路号,查找到的对应的最大额定值存放于31H和32H单元中。查找最大允许额定值子程序如下:,地址 机器码 源程序注释 ORG 2000H2000 EA MOV A,R2;检测路号送A2001 2A ADDA,R2;(R2)22002 F531 MOV 31H,A;距表首址偏移量2004 2408 ADD A,#19H;偏移量2006 83 MOVC A,A+PC;查表,读取第1个字节内容2007 C531 XCH A,31H;第1字节存入31H单元2009 2404 AD
23、D A,#15H;偏移量200B 83 MOVC A,A+PC;查表,读取第2字节200C F532 MOV 32H,A;第2字节存入32H单元200E,ORG2020H;最大额定值表20201230 TAB:DW 1230H,;路号020221540 DW 1540H;路号120242340 DW 2340H,;路号220262430 DW 2430H;路号3 END 说明:rel计算2020H-(2006H+1)=19H(2020H+1)-(200BH+1)=15H,设表中有1024个元素,每个元素为两个字节,则表格总长为2048个字节。现按R4和R5的内容从表格中查出对应的数据元素值,送
24、存R4和R5中。TBDP1:MOV DPTR,addrl6;表格首地址值送DPTR MOVA,R5;查表参数低位字节送A CLR C;清CY RLC A;带进位左移一位 XCH A,R4;将查表参数R4内容送A RLC A;带进位左移一位 XCH A,R4;R4与R5内容互换,例.查表,ADD A,DPL;DPL查表参数低位字节 MOV DPL,A;调整DPL、DPH MOV A,DPH;DPH送A ADDC A,R4;DPH查表参数高位字节 MOV DPH,A;相加和存DPH CLR A;清A,MOVC A,ADPTR;查表,读第1字节 MOV R4,A;第1字节存入R4 CLR A;清A
25、INCDPTR;(DPTR)1 MOVC A,ADPTR;查表,读第2字节 MOV R5,A;第2字节存入R5 RET TBDP2:DW;数据表 DW,特点:程序执行流程中必然包含有条件判断,符合条件要求和不符合条件要求分别有不同的处理路径。在程序设计时,往往借助程序框图(判断框)来指明程序的走向。一般情况下,每个分支均需单独一段程序,在程序的起始地址赋予一个地址标号,以便当条件满足时转向指定地址单元去执行,条件不满足时仍顺序往下执行。,4.2.2 分支结构程序设计,单分支结构 程序仅有两个出口,两者选一。通常用条件判跳指令来选择并转移。可实现单分支程序转移的指令有位条件转移指令,如:JC、J
26、NC、JB、JNB和JBC等,还有一些条件转移指令,如:JZ、JNZ、DJNZ等。有3种典型形式(见图42)。,图42(a),当条件满足时执行分支程序1,否则执行分支程序2。图42(b),当条件满足时跳过程序段1,从程序段2开始继续顺序执行;否则,顺序执行程序段1和程序段2。图42(c),当条件满足时程序顺序执行程序段2;否则,重复执行程序段1,直到条件满足为止。实际是循环结构程序。,设对addrl,addrl1的双字节数取补后存入addr2和 addr2十1单元中,其中高位字节在高地址单元中。8位微机对双字节数取补需分两次进行。首先对低字节数取补,然后判其结果是否为全“0”。若为“0”,则高
27、字节数取补;否则,高位字节数取反。START:MOV R0,addrl;原码低字节地址码送R0 MOVR1,addr2;补码低字节地址码送R1 MOV A,R0;原码低字节内容送ACPL A INC A;A内容取反加l,即取补 MOV R1,A;低字节补码存addr2单元,例.求双字节补码程序,INC R0;指向原码高字节 INC R1;指向补码高字节 JZ LOOP1;当(A)0,转LOOP1 MOV A,R0;原码高字节送A CPL A;高字节内容取反 MOV R1,A;字节反码存(addr2十1)单元 SJMP LOOP2;转LOOP2,结束 LOOP1:MOV A,R0;低字节补码为0
28、 CPL A;对高字节数取补 INC A MOV R1,A;高字节补码存(addr2+1)单元LOOP2:END;结束,Y=a2b(当b10时)Y=a2b(当b10时)ORG0000HSTART:MOV A,#aMOV B,AMULAB;(B)(A)=a2 MOV R0,A;(R1)(R0)=a2 MOV R1,BMOV A,#bCJNEA,#0AH,MMN;b10则转移,例、试编写计算下式的程序,MM:ADD A,R0;b10,a2+b=YMOV R0,AMOV A,#00HADDC A,R1MOV R1,ASJMP MMNN MMN:JNC MM;无借位(即b10)转MMMOV R3,A;
29、R3bMOV A,R0CLR C,SUBBA,,3;(R1)(R0)a2-b MOV R0,AMOV A,R1SUBBA,#00HMOV R1,AMMNN:MOV Y0,R0;(Y1)(Y0)结果MOV Y1,R1HERE:AJMP HERE 注:Y1、Y0需用位定义伪指令赋值。,多分支选择结构 多分支结构:程序的判别部分有两个以上的出口流向。通常有两种形式,参见图43。分支结构程序允许嵌套即一个程序的分支又由另一个分支程序所组成,从而形成多级分支程序结构。,80C51设有两条多分支选择指令:散转指令 JMP ADPTR 散转指令由数据指针DPTR决定多分支转移程序的首地址,由累加器A中内容动
30、态地选择对应的分支程序,可从多达256个分支中选一。比较指令 CJNE A,direct,rel比较两个数的大小,必然存在大于、等于、小于3种情况,这时就需从3个分支中选一。另外,还可以使用查地址表的办法、查转移指令表的办法或通过堆栈来实现多分支程序转移。,设分支转移序号在R3中,分支程序入口地址放在BRTAB表中。MOV DPTR,#BRTAB;分支入口地址表首地址MOV A,R3RL A;2MOV R1,AINC A;取低位地址MOVC A,A+DPTRPUSH A;低位地址入栈MOV A,R1MOVC A,A+DPTR;取高位地址,并入栈PUSH ARET;分支入口地址出栈送入PCBRT
31、AB:DW BR0,BR1,;分支程序入口地址表注:RET指令与两条PUSH指令配对,压栈时先“低”后“高”。而DW伪指令在字节存放时,先“高”后“低”。,例.通过堆栈操作实现分支程序转移,由40H单元中动态运行结果值来选择分支程序(40H)0,转处理程序0(40H)1,转处理程序1(40H)n,转处理程序nSTART:MOV DPTR,addr16;多分支转移指令表首址送;DPTR MOV A,40H;40H单元内容送A CLR C;清CY RLC A;A内容左移一位,例.通过查转移指令表实现多分支程序转移,JNC TABLE;若CY0,转TABEL INC DPH;若CYl,DPH内容十1
32、 TABEL:JMP A十DPTR;多分支转移ADDR16:AJMP LOOP0;转分支程序0 AJMP LOOP1;转分支程序1 AJMP LOOPn;转分支程序n 由于选用绝对转移指令AJMP,每条指令占用两个字节,因此,要求A中内容为偶数,在程序中将选择参量(A中内容)左移一位。如果最高位为1,则将它加到DPH中,这样分支量可在0255中选一。,根据AJMP指令的转移范围,要求分支程序段和各处理程序入口均位于2KB范围内。如果要求不受此限制,可选用长跳转指令LJMP,但它需占用3个字节。START:MOV DPTR,ADDR16;分支程序段首址送DPTR MOVA,40H;选择参量送A
33、MOV B,03H;乘数3送入B MUL AB;参量3 MOV R7,A;乘积低8位暂存R7中,MOV A,B;乘积高8位送A ADD A,DPH;乘积高8位加到DPH中 MOV DPH,A MOV A,R7 JMP ADPTR;多分支选择ADDR16:LJMP LOOP0;转分支程序0 LJMP LOOP1;转分支程序1 LJMP LOOPn;转分支程序n,CLRA;结果单元20H29H清零MOVR0,#10MOVR1,#20HLP:MOVR1,AINCR1DJNZR0,LPMOVR0,#100;100个数的计数器READ:MOV A,P1;读入P1,例.对从P1口输入的100个09的数进行
34、概率统计。统计的数值分别存入20H29H中。,CHK0:CJNE A,#0,CHK1;比较,不为“0”,继续比较INC20H;是“0”,则“0”计数单元加1SJMPEND0;是否全部统计完?CHK1:CJNE A,#1,CHK2INC21H;是“1”,则“1”计数单元加1SJMPEND0CHK2:CJNE A,#2,CHK3INC22H;是“2”,则“2”计数单元加1SJMPEND0,CHK3:CJNE A,#3,CHK4INC23H;是“3”,则“3”计数单元加1SJMPEND0CHK4:CJNE A,#4,CHK5INC24H;是“4”,则“4”计数单元加1SJMPEND0CHK5:CJN
35、E A,#5,CHK6INC25H;是“5”,则“5”计数单元加1SJMPEND0,CHK6:CJNE A,#6,CHK7INC26H;是“6”,则“6”计数单元加1 SJMPEND0CHK7:CJNE A,7,CHK8INC27H;是“7”,则“7”计数单元加1SJMPEND0,CHK8:CJNE A,#8,CHK9INC28H;是“8”,则“8”计数单元加1SJMPEND0CHK9:CJNE A,#9,ERRINC29H;是“9”,则“9”计数单元加1END0:DJNZ R0,READ;判是否全部统计完?HERE:SJMPHEREERR:;非09,出错,循环:强制CPU重复多次地执行一串指
36、令的基本程序结构。循环程序结构是分支程序中的一个特殊形式。计数循环结构如图44所示,条件循环结构如图4-5所示。,4.2.3 循环结构程序设计,循环程序的4个部分(1)循环初始化在进入循环程序体之前所必要的准备工作:需给用于循环过程的工作单元设置初值,如循环控制计数初值的设置、地址指针的起始地址的设置、为变量预置初值等,有些情况下还要进行现场保护。,(2)循环体 循环结构程序的核心部分,完成实际的处理工作,是需反复循环执行的部分。,(3)循环控制 控制循环程序的循环与结束部分,通过循环变量和结束条件进行控制。在重复执行循环体的过程中,不断修改循环变量,直到符合结束条件,就结束循环程序的执行。在
37、循环过程中,除不断修改循环变量外,还需修改地址指针等有关参数。实现方法主要有循环计数控制法和条件控制法。循环次数不确定的情况:满足条件就结束循环。采用条件控制法。循环次数己知的情况:采用计数控制法。,(4)结束部分 对循环程序执行的结果进行分析、处理和存放。有些情况下需恢复现场。图44是计数循环结构形式。主机对循环程序的初始化和结束部分均只执行一次,而对循环体和循环控制部分则常需重复执行多次,不管条件如何,它至少执行一次循环体循环程序设计的重点。图45是条件循环结构形式。条件循环先检查控制条件是否成立,决定循环程序是否执行。,计数控制循环结构 计数循环程序的特点是循环次数已知,必须在初始化部分
38、设定计数的初值,循环控制部分依据计数器的值决定循环次数。一般均设置为减“1”计数器,每循环一次自动减“1”,直到回0时结束循环。DJNZ Rn,rel;以工作寄存器作控制计数器 DJNZ direct,rel;以直接寻址单元作控制计数器,有些情况可以不采用单片微机内的定时器/计数器作定时,而是采用软件延时的办法,执行一段循环程序,而循环程序执行的时间即为延时时间。DELAY:MOV R2 data;预置计数循环控制常数DELAY1:DJNZ R2,DELAY1;当(R2)0,转向本身 RET 根据R2的不同初值(0 FFH),可实现4514个机器周期的延时。,例.软件延时,条件控制循环结构 根
39、据控制循环结束的条件,决定是否继续循环程序的执行。所谓的结束条件可以是搜索到某个参数(比如回车符“CR”),也可以是发生的某种变化(如故障引起电路电平变化)等,什么时侯结束循环是不可预知的。一般常用比较转移指令或条件判跳指令进行控制和实现。,把内部RAM中起始地址为DATA的数据串传送到外部RAM以BUFFER为首地址的区域,直到发现“$”字符的ASCII码为止,数据串的最大长度在内存20H中。MOV R0,#DATA;数据区首地址MOV DPTR,#BUFFER;数据区长度指针LOOP:MOV A,R0CJNEA,#24H,LOOP2;判是否为“$”符(24H)SJMPLOOP1;是“$”符
40、,则结束LOOP2:MOV A,R0;不是“$”符,则传送MOVX DPTR,A,例,INC R0 INC DPTR DJNZ 20H,LOOP;数据串未查完,继续LOOP1:注:一个是条件循环控制,以找到ASCII码“$”符为循环结束条件;笫二个是计数循环结构,万一找不到ASCII码“$”符,则由数据串的最大长度作为计数循环控制。,循环嵌套结构循环嵌套就是在循环内套循环的结构形式,也称多重循环。循环的执行过程是从内向外逐层展开的。内层执行完全部循环后,外层则完成一次循环,逐次类推。层次必须分明,层次之间不能有交叉,否则将产生错误。,子程序及其调用 子程序是一段由专门的子程序调用指令CALL调
41、用而以子程序返回指令RET结束的程序段。将那些需多次应用的、但完成的运算或操作相同的程序段,编制成一个子程序,并尽量使其标准化,存放于某存储区域。调用子程序的程序称为主程序或调用程序。,4.2.4 子程序设计,调用指令自动将断点地址(当前PC值)压入堆栈保护,以便于程序执行完毕,正确返回原程序,从断点处继续往下执行。返回指令:RET。设置在子程序的末尾,表示子程序执行完毕。它的功能是自动将断点地址从堆栈弹出送PC,从而实现程序返回原程序断点处继续往下执行。子程序的第一条指令地址,通常称为子程序首地址或入口地址,往往采用标号(可用助记符)加以表示,调用(转子)指令的下一条指令地址,通常称为返回地
42、址或断点。子程序与主程序之间的关系如图46所示。,在子程序的执行过程中,可能出现在子程序中再次调用其它子程序的情况。像这种子程序调用子程序的现象通常称为子程序嵌套。子程序入口条件 在凋用子程序之前,必须先将数据或参数送到主程序与子程序的某一共享存储单元或寄存器中,调用子程序后,子程序从共享存储单元或寄存器中取得数,在返回主程序之前,子程序还必须把计算结果送到共享存储单元或寄存器中。,保护现场与恢复现场 在调用子程序时,单片微机只是自动保护断点地址。PSW、A、B等可通过压栈指令进栈保护。工作寄存器保护采用选择不同工作寄存器组的方式来达到的。当子程序执行完后,即返回主程序时,应先将上述内容送回到
43、来时的寄存器中去,这后一过程称为恢复现场。在编写子程序时,还应注意保护(压栈)和恢复(弹出)的顺序,即先压入者后弹出。,子程序的特性 对于通用子程序,为便于各种用户程序的选用,要求在子程序编制完成后提供一个说明文件,一般包含如下内容:子程序名。标明子程序功能的名字。子程序功能。简要说明子程序能完成的主要功能。子程序入口条件和出口结果。说明当主程序或调用程序调用本 子程序时应设置哪些参量,说明子程序执行结果及其存储单元。子程序所用的寄存器、存储单元、标志位等,提示主程序或调用程序是否需要在调用本子程序前对此进行保护。子程序嵌套。指明本子程序需调用哪些子程序。,应用软件来进行数字滤波。中值滤波就是
44、连续输入三个检测信号值,从中选择一个中间值为有效信号。入口条件:三次采集数据分别存储在内部存储器的20H、21H和22H中。出口结果:中间值在R0寄存器中。使用资源:累加器A、R0及内存20H、21H和22H。,例.中值数字滤波子程序,ORG2100HFILLE:PUSHPSW;PSW及ACC保护入栈PUSHACCMOVA,20H;取第一个数据CLRC SUBBA,21H;与第二个数据比较,JNCLOB1;第一个数据比第二个数据大,转;LOB1MOVA,20H;第一个数据比第二个数据小,交换;二个数的位置XCHA,21HMOV20H,ALOB1:MOV A,22HCLRCSUBBA,20H;第
45、三个数据与前二个数据中的较大;数比较JNCLOB3;第三个数据大于前二个数据中的较;大数,转LOB3,MOVA,22HCLRCSUBBA,21H;第三个数据与前二个数据中的较小数比较JNCLOB4MOVA,21HMOVR0,A LOB2:POPACC;恢复ACC和PSWPOPPSWRET,LOB3:MOVA,20HMOVR0,AAJMPLOB2LOB4:MOVA,22H;存入中值 MOVR0,AAJMPLOB2,把外部RAM 30H3FH共 16个单元中的ASCII码依次转换为十六进制数,并拼装压缩存入内部60H67H共8个单元中。ASCTOH:MOVR0,#30H;设ASCII码地扯指针MO
46、V R1,#60H;设十六进制数地址指针 MOVR7,#08H;拼装的十六进制数字节个数。AB:ACALL TRAN;调用转换子程序。SWAP A MOVX R1,A INC R0,例.码制转换,ACALL TRAN;调用转换子程序。XCHD A,R1XCHD A,R1INC R0 INC R1 DJNZ R7,AB HALT:SJMP HALT,TRAN:CLR C;ASCII码数转换为十六进制数子程序 MOVX A,RSUBB A,#30H CJNEA,#0AH,BB AJMP BCBB:JCDONEBC:SUBB A,#07H;0AH,则再减07HDONE:RET,注:转换算法把欲转换的
47、ASCII码数减30H,若小于0则为非十六进制数,若为09,即为转换结果。若0AH,则应再减07H(“41H”“A”),若在0AH0FH间,即为转换结果,若小于0AH或大于0FH,均为非十六进制数。标号为TRAN的子程序实现ASCII码数转换为十六进制数,调用前应把欲转换的ASCII码数放在以R0间接寻址的单元中,转换结果在累加器A中。,数据排序程序常用的有插入排序法、冒泡排序法、快速排序法、选择排序法、堆积排序法、二路归并排序法及基数排序法等。冒泡法是一种相邻数互换的排序方法。从前向后进行相邻数比较,若数据的大小次序与要求的顺序不符时(逆序),就将二数互换,正序时不交换,假定是升序排序,则通
48、过这种相邻数互换方法,使小数向前移,大数向后移,从前向后进行一次冒泡(相邻数互换),把最大数换到最后,再进行一次冒泡,就会把次大数排在倒数第二,直至冒泡结束。,4.2.5 程序设计举例,假定原始数据为5FH,38H,7H,13H,44H,D8H,22H 冒泡过程:5FH,38H,7H,13H,44H,D8HH,22H(逆序,则两数互换)38H,5FH,7H,13H,44H,D8H,22H(逆序,则两数互换)38H,7H,5FH,13H,44H,D8H,22H(逆序,则两数互换)38H,7H,13H,5FH,44H,D8H,22H(逆序,则两数互换)38H,7H,13H,44H,5FH,D8H,
49、22H(正序)38H,7H,13H,44H,5FH,D8H,22H(逆序,则两数互换),第一次冒泡结束:38H,7H,13H,44H,5FH,22H,D8H第二次冒泡结束:7H,13H,38H,44H,22H,5F H,D8H第三次冒泡结束:7H,13H,38H,22H,44H,5FH,D8H第四次冒泡结束:7H,13H,22H,38H,44H,5FH,D8H第五次冒泡结束:7H,13H,22H,38H,44H,5FH,D8H,说明:每次冒泡都从向后排定了一个大数(升序),每次冒泡所需进行的比较次数都递减,例如有n个数排序,则第一次冒泡需比较(n-1)次,第二次冒泡则需(n-2)次,实际编程中
50、为了简化程序,往往把各次比较次数都固定为(n-1)次。对于n个数,理论上说应进行(n-1)次冒泡才能完成排序,但实际上往往不到(n-1)次就已排好序。判定排序是否完成的最简单方法是每次冒泡中是否有互换发生,如果有互换发生,说明排序还没完成。控制排序结束常不使用计数方法,而使用设置互换标志的方法,以其状态表示在一次冒泡中有无数据互换进行。,在一组测量数据中,挑选出大于标准m的数值作为合格的产品,而那些小于m 的数值作为不合格产品,则被剔除掉。设数据组为X1、X2、X10共10个。ORG0000H0000H C2 00 PX:CLR 00;设交换过标志0002H 7B 09 MOVR3,#09H;