版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章汇编程序的设计与调试一、汇编语言程序设计概述二、实用程序设计三、C51介绍程序设计语言1.机器语言(MachineLanguage)这是一种用二进制代码“0”和“1”表示指令和数据的程序设计语言。计算机只能识别二进制代码,这种语言是能被计算机直接识别和执行的机器级语言。特点:机器语言能够被计算机立即识别并加以执行,具有执行速度快、占用内存少等优点。但对于使用者来说,用机器语言编写程序具有编写难、识别难、记忆难、查错难、交流难等缺点。2.汇编语言(AssemblyLanguage)汇编语言是一种用助记符来表示的面向机器的程序设计语言。不同的机器所使用的汇编语言一般是不同的。但计算机的CPU不能直接识别汇编语言,所以计算机不能立即执行汇编语言程序。用汇编语言编写的源程序,在由计算机执行之前,必须将它翻译成机器语言程序。特点:这种语言弥补了机器语言的不足,用汇编语言编写程序比用机器语言方便、直观、易懂、易用、易记。可以编写出结构紧凑、运行时间精确的程序。所以,这种语言非常适合于实时控制的需要。3.高级语言(High-LevelLanguage)高级语言是面向过程并能独立于计算机硬件结构的通用程序设计语言,是一种接近人类语言和数学表达式的计算机语言。比如:BASIC、FORTRAN、COBOL、PASCAL、C语言等。高级语言不能被计算机直接识别和执行,需要用编译程序或解释程序将高级语言编写的源程序翻译为机器语言。特点:它比汇编语言易学、易懂,具有通用性强、易于移植等优点。高级语言的语句功能强,它的一条语句往往相当于许多条指令,因而用于翻译的程序要占用较多的存储空间,而且执行时间长,且不易精确掌握,故在高速实时控制中一般是不适用的。
基本概念在目前单片机的开发应用中,经常采用C51语言和汇编语言共同编写程序。要想很好地掌握和应用单片机首先要掌握汇编语言。
汇编语言是面向机器的程序设计语言,对于CPU不同的单片机,其汇编语言一般是不同的。用汇编语言编写的程序称为汇编语言源程序。汇编语言源程序是由汇编语言语句构成的。汇编语言语句可分为两大类:指令性语句和指示性语句。指令性语句是由指令组成的由CPU执行的语句,指示性语句是由伪指令组成的,它不被CPU执行,用来告诉汇编程序如何对程序进行汇编的指令;由于它不能生成机器语言,故又被称为伪指令语句。一、汇编语言程序设计概述1.指令性语句格式
[标号:]操作码助记符[目的操作数][,源操作数][;注释]
每条汇编语句一般由若干部分组成,每一部分称为一个字段。每个字段之间应该严格地用分界符加以分隔。分界符包括冒号、空格符、逗号、分号等。标号段与操作码之间要加冒号“:”;操作码与操作数之间要用空格相隔;各操作数之间要用逗号“,”相隔;操作数与注释段之间要加分号“;”相隔。标号是语句所在地址的标志符号
(1)标号后边必须跟以冒号“:”(2)由1-8个ASCII字符组成(3)同一标号在一个程序中只能定义一次(4)不能使用汇编语言已经定义的符号作为标号必须以分号“;”开头,换行书写,但必须注意也要以分号“;”开头。汇编时,注释字段不会产生机器代码。操作字段:(1)十六进制,后缀“H”例:MOVA,#23H二进制,后缀“B”例:MOVA,#01010101B十进制,后缀“D”,也可省略。(2)若十六进制的操作数以字符A-F中的某个开头时,则需在它前面加一个“0”,以便在汇编时把它和字符A-F区别开来。例:MOVA,#0FCH(3)采用工作寄存器和特殊功能寄存器的代号来表示,也可用其地址来表示。例:程序状态子可用PSW表示,也可用D0H来表示(4)美元符号$的使用用于表示该转移指令操作码所在的地址。例如,如下指令:HERE:SJMPHERE可写为:
SJMP$2.伪指令的指示性语句格式
[标号:]伪操作操作数[,操作数,......][;注释]
伪指令不是真正的指令,是在汇编时供汇编程序识别的指令,又称为汇编指令。它不属于指令系统,也无对应的机器码,只是用来对汇编过程进行某种控制。利用伪指令告诉汇编程序如何进行汇编,为编程提供方便。
常用伪指令定位伪指令ORG定义字节数据伪指令DB定义字数据伪指令DW定义空间伪指令DS符号定义伪指令EQU或=定义标号伪指令DL数据赋值伪指令DATA数据地址赋值伪指令XDATA汇编结束伪指令END①ORG(Origin)汇编起始指令ORG是程序汇编起始地址定位伪指令,功能:是规定对汇编语言源程序进行汇编时,目的程序在程序存储器中存放的起始地址。格式:[标号:]ORG16位地址或标号注意:在一个源程序中,可多次使用ORG指令,以规定不同程序段的起始位置,地址应从小到大顺序排列,不允许重叠。
例如:
ORG 0000H START:SJMP MAIN … ORG 0030H MAIN:MOVSP,#30H…②END(End)汇编结束指令END是汇编语言程序结束伪指令。功能:是表示程序已结束,汇编程序对END后面的指令不再汇编。格式:[标号:]END注意:在一个源程序中,只能有一条END指令,而且必须放在整个程序的末尾。③EQU(Equate)赋值指令
EQU是赋值(也称等值)伪指令。功能:把操作数段中的数据或地址赋值给标号字段中的字符名称。格式:字符名称EQU数值或汇编符号
注意:字符名称必须先赋值后使用,故EQU指令通常放在源程序的开头。EQU可定义8位或16位的数据或地址,
例如:ORG 8500H
AA EQU R1A10 EQU 10HDELAYEQU 87E6HMOV R0,A10 ;R0←(10H)MOV A,AA ;A←(R1)LCALL DELAY ;调用起始地址为87E6H的子程序END
④DATA(Data)数据地址赋值指令
DATA是数据地址赋值伪指令。功能:把操作数段中的表达式的值赋给标号字段中的字符名称。
格式:字符名称DATA表达式
注意:DATA指令功能与EQU指令类似,它们的主要区别如下:DATA定义的字符名称可以先使用后定义,DATA指令可以放在源程序的任何位置,使用灵活。DATA只能用来定义8位的数据或地址。EQU可以把汇编符号赋给字符名称,而DATA只能把数据赋给字符名称。DATA可以把表达式的值赋给字符名称,这个表达式是可以进行求值运算例:A1DATA345HA1DATAA1+1
⑤XDATA数据地址赋值指令
XDATA是数据地址赋值伪指令。功能:把操作数段中的表达式的值赋给标号字段中的字符名称。格式:字符名称XDATA表达式
注意:XDATA指令功能与DATA指令类似,它们的主要区别是XDATA可定义16位的数据或地址。
⑥BIT(Bit)位地址赋值指令
BIT是位地址赋值伪指令。功能:把位地址赋给字符名称。格式:字符名称BIT位地址例如:
AB BIT 30H ;AB与30H等值
AC BIT P1.0;AC与P1.0等值
MOV C,AB;把位地址区30H单元中的数据送入位累加器C中
CLR AC;把P1.0中的内容清零
⑦DB(DefineByte)定义字节指令
DB是定义字节伪指令。功能:从程序存储器指定地址单元开始存放若干个字节的数值或ASCII码字符。格式:[标号:]DB字节数据或ASCII码字符
注意:多个字节数据或ASCII码字符之间要用逗号相隔,DB指令常用于定义8位的数据常数表。
例如:ORG7F00HTAB:DB 01110010B,16H,45,‘8’,‘A’汇编后存贮单元内容为:(7F00H)=72H、(7F01H)=16H、(7F02H)=2DH(7F03H)=38H、(7F04H)=41H⑧DW(DefineWord)定义字指令
DW是定义字伪指令。功能:从程序存储器指定地址单元开始存放若干个字的数值。格式:[标号:]DW字节数据或ASCII码字符
注意:多个字数据之间要用逗号相隔,DW指令常用于定义16位的地址表。
例如:ORG 6000HTAB:DW 1254H,32H,161汇编后存贮单元内容为:(6000H)=12H(6001H)=54H
(6002H)=00H(6003H)=32H (6004H)=00H(6005H)=0A1H⑨DS(DefineSpace)定义存储空间指令
DS是定义存储空间伪指令。功能:从程序存储器指定地址单元开始保留表达式的值所规定的存储单元。格式:[标号:]DS表达式
例如:
ORG1000HTAB:DS06H DB25H,35H在上述源程序中,程序存储器从1000H单元开始保留6个单元,1006H单元存放25H,1007H单元存放35H。注:对8051单片机,DB、DW、DS等伪指令只能用于程序存储器,而不能对数据存储器使用。3.汇编语言源程序的汇编
汇编语言源程序必须要转换为机器码(即目的程序),计算机才能执行,这个转换过程称为汇编。汇编语言源程序的汇编可分为手工汇编和机器汇编两类。手工汇编是指用人脑通过查指令编码表(见附录中的指令表)把汇编语言源程序翻译成机器码的过程,又称为人工代真。机器汇编是用机器代替人脑并由专门的程序来进行的,这种程序称为汇编程序(不同的指令系统汇编程序不同)。机器汇编由计算机自动完成,汇编程序把用汇编语言编写的源程序翻译成由机器语言表示的目的程序。用编辑软件进行源程序的编辑。编辑完成后,生成一个ASCII码文件,扩展名为“.ASM”。反汇编是在分析程序存储器已有的程序时,将机器语言翻译成汇编语言的转换过程。
无论是高级语言还是汇编语言写的源程序都必须转换成目标程序,单片机才能执行。目前很多公司都将编辑器、汇编器、编译器、连接/定位器、符号转换程序做成了软件包,称为集成开发环境,如Keil
uVision、SiliconLaboratoriesIDE等。二、实用程序设计程序设计方法和技巧源程序的基本格式汇编语言程序设计举例程序设计方法和技巧
1.程序设计的一般步骤(1)分析工作任务,明确要达到的工作目的、技术指标等。(2)确定解决问题的算法。算法就是如何将实际问题转化成程序模块来处理,要对不同的算法进行分析、比较,找出最适宜的算法。(3)画程序流程图。其图形的符号规定均与高级语言流程图相同,如桶形框表示程序的开始或结束,矩形框表示需要进行的工作,菱形框表示需要判断的事情,指向线表示程序的流向等。(4)分配内存工作单元,确定程序与数据的存放地址。(5)编写源程序。(6)上机调试、修改源程序。2.程序设计的一般原则按照尽可能使程序简短和缩短运行时间两个原则编写程序。应用程序一般都由一个主程序(包括若干个功能模块)和多个子程序构成,即采用模块化的程序设计方法。每一功能模块或子程序都能完成一个明确的任务,实现某个具体功能,如检测输入信号、码制转换、输出控制信号、发送数据、接收数据、延时、显示、打印等。
3.模块化程序设计方法的特点单个模块结构的程序功能单一,易于编写、调试和修改。对程序的局部修改,可以使无关的部分保持不变。程序可读性好,便于功能扩展和版本升级。对于使用频繁的子程序可以建立子程序库,便于多个模块调用。可实现多人同时进行程序的编写和调试工作,缩短程序编写时间。4.划分模块应遵循的原则高内聚性。每个模块应具有独立的功能,能产生一个明确的结果。低耦合性。模块之间的控制耦合应尽量简单,数据耦合应尽量少。控制耦合是指模块进入和退出的条件及方式,数据耦合是指模块间的信息交换(传递)方式、交换量的多少及交换的频繁程度。模块长度适中。模块语句的长度为20~100条的范围较合适。模块太长时,分析和调试比较困难,失去了模块化程序结构的优越性;过短则模块的连接太复杂,信息交换太频繁。
源程序的基本格式 ORG0000H LJMPSTART;转向主程序 ORG0003H LJMPINTIE0;转向外部中断服务程序 …… ORG0050HSTART:MOVA,#00H …… ORG4500HINTIE0:… ……DBLO:DB43H,64H,…;表格参量END;结束分支结构程序循环结构程序简单结构程序查表程序子程序汇编语言程序设计举例关键字查找程序设计数据极值查找程序设计数据排序程序设计子程序设计主要内容:
1.主程序与子程序的关系2.子程序嵌套3.子程序的参数传递子程序是指完成某一专门任务并能被其他程序反复调用的程序段。调用子程序的程序称为主程序或调用程序。使用子程序的过程称为调用子程序。子程序执行完后返回主程序的过程称为子程序返回。主程序和子程序是相对的,同一程序既可以作为另一程序的子程序,也可以有自己的子程序。也就是说,子程序是允许嵌套的,嵌套深度和堆栈区的大小有关。采用子程序能使整个程序结构简单,缩短程序设计时间,减少对存储空间的占用。
主程序与子程序的关系子程序SUB主程序MAIN返回LCALLSUB调用子程序子程序入口地址RETMAIN: ┇ ;MAIN为主程序或调用程序标号 ┇
LCALLSUB ;调用子程序SUB ┇ ┇SUB: PUSHPSW ;现场保护PUSHACC ;
子程序处理程序段POPACC ;现场恢复 POPPSW ;
RET ;最后一条指令必须为RET典型的子程序的基本结构注意:子程序的第一条指令的地址称为子程序的入口地址,该指令前应有标号。在子程序末尾用RET返回指令从子程序返回主程序。根据需要保护现场和恢复现场。在子程序的开始,使用压栈指令把需要保护的内容压入堆栈;在返回主程序前,使用弹出指令把堆栈中保护的内容送回原来的存储单元中。子程序中有可能要使用累加器A或工作寄存器,在子程序使用它们之前,把它们中可能存有的主程序的中间结果保存起来,这一过程称为保护现场。在子程序执行完并将返回主程序之前,再将这些中间结果取出,送回到累加器A或原来的工作寄存器中,这一过程称为恢复现场。子程序中应尽量使用相对转移指令而不使用其他转移指令,以便子程序放在内存的任何区域都能被主程序调用。要正确地设置堆栈指针,以避免堆栈区与工作寄存器或其他存储单元发生冲突。
ORG 0000HMAIN: MOV A,#0FEH ;送显示初值LP: MOV R0,#10 ;送闪烁次数LP0: MOV P1,A ;点亮LED
LCALL DELAY ;延时 MOV P1,#0FFH;熄灭灯
LCALL DELAY ;延时 DJNZ R0,LP0 RL A SJMP LPEND
实例:P1口连接的8个LED依次循环闪烁10次延时次数-1=0点亮相应的LEDYN熄灭相应的LED延时初值左移1位指向下一个LED设闪烁次数送显示初值开始子程序嵌套子程序嵌套(或称多重转子)是指在子程序执行过程中,还可以调用另一个子程序。问题:子程序调用、返回到主程序中的正确位置,并接着执行主程序中的后续指令呢?为了解决这个问题,我们采用了堆栈技术。子程序嵌套
子程序SUB1
主程序MAINRET
子程序SUB2RET20102013211021132100220020132013PC21131321堆栈指针SP堆栈LCALLSUB1LCALLSUB221132013子程序嵌套范例:LED灯闪烁(二)
ORG 0000HMAIN:MOV A,#0FEH ;送显示初值COUN:ACALLFLASH ;调闪烁子程序 RL A ;A左移,下一个灯闪烁 SJMPCOUN ;循环不止
FLASH:MOV R0,#10 ;送闪烁次数FLASH1:MOV P1,A ;点亮LED
LCALLDELAY ;延时 MOV P1,#0FFH ;熄灭灯
LCALLDELAY ;延时 DJNZR0,FLASH1 ;闪烁次数不够10次,继续 RET
DELAY:MOVR3,#0FFH ;延时子程序DEL2:MOVR4,#0FFHDEL1:NOP DJNZR4,DEL1 DJNZR3,DEL2 RET END子程序的参数传递范例:计算平方和c=a2+b2
,a存放在31H,b存放在32H,结果c存放在33HORG 0000H ;主程序MOV SP,#3FH;设置栈底MOV A,31H ;取数a存放到累加器A中作为入口参数LCALLSQR;计算a2MOV R1,A ;出口参数——平方值存放在A中MOV A,32H ;取数b存放到累加器A中作为出口参数LCALLSQR;计算b2ADD A,R1 ;求和MOV 33H,A ;存放结果SJMP $
;子程序:SQR;功能:通过查表求出平方值y=x2;入口参数:x存放在累加器A中;出口参数:求得的平方值y存放在A中;占用资源:累加器A,数据指针DPTRSQR:PUSHDPH ;保护现场,将主程序中DPTR的高八位放入堆栈PUSHDPL ;保护现场,将主程序中DPTR的低八位放入堆栈MOVDPTR,#TABLE;在子程序中重新使用DPTR,表首地址→DPTRMOVCA,@A+DPTR;查表POPDPL ;恢复现场,将主程序中DPTR的低八位从堆栈中弹出POPDPH ;恢复现场,将主程序中DPTR的高八位从堆栈中弹出RETTABLE:DB0,1,4,9,16,25,36,49,64,81传送子程序参数的方法利用寄存器或片内RAM传送参数。可以把入口参数存放到寄存器或片内RAM中传送给子程序,也可以把出口参数存放到寄存器或片内RAM中传送给主程序。利用寄存器传送参数的地址。把存放入口参数的地址通过寄存器传送给子程序,子程序根据寄存器中存放入口参数的地址便可找到入口参数并对它们进行相应操作;出口参数的地址也可通过寄存器传送给主程序。利用堆栈传送参数。可以用压栈指令PUSH把入口参数压入堆栈传送给子程序,也可以使用压栈指令PUSH把出口参数压入堆栈传送给主程序。
子程序设计注意事项
(1)要给每个子程序起一个名字,也就是入口地址的代号。(2)要能正确地传递参数。即首先要有入口条件,说明进入子程序时,它所要处理的数据放在何处(如:是放在A中还是放在某个工作寄存器中等)。另外,要有出口条件,即处理的结果存放在何处。(3)注意保护现场和恢复现场。在子程序使用累加器、工作寄存器等资源时,要先将其原来的内容保存起来,即保护现场。当子程序执行完毕,在返回主程序之前,要将这些内容再取出,送还到累加器、工作寄存器等原单元中,这一过程称为恢复现场。在单片机的实际应用中,经常要对一些数据进行函数运算,例如求平方、正弦函数等,为了提高单片机执行程序的速度,一般将某函数的全部函数值按一定的规律编成表格存放到程序存储器中。查表程序就是根据某数据的函数运算要求,按索引号从程序存储器中查找与之相对应的函数值的程序结构。设计查表程序时,主要通过两条查表指令实现查表功能。
MOVCA,@A+DPTRMOVCA,@A+PC查表程序例用查表法计算平方(1)
ORG0000HMOV DPTR,#TABLE;表首地址送DPTRMOVA,#05 ;被查数字05AMOVCA,@A+DPTR ;查表求平方SJMP$TABLE:DB0,1,4,9,16,25,36,49,64,81END
例用查表法计算平方(2)
ORG 0000HMOVA,#05 ;05AADD A,#02 ;修正累加器AMOVCA,@A+PC ;查表求平方SJMP$DB0,1,4,9,16,25,36,49,64,81END74H05H24H02H83H80HFEH00H01H04H09H10H19H24H31H40H51H00H0000H0001H0002H0003H0004H0005H0006H0007H0008H0009H000AH000BH000CH000DH000EH000FH0010H0011H例:设有一巡回检测报警装置,需对16路输入量进行测量控制,每路有一个最大允许值。控制时根据测量的路数,找出该路的最大允许值。测量的路数保存在R2中,最大值结果保存在R3R4中。解:利用查表程序完成。LTB: MOV A,R2 ADD A,R2 MOV R3,A ADD A,#6 MOVC A,@A+PC XCH A,R3 ADD A,#3 MOVC A,@A+PC MOV R4,A RETMAX: DW 1520,3721,445,7850 DW 3483,32657,883,9943 DW 1101,40511,6756,331 DW 4468,5871,13224,9981解:利用查表程序完成。LTB: MOV A,R2 ADD A,R2 MOV R3,A MOV DPTR,#MAX MOVC A,@A+DPTR XCH A,R3 INC A MOVC A,@A+DPTR MOV R4,A RETMAX: DW 1520,3721,445,7850 DW 3483,32657,883,9943 DW 1101,40511,6756,331 DW 4468,5871,13224,9981数据极值查找程序设计在指定的数据区中找出最大值(或最小值)。进行数值大小的比较,从这批数据中找出最大值(或最小值)并存于某一单元中。例
片内RAM中存放一批数据,查找出最大值并存放于首地址中。设R0中存首地址,R2中存放字节数。 MOVR2,n ;n为要比较的数据字节数 MOVA,R0 ;存首地址指针 MOVR1,A DECR2 MOVA,@R1 LOOP: MOVR3,A DECR1 CLRC SUBBA,@R1 ;两个数比较 JNCLOOP1 ;C=0,A中的数大,跳LOOP1 MOVA,@R1 ;C=1,则大数送A SJMPLOOP2 LOOP1: MOVA,R3 LOOP2: DJNZR2,LOOP ;是否比较结束? MOV@R0,A ;存最大数
RET例
片内RAM中存放一批数据,查找出最大值并存放于首地址中。设R0中存首地址,R2中存放字节数。分支程序是根据程序的要求改变程序的执行顺序,并根据条件对程序的流向进行判断的程序结构。程序中有转移指令包括无条件转移(AJMP、SJMP、LJMP)、条件转移(JZ、JC、JB等)和散转指令(JMP@A+DPTR)分支程序一般有两个或两个以上的出口。分支程序又分为单分支和多分支结构。分支结构程序单分支选择结构多分支选择结构程序如下:
ORG0000H
AJMPMAIN
ORG0100H
MAIN:MOVA,30H
CJNEA,#24H,DY31;不是“$”,转去DY31
MOV40H,A;是“$”,存入40H单元
AJMPEND0
DY31:MOV31H,A;不是$,存入31H单元
END0:SJMP$
END1.单分支程序单分支程序例:已知内RAM30H单元存有一个ASCII码,试对其进行判断,如果是“$”(24H),将其存入40H,否则存入31H单元。
例已知某信号灯电路如图所示,试编程实现如下功能:
⑴S0单独按下,红灯亮,其余灯灭;
⑵S1单独按下,绿灯亮,其余灯灭;
⑶S0、S1均按下,红、绿、黄灯全亮;
⑷都不按下黄灯亮。
参考程序如下:
ORG0000HLJMPSTARTORG0100HSTART:ORLP1,#11000111B;P1.6、P1.7设为输入,红绿黄灯灭多分支程序
SS0:JBP1.7,SS1;S0未按,转判S1JBP1.6,RED;S0按下,S1未按,转红灯亮DL:CLRP1.2;红灯亮CLRP1.1;绿灯亮CLRP1.0;黄灯亮SJMPSS0;重新检测SS1:JBP1.6,YELLOW;S0未按,S1未按,转黄灯亮GREEN:CLRP1.1;绿灯亮SETBP1.2;红灯灭SETBP1.0;黄灯灭SJMPSS0RED:CLRP1.2;红灯亮SETBP1.1;绿灯灭SETBP1.0;黄灯灭SJMPSS0
YELLOW:CLRP1.0;黄灯亮SETBP1.2;红灯灭SETBP1.1;绿灯灭SJMPSS0END说明:如果真要实现信号灯的点亮,还要在每段灯亮灭指令后加一段延时程序。循环程序的结构一般包括以下几部分。循环初始化——是进入循环处理前必须要有的一个环节,用于完成循环前的准备工作。循环初始化包括给工作寄存器(或其他存储单元)设置计数初值、地址指针、数据块长度等。循环处理——是需要多次重复执行的程序段。循环处理是循环程序的核心,用于完成主要的计算和操作任务。循环控制——是用条件转移指令控制循环是否继续。每循环一次,根据循环结束条件进行一次判断;当满足条件时,停止循环,继续执行其他程序;否则,再作循环。循环结束——用于存放循环程序的执行结果,同时恢复相关工作单元的初值。
循环结构程序循环程序的特点和设计方法。程序结构紧凑,占用存储单元较少,程序中间有分支,循环程序本质上是分支程序的一种特殊形式。DJNZ指令使用得较多,凡是分支程序中可以使用的控制转移类指令,循环程序一般都可以使用。循环控制的形式有多种。计数循环是最常用的一种,它先预置计数初值,再用DJNZ指令控制循环次数;条件循环也是较常用的一种,它先预置结束循环的条件,再用CJNE指令、JZ指令或JB指令控制循环的结束。
先判断后处理先处理后判断两重循循环程序流程图循环程序流程图程序流程图
开始
循环控制
循环结束
循环处理
循环初始化
结束
Y
N
条件满足?
循环控制2
循环结束
循环处理1
循环初始化1
结束
Y
N
循环处理2
循环初始化2
Y
N
循环控制1
开始
条件满足?
条件满足?
多重循环程序中的各重循环不能有交叉,不能从外循环跳入内循环,只能外循环内嵌套内循环。【例】
片内RAM中存放有10个数据,首地址为30H,编程将数据块传送到片外RAM以1000H为首地址的存储单元中。
解:该程序是单重循环程序,片内RAM首地址30H、片外RAM首地址1000H和数据块长度10都是循环初始化的内容。循环控制是对数据块长度进行判断,每传送一个数据,存放数据块长度的寄存器减1;10个数据传送完,存放数据块长度的寄存器内容正好为零,退出循环。
ORG0000H
LJMPMAIN
ORG0100HMAIN:
MOVR1,#30H;置片内RAM地址指针30H
MOVDPTR,#1000H;置片外RAM地址指针1000H
MOVR2,#10;数据块的长度LOOP:
MOVA,@R1;从片内RAM取数据MOVX@DPTR,A;数据传送到片外RAM
INCR1;修改片内RAM地址指针
INCDPTR;修改片外RAM地址指针
DJNZR2,LOOP;循环次数未到10次,转移
SJMP$
END【例】
片内RAM中存放有10个数据,首地址为30H,编程将数据块传送到片外RAM以1000H为首地址的存储单元中。
例工作单元清零。在应用系统程序设计时,有时经常需要将存储器中各部分地址单元作为工作单元,存放程序执行的中间值或执行结果,工作单元清零工作常常放在程序的初始化部分中。设有50个工作单元,其首址为外部存储器8000H单元,则其工作单元清零程序如下:单片机与一般集成电路的区别在于可编程应用,程序是单片机应用系统的灵魂.由于汇编语言是面向机器的语言,因此对单片机系统进行程序设计时必须考虑硬件资源的配置。
程序设计的方法和技巧尽量采用模块化程序设计方法
;
这种设计方法是把一个完整的程序分成若干个功能相对独立的、较小的程序模块,对各个程序模块分别进行设计、编制程序和调试,最后把各个调试好的程序模块装配起来进行联调,最终成为一个有实用价值的程序。模块化程序设计的优点是:对单个程序模块设计和调试比较方便、容易完成,一个模块可以被多个任务共用。尽量采用循环结构和子程序结构
;
采用循环结构和子程序结构,可以使程序的总容量减小,提高程序的效率,节省内存。尽量少用无条件转移指令
;
少用无条件转移指令,可以保证程序的条理更加清晰,从而减少错误发生。充分利用累加器;
累加器是主程序和子程序之间信息传递的桥梁,利用累加器传递入口参数或返回参数比较方便。这时,一般不要把累加器内容压入堆栈。对于通用子程序要保护现场;
由于子程序的通用性,除了保护子程序入口参数的寄存器内容外,还要对子程序中用到的其它寄存器内容一并入栈保护。
对于中断处理,还要保护程序状态字
在中断处理程序中,既要保护处理程序中用到的寄存器内容,还要保护程序状态字PSW。否则,当中断服务程序执行结束返回主程序时,整个程序的执行可能会被打乱。单片机C语言程序设计1、C语言的特点语言简洁、紧凑,使用方便、灵活。运算符丰富。数据结构丰富。具有现代化语言的各种数据结构。可进行结构化程序设计。可以直接对计算机硬件进行操作。生成的目标代码质量高,程序执行效率高。可移植性好。一、C语言概述与最简单的C程序2、C语言的程序结构C语言程序采用函数结构,每个C语言程序由一个或多个函数组成,在这些函数中至少应包含一个主函数main(),也可以包含一个main()函数和若干个其它的功能函数。不管main()函数放于何处,程序总是从main()函数开始执行,执行到main()函数结束则结束。在main()函数中调用其它函数,其它函数也可以相互调用,但main()函数只能调用其它的功能函数,而不能被其它的函数所调用。功能函数可以是C语言编译器提供的库函数,也可以是由用户定义的自定义函数。在编制C程序时,程序的开始部分一般是预处理命令、函数说明和变量定义等。
3、C语言与MCS-51单片机用C语言编写MCS-51单片机程序与用汇编语言编写MCS–51单片机程序不一样。用汇编语言编写MCS–51单片机程序必须要考虑其存储器结构,尤其必须考虑其片内数据存储器与特殊功能寄存器的使用以及按实际地址处理端口数据。用C语言编写的MCS–51单片机应用程序,则不用像汇编语言那样须具体组织、分配存储器资源和处理端口数据,但在C语言编程中,对数据类型与变量的定义,必须要与单片机的存储结构相关联,否则编译器不能正确地映射定位。
C语言编写单片机应用程序时,需根据单片机存储结构及内部资源定义相应的数据类型和变量,而标准的C语言程序不需要考虑这些问题;
C51包含的数据类型、变量存储模式、输入输出处理、函数等方面与标准的C语言有一定的区别。其它的语法规则、程序结构及程序设计方法等与标准的C语言程序设计相同。
用C语言编写单片机应用程序与标准的C语言程序也有相应的区别:
现在支持MCS-51系列单片机的C语言编译器有很多种,如AmericanAutomation、Avocet、BSO/TASKING、DUNFIELDSHAREWARE、KEIL/Franklin等。各种编译器的基本情况相同,但具体处理时有一定的区别,其中KEIL/Franklin以它的代码紧凑和使用方便等特点优于其它编译器,现在使用特别广泛。
本章主要以KEIL编译器介绍MCS-51单片机C语言程序设计。二、C51数据的存储模式和数据类型
1、存储模式
C51变量的存储模式与标准C中变量的存储模式不一样,C51中变量的存储模式是与MCS-51单片机的存储器紧密相关。C51是面向8XX51系列单片机及硬件控制系统的开发语言,它定义的任何变量必须以一定的存贮类型的方式定位在8XX51的某一存贮区中,否则便没有意义。因此在定义变量类型时,还必须定义它的存贮类型。存储器类型存储区域大小对应的汇编语句描述code程序存储区64KBMOVCA,@A+DPTR用来说明常量data直接寻址的内部数据存储区128BMOVXX,#ADDR访问速度快idata间接寻址的内部数据区256BMOVXX,@Rn可访问整个内部数据区域bdata位寻址的内部数据存储区16B可使用位寻址或字节寻址来访问这一区域xdata外部数据存储或64KBMOVXA,@DPTR使用DPTR来访问外部数据存储器far扩充的RAM和ROM使用用户定义的专用例程或特殊芯片指令扩展命令pdata分页的外部数据存储区256BMOVXA,@Rn利用R0,R1来访问分页的外部数据存储器datacharvar;/*字符变量var定位在片内数据存贮区*/charcodeMSG[]=″PARAMETER:″;/*字符数组MSG[]定位在程序存 贮区*/unsignedlongxdataarray[100];/*无符号长型数组定位在片外RAM区*/floatidatax,y,z;/*实型变量x,y,z,定位在片内用间址访问的内部RAM区*/unsignedintpdatasion;/*无符号整型变量sion定位在分页的外部RAM*/unsignedcharxdatavector[10][4][4]/*无符号字符型三维数组,定位在片外RAM区*/charbdataflags;/*字符变量flags定位在可位寻址内部RAM区*/2、数据类型C51的数据类型分为基本数据类型和组合数据类型,情况与标准C中的数据类型基本相同,但其中char型与short型相同,float型与double型相同,另外,C51中还有专门针对于MCS-51单片机的特殊功能寄存器型和位类型。
C51数据类型(1)数据类型C51专用长度取值范围signedchar单字节-128to+127unsignedchar单字节0to255signedshort2字节-32768to+32767unsignedshort2字节0to65535signedint2字节-32768to+32767unsignedint2字节0to65535signedlong4字节-2147483648to+214746483647unsignedlong4字节0to4294967295float4字节±1.175494E-38to±3.402823E+38*1~3字节对象的地址enum1或2字节-128to+127或-32768to+32767C51数据类型(2)sfr:为字节型特殊功能寄存器类型,占一个内存单元,利用它可以访问MCS-51内部的所有特殊功能寄存器;sfr16:为双字节型特殊功能寄存器类型,占用两个字节单元,利用它可以访问MCS-51内部的所有两个字节的特殊功能寄存器。注:在C51中对特殊功能寄存器的访问必须先用sfr或sfr16进行声明。bit:位变量声明,在内存中都只占一个二进制位,其值可以是“1”或“0”。用bit定义的位变量在C51编译器编译时,在不同的时候位地址是可以变化的sbit:特殊功能位声明,在内存中都只占一个二进制位,其值可以是“1”或“0”。用sbit定义的位变量必须与MCS-51单片机的一个可以寻址位单元或可位寻址的字节单元中的某一位联系在一起,在C51编译器编译时,其对应的位地址是不可变化的。C51对SFR、可寻址位、存储器和I/O口的定义
特殊功能寄存器SFR定义
C51提供了一种自主形式的定义方式,使用特定关键字sfr如sfrSCON=0x98;/*串行通信控制寄存器地址98H*/sfrTMOD=0x89;/*定时器模式控制寄存器地址89H*/sfrP1=0x90;/*P1端口地址90H*/sfr16DPTR=0x82;定义了以后,程序中就可以直接引用寄存器名。C51也建立了一个头文件reg51.h(增强型为reg52.h),在该文件中对所有的特殊功能寄存器的进行了sfr定义,对特殊功能寄存器的有位名称的可寻址位进行了sbit定义,因此,只要用包含语句#include<reg51.h>,就可以直接引用特殊功能寄存器名,或直接引用位名称。要特别注意:在引用时特殊功能寄存器或者位名称必须大写。
C51对位变量的定义有三种方法:1.将变量用bit类型的定义符定义为bit类型:
如bitmn; mn为位变量,其值只能是“0”或“1”,其位地址C51自行安排在可位寻址区的bdata区。
2.采用字节寻址变量.位的方法:
如bdataintibase;/*ibase定义为整型变量*/sbitmybit=ibase^15;/*mybit定义为ibase的D15位*/这里位是运算符“^”相当于汇编中的“·”,其后的最大取值依赖于该位所在的字节寻址变量的定义类型,如定义为char最大值只能为7。
3.对特殊功能寄存器的位的定义
方法1:使用头文件及sbit定义符;多用于无位名的可寻址位。 例如#include<reg51.h>sbitP1-1=P1^1/*P1-1为P1口的第1位*/sbitac=ACC^7;/*ac定义为累加器A的第7位*/方法2:使用头文件reg51.h,再直接用位名称。 例如#in
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 海豹油在皮肤健康中的作用
- 2024年度高铁站门禁设备安装及维护服务合同
- 2024年度广告发布合同标的为品牌宣传推广服务
- 2024年度广告发布合同标的广告内容与投放
- 电网动态信号分析技术
- 2024年度食品生产设备采购合同
- 2024版店铺数字化转型咨询与实施服务合同
- 二零二四年人工智能技术研究与应用合同
- XXXX大学“助研计划”管理实施办法
- 2024年张紧装置项目申请报告范文
- 2024年医疗器械经营质量管理规范培训课件
- 22G101三维彩色立体图集
- 建筑施工安全生产治本攻坚三年行动方案(2024-2026年)
- 化工厂安全消防标志的制定
- 高低加投停及事故处理
- CKD 电子式压力开关PPG-C使用说明书
- 县农村土地确权信息纠错工作实施方案
- 关于统一使用公司手机号码的通知
- 标准吞咽功能评价量表(SSA)2页
- 用友华表伙伴商务手册.
- 心理安全网格化监管实施方案
评论
0/150
提交评论