




已阅读5页,还剩64页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章单片机程序设计基础,4.1编程的步骤、方法和技巧4.2汇编语言源程序的编辑和汇编4.3汇编语言程序设计举例4.4C51高级语言简介,4.1编程的步骤、方法和技巧,4.1.1编程的步骤4.1.2编程的方法和技巧4.1.3汇编语言程序的基本结构,4.1.1编程的步骤,一、分析问题二、确定算法三、画程序流程图四、编写程序,4.1.2编程的方法和技巧,一、模块化的程序设计方法二、编程技巧,一、模块化的程序设计方法,1、程序功能模块化的优点2、划分模块的原则,1、程序功能模块化的优点,单个模块结构的程序功能单一,易于编写、调试和修改。便于分工,从而可使多个程序员同时进行程序的编写和调试工作,加快软件研制进度。程序可读性好,便于功能扩充和版本升级。对程序的修改可局部进行,其它部分可以保持不变。对于使用频繁的子程序可以建立子程序库,便于多个模块调用。,2、划分模块的原则,每个模块应具有独立的功能,能产生一个明确的结果,即单模块的功能高内聚性。模块之间的控制耦合应尽量简单,数据耦合应尽量少,即模块间的低耦合性。控制耦合是指模块进入和退出的条件及方式,数据耦合是指模块间的信息交换方式、交换量的多少及交换频繁程度。模块长度适中。20条100条的范围较合适。,二、编程技巧,1、尽量采用循环结构和子程序。2、尽量少用无条件转移指令。3、对于通用的子程序,考虑到其通用性,除了用于存放子程序入口参数的寄存器外,子程序中用到的其他寄存器的内容应压入堆栈保护。4、在中断处理程序中,除了要保护处理程序中用到的寄存器外,还要保护标志寄存器。5、用累加器传递入口参数或返回参数比较方便,在子程序中,一般不必把累加器内容压入堆栈。,4.1.3汇编语言程序的基本结构,一、顺序程序二、分支程序三、循环程序,子程序结构,4.2汇编语言源程序的编辑和汇编,4.2.1源程序的编辑4.2.2源程序的汇编4.2.3伪指令,4.2.1源程序的编辑,在微型计算机上,借助编辑软件,编写或修改汇编语言源程序。如行编辑或屏幕编辑软件。,4.2.2源程序的汇编,汇编:将汇编语言源程序转换为机器码表示的目标程序的过程。对单片机有:一、手工汇编二、机器汇编,反汇编:将二进制机器语言程序翻译成汇编语言程序的过程称反汇编。,4.2.3伪指令,伪指令不是真正的指令,无对应的机器码,在汇编时不产生目标程序,只是用来对汇编过程进行某种控制。89S51有8个伪指令:ORGENDEQUDATADBDWDSBIT,ORG汇编起始命令,格式:ORG16位地址功能:规定该伪指令后面程序的汇编地址,即汇编后生成目标程序存放的起始地址。例如:ORG2000HSTART:MOVA,#64H规定了START的地址是2000H,又规定了汇编后的第一条指令码从2000H开始存放。,END汇编结束指令,格式:END功能:通知汇编程序结束汇编。在END之后所有的汇编指令均不予以处理。,EQU赋值命令,格式:字符名称EQU项(数或汇编符号)功能:把“项”赋给“字符名称”。注意:字符名称不等于标号(其后没有冒号);其中的项可以是数,也可以是汇编符号。EQU赋值过的符号名可以用作数据、代码地址、位地址或一个立即数。可以是8位的,也可以是16位的。例1:AAEQUR1MOVA,AA;AA代表工作寄存器R1例2:A10EQU10DELYEQU07EBHMOVA,A10;A10作为片内的一个直接地址LCALLDELY;DELY作为一个16位子程序的入口地址,DATA数据地址赋值命令,格式:字符名称DATA表达式功能:与EQU类似,但有以下差别:1、EQU定义的字符名必须先定义后使用,而DATA定义的字符名可以后定义先使用。2、用EQU伪指令可以把一个汇编符号赋给一个名字,而DATA只能把数据赋给字符名。3、DATA语句可以把一个表达式的值赋给字符名称,其中的表达式应是可求值的。DATA伪指令在程序中用来定义数据地址。,DB定义字节命令,格式:DB(项或项表)功能:通知汇编程序从当前ROM地址开始,保留一个字或字节串的存储单元,并存入DB后的数据。注意:项或项表可以是一个字节,用逗号隔开的字节串或括在单引号中的ASCII字符串。例如:ORG2000HDB0A3HLIST:DB26H,03HSTR:DBABC经汇编后(2000H)=A3H,(2001H)=26H,(2002H)=03H,(2003H)=41H,(41H43H为A,B,C的ASCII码)(2004H)=42H,(2005H)=43H,,DW定义字命令,格式:DW16位数据项或项表功能:把DW后的16位数据项或项表从当前地址连续存放。每项数值为16位二进制数,高8位先放,低8位后存放。DW用于定义一个地址表。例如:ORG1500HTABLE:DW7234H,8AH,10H经汇编后(1500H)=72H,(1501H)=34H,(1502H)=00H,(1503H)=8AH,(1504H)=00H,(1505H)=10H,,DS定义存储空间命令,格式:DS表达式功能:在汇编时,从指定地址开始保留DS之后表达式的值所规定的存储单元以备后用。例如:ORG1000HDS08HDB30H,8AH汇编后,从1000H保留8个单元,然后从1008H按DB命令给内存赋值,即(1008H)=30H(1009H)=8AH,注:DB,DW,DS伪指令都只对程序存储器起作用,不能对数据存储器进行初始化。,BIT位地址符号命令,格式:字符名BIT位地址功能:把BIT后的位地址值赋给字符名。其中字符名不是标号,其后没有冒号,但字符名是必须的。例如:A1BITP1.0A2BIT02H汇编后,P1口第0位的位地址90H就赋给了A1,而A2的值则为02H。,4.3汇编语言程序设计举例,一简单程序设计举例二分支程序三循环程序四子程序设计举例五代码转换程序设计举例六运算类程序设计举例七、查表程序设计举例八、延时程序设计举例,一、简单程序设计举例,例1:拆字。将片内RAM20H单元的内容拆成两段,每段四位。并将它们分别存入21H与22H单元中。程序如下:,解:ORG2000HSTART:MOVR0,#21H;21HR0MOVA,20H;(20H)AANLA,#0FH;A#0FHAMOVR0,A;(A)(R0)INCR0;R0+1R0MOVA,20H;(20H)ASWAPA;A03A47ANLA,#0FH;A#0FHAMOVR0,A;(A)(R0)SJMP$,例2:16位数求补。设16位二进制数在R1R0中,求补结果存于R3R2中。,解:ORG1000HSTART:MOVA,R0CPLAADDA,#01HMOVR2,AMOVA,R1CPLAADDCA,#00HMOVR3,ASJMP$,例1:片内RAMONE和TWO两个单元中存有两个无符号数,将两个数中的小者存入RES单元。程序如下:,二、分支程序,解:ORG1000HONEDATA22H;定义ONETWODATA23H;定义TWORESDATA30H;定义RESMOVA,ONESTART:CJNEA,TWO,BIGSJMPSTOREBIG:JCSTOREMOVA,TWOSTORE:MOVRES,ASJMP$,例2使用多条CJNE实现多分支程序转移某温度控制系统,采集的温度值(Ta)放在A中,此外,在内部RAM54h单元存放控制温度的下限值(T54),在55h单元中存放控制温度的上限(T55),若TaT55,程序转向JW(降温处理),若TaT54,程序转向SW(升温处理),否则,转向FH(返回主程序).,CJNEA,55H,LOOPHAJMPFHLOOPH:JNCJWCJNEA,54H,LOOP2AJMPFHLOOP2:JCSWFH:RETJW:.;降温处理SW:.;升温处理,例3使用散转指令实现多分支程序设键盘上有3个操作键键值:01功能:读数据键值:02功能:写数据键值:03功能:插入数据假定键值放在A中,MOVDPTR,#3000HCLRCRLCAJMPA+DPTR3000H3001H3002HAJMPDS;转到读数据程序3003H3004HAJMPXS;转到写数据程序3005H3006HAJMPCR;转到插入数据程序,K=?,转向0分支,K=0,转向1分支,转向n-1分支,转向n分支,图中,K的最大值一般为128。,设寄存器R3中存有分支转移序号00H7FH,试编写根据序号转移的程序。,散转程序设计框图,JMP_128:MOVA,R3RLAMOVDPTR,#JMPTABJMPA+DPTRJMPTAB:AJMPROUT00;128个子程序首址AJMPROUT01AJMPROUT7F,说明:此程序要求转移目的地址ROUT00ROUT7F必须驻留在与指令AJMP同一个2KB存储区内,且程序的最大分支值为128。,三、循环程序,例1:数据块传送。将片内RAM20H单元开始的10个字节,传送到片外RAM1000H单元开始的单元中去。,解:程序如下:ORG0800HSTART:MOVR0,#20HMOVDPTR,#1000HMOVR7,#0AHLOOP:MOVA,R0MOVXDPTR,AINCR0INCDPTRDJNZR7,LOOPSJMP$,循环程序,例2:统计字串长度。内存从STRING开始有一字串,该字串以$(ASCII码为24H)结束,试统计该字串长度,结果存于NUM单元中。,解:ORG0800HNUMDATA20HSTRINGDATA21HSTART:CLRAMOVR0,#STRINGLOOP:CJNER0,#24H,NEXTSJMPCOMPNEXT:INCAINCR0SJMPLOOPCOMP:MOVNUM,ASJMP$,四、子程序设计举例,例1:用查表法编一子程序,将40H中的BCD码转换成ASCII码。入口:待转换数在(40H)出口:转换后的数(40H),解:ORG1000HTAB:DB30H,31H,32H,33H,34H,35H,36H,37H,38H,39HSUB1:MOVA,40HMOVDPTR,#TABMOVCA,A+DPTRMOV40H,ARET,若将30H单元BCD码转换成ASCII码,利用SUB1子程序。,ORG2000HMAIN:MOV40H,30HLCALLSUB1MOV30H,40HSJMP$,例:片外RAM2000H单元中有一BCD码,编一子程序将其转换成ASCII码。,ORG0100HBAS2:MOVDPTR,#2000HMOVXA,DPTRADDA,#30HMOVXDPTR,ARET,五、代码转换程序设计举例,六、运算类程序设计举例,例1:片内RAM30H单元开始有10个字节的二进制数。编一子程序,求它们的和。(和256)将和存入20H单元中。,解:方法1ORG1000HASUB1:MOVR0,#30HCLRAMOVR7,#10CLRCLOOP:ADDCA,R0INCR0DJNZR7,LOOPMOV20H,ARET,方法2ORG2000HASUB2:MOVR0,#30HMOVA,R0MOVR7,#09CLRCLOOP:INCR0ADDCA,R0DJNZR7,LOOPMOV20H,ARET,例2:编写将30H,31H单元中的两字节二进制数乘以2的程序(积小于65536)。,解:ORG1000HMSUB:CLRCMOVA,30HRLCAMOV30H,AMOVA,31HRLCAMOV31H,ARET,例1利用查表的方法编写Y=X2(X=0,1,29)的程序。编程说明:设变量X的值存放在内存30H单元中,变量Y的值存入内存31H单元。先用远查表指令MOVCA,A+DPTR编写程序(参考程序1);再用近查表指令MOVCA,A+PC编写程序(见参考程序2)。,七、查表程序设计举例,参考程序1:ORG1000HSTART:MOVA,30HMOVDPTR,#TABLEMOVCA,A+DPTRMOV31H,ATABLE:DB0,1,4,9,16DB25,36,49,64,81END,思考:程序结构有问题吗?,参考程序2:ORG1000HSTART:MOVA,30HADDA,#03H;思考该指令的作用?MOVCA,A+PCMOV31H,ARETDB0,1,4,9,16DB25,36,49,64,81END,例2将1位十六进制数,转换成相应ASC码。用计算求解和查表求解,进行比较。(1)计算求解:编程说明:设待转换的一位十六进制数存放在40H单元中,转换后的ASC码仍存放在40H中。编程思路:十六进制数09ASC码:30H39H,加30H,十六进制数AFASC码:41H46H,加37H。,参考程序如下:ORG0100HMOVA,40HANLA,#0FHCLRCSUBBA,#0AH;A10?JCNEXTADDA,#0AHADDA,#37HSJMPSAVENEXT:ADDA,#0AHADDA,#30HSAVE:MOV40H,ARETEND,(2)查表求解:ORG0100HMOVA,40HANLA,#0FHADDA,#03HMOVCA,A+PCMOV40H,ARETDB0,1,2,3,4,5DB6,7,8,9,A,BDBC,D,E,FEND,八、延时程序设计举例,查表注意到执行DJNZ指令要用两个机器周期执行MOVRn,#data要一个机器周期执行MOVdir,#data要两个机器周期因此可以精确算出程序执行时间。例:以机器周期为单位,计算以下程序的执行时间。MOVR7,#64HLOOP:MOVR6,#0FAHDJNZR6,$DJNZR7,LOOPRET,;1个机器周期;1;250*2=500;2,503*100=50300;2,共50303个机器周期,问题:将以上程序的第二句LOOP:MOVR6,#0FAH改为LOOP:MOVR6,#0则DJNZR6,$语句会执行多少次?要实现延时功能,有时还需要用到空操作指令:,*空操作指令不进行任何操作,但它在程序存储器中占了一个字节的位置,执行时也需要占用一个机器周期的时间。,例1:设单片机晶振频率6M,编写一段程序,大约延时1秒钟。分析:由于DJNZ指令最多的循环次数是256次,而1S256256约等于15S,晶振频率6MHZ,则1个机器周期为2S,我们把内循环定为8个机器周期16S。则16S250250=1S。Delay:MOVR7,#0FAHLOOP:MOVR6,#0FAHLOOP1:NOPNOPNOPNOPNOPNOPDJNZR6,LOOP1DJNZR7,LOOP实际执行时间:(6+2)250+2+1250+1=500751个机器周期,需1.001502秒。,例2:编写延时4ms的子程序。设晶振为12MHZ。,解:晶振为12MHZ,则1个机器周期为1s,1条DJNZ指令为2个机器周期,则执行该指令2000次为4ms,200020*100.ORG1000HDelay:MOVR6,#20DLY1:MOVR7,#100DLY2:DJNZR7,DLAY2DJNZR6,DLY1RET,4.451高级语言简介4.4.1C51的标识符与关键字,标识符标识符由字母、数字、下划线等组成,第一个字符必须是字母或下划线。说明:标识符用来标识源程序中某个对象的名字,这些对象可以是语句、数据类型、函数、变量、数组等。C51语言是一种区分大小写的高级语言。C51语言中有一些库函数的标识符是以下划线开头的,编程者一般不要以下划线开头来命名标识符。在C51编译器中,只支持标识符的前32个字符为有效标识。,关键字关键字是编程语言保留的特殊标识符,它们具有固定名称和含义,在程序编写过程中不允许将关键字另做它用。说明:1.在C51语言中,除了有ANSIC标准的32个关键字以外,还根据单片机的特点扩展了相关的关键字。2.在C51语言的文本编辑中编写C51语言程序时,系统可以把关键字用不同的颜色显示。3.表4.1按用途列出了标准C语言ANSIC的关键字。4.表4.2列出了C51编译器扩展的关键字。,4.4.2C51语言的数据类型,数据类型数据是MCS-51单片机操作的对象,是具有一定格式的数字或数值。数据的不同格式就称为数据类型。数据按照一定的数据类型进行排列、组合和架构后称为数据结构。说明:C51语言与标准C语言的数据类型基本相同,使用方法基本类似。增设了位型,取消了布尔型,大体可以分为基本数据类型、构造数据类型、指针类型、空类型。C51语言的数据类型如表4.3所示。,表4.3C51语言的数据类型,表4.3,C51语言的数据类型,C51语言扩展的数据类型bit:位型sfr:特殊功能寄存器sfr16:16位特殊功能寄存器sbit:可寻址位,例:用关键字sbit定义特殊功能寄存器中的可寻址位1、sbitOV=0 xD2;/*将位地址赋给位变量OV*/2、sfrP1=0 x90;/*定义特殊功能寄存器P1*/sbitSwitch_k1=P10;/*定义位变量Switch_k1在P1.0位*/3、sbitCY=0 xD07;/*定义CY在字节地址0 xD0的第7位*/,4.4.3C51变量的存储种类和存储器类型,变量C51语言规定变量必须先定义后使用。对变量进行定义的格式如下:存储种类数据类型存储器类型变量名表说明:每个变量都有一个变量名,在内存中占据一定的存储单元(地址),并在该内存单元中存放该变量的值。变量名应符合标识符的要求,各变量名之间用逗号“,”分隔,从而构成变量名表。,变量的存储种类存储种类是指变量在程序执行过程中的作用范围。变量的存储种类有4种:autoexternstaticregister,变量的存储器类型存储器类型和存储种类是完全不同的概念,存储种类是指变量在程序执行过程中的作用范围,而存储器类型指明该变量所处的单片机内存空间。C51编译器能识别以下存储器类型,如表4.4所示。,表4.4C51编译器能识别的存储器类型,存储模式C51编译器允许采用3种存储模式:小编译模式Small、紧凑编译模式Compact、大编译模式Large。存储模式确定了变量在内存中的地址空间,在Small模式下,变量存放在单片机的内部RAM中;在Compact模式和Large模式下,变量存放在单片机外部RAM中。在Small模式下,未说明变量的存储器类型时,该变量被默认存放到data区。存储模式的软件定义实例如下:#pragmasmall/small模式下,变量的存储器类型为片内直接寻址RAM区,4.4.4C51语言的基本语句,控制语句ifelse条件语句for()循环语句while()循环语句dowhile()循环语句continue结束本次循环的语句break中止执行开关语句switch或循环的语句switchcase多分支选择语句goto无条件转向语句return函数返回语句,4.4.5C51函数,函数的概念“函数”与汇编语言中的“子程序”、“过程”的意义相同,是按照一定格式编写的完成一定功能的代码段。在构成C51语言程序的若干个函数中,必有一个是主函数main()。C51语言程序的执行从主函数main()开始,主函数main()可以根据需要来调用其他函数,函数在使用前要先定义。,函数的定义,概念:创建函数称为函数的定义,函数定义的过程就是给出函数原型(functionprototype)。无参函数的定义返回值数据类型标识符函数名()函数体语句有参函数的定义返回值数据类型标识符函数名(形式参数列表)形式参数说明函数体语句,中断函数的定义,返回值数据类型标识符函数名(形式参数列表)interruptnusingm中断服务程序语句体说明:中断函数由单片机中断系统自动调用,用户在主程序或函数中,不能调用中断函数。关键字interrupt后面的n是中断号,n的取值范围为031。C51编译器从8n+3处产生中断矢量,89S51单片机的中断源、中断号、中断矢量的关系如表4.5所示。usingm选项用于实现工作寄存器组的切换,m是中断服务程序中选用的工作寄存器组区号。,表4.589S51的中断源、中断号、中断矢量,例:单片机点对点双机串行通信。,单片机点对点的双机串行通信图,4.4.6C51高级语言程序设计举例,双机串行通信程序可以在甲机、乙机中运行,发送时源程序中将常量Select_TR定义为1;接收则定义为0。,#include#defineucharunsignedchar#defineSelect_TR1/Select_TR=1时接收数据,Select_TR=0时发送数据ucharidatabuffer10;/定义全局变量uchardatacheak_sum;voidserial_initialize(void);/函数声明voidsend(ucharidata*data_buffer);voidreceive(ucharidata*data_buffer);main()serial_initialize();/串行口初始化if(Select_TR=0)send(buffer);/发送数据elsereceive(buffer);/接收数据,/*串行口初始化函数原型*/voidserial_initialize(void)TMOD=0 x20;/T1运行于定时工作方式2TH0=0 xe8;TL0=0 xe8;TR1=1;SCON=0 x50;/串行口工作方式1,允许接收,/*发送数据函数原型*/voidsend(ucharidata*data_buffer)uchari;doSBUF=0 xAA;/发送联络信号0 xAAwhile(TI=0);TI=0;/等待1帧数据发送完毕while(RI=0);RI=0;/等待联络应答信号0 xBBwhile(SBUF0 xBB!=0);/接收方没准备好则继续联络docheak_sum=0;/清0校验和变量for(i=0;i10;i+)/循环发送10Bytes数据SBUF=data_bufferi;/发送1Bytecheak_sum+=data_bufferi;/计算校验和while(TI=0);TI=0;SBUF=cheak_sum;/发送校验和while(TI=0);TI=0;while(RI=0)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 主管会计面试题目及答案
- A A place to go (Viewing and listening)说课稿-2025-2026学年初中英语沪教版五四学制2024六年级上册-沪教版五四学制2024
- 珠海客服面试题库及答案
- 中岩培训考试题库及答案
- 2025年智能电网分布式电源并网技术创新与智能电网创新驱动策略
- 中软运维考试题及答案
- 2025年智能电网电力系统稳定控制技术创新成果综述
- 管理学山大试题及答案
- 2025年智能仓储机器人协同作业在仓储供应链管理中的创新解决方案
- 第9章化学与社会可持续发展说课稿-2024-2025学年九年级化学沪教版(2024)下册
- 门窗工程管理办法
- 小学体育家长会课件
- 依法治校视角下高校后勤管理法律风险的识别与化解策略
- 2025年法学专业基础课程试题及答案
- 腰椎管狭窄症病例讨论
- 部编版语文(2024)二年级上册第一单元综合素养测评A卷(含答案)
- 工程质量事故案例课件
- 多囊卵巢综合症及护理方法
- 2025年城市更新与历史文化街区保护相结合的社区治理模式研究报告
- DB1311T 091-2025 旧水泥混凝土路面多锤头碎石化施工技术规范
- 前臂骨折护理查房
评论
0/150
提交评论