《第3章MCS51单片机程序设计课件》由会员分享,可在线阅读,更多相关《第3章MCS51单片机程序设计课件(61页珍藏版)》请在金锄头文库上搜索。
1、第3章51单片机程序设计单片机原理、接口及应用单片机原理、接口及应用第3章程序设计林海波林海波第3章51单片机程序设计内内 容容 提提 要要概述汇编语言程序设计C语言程序设计第3章51单片机程序设计3.1概述MCS-51单片机的编程语言可以是汇编语言也可以是高级语言(如C语言),高级语言编程快捷,但程序长,占用存储空间大,执行慢;汇编语言产生的目标程序简短,占用存储空间小,执行快,能充分发挥计算机的硬件功能。无论是高级语言还是汇编语言,源程序都要转换成目标程序(机器语言)单片机才能执行。第3章51单片机程序设计连接连接/定位器定位器L51汇编语言汇编语言源程序源程序汇编器汇编器A51符号转换程
2、序符号转换程序OHS51绝对地址绝对地址目标程序目标程序 .BINC语言程序语言程序浮浮动动地地址址目目标标程程序序编译器编译器C51 HEX图图 3-1 两种语言源程序转换成目标程序两种语言源程序转换成目标程序第3章51单片机程序设计 目前很多公司将编辑器、汇编器、编译器、连接/定位器、符号转换程序做成集成软件包,用户进入该集成环境,编辑好程序后,只需点击相应菜单就可以完成上述的各步,如WAVE、KEIL、IAR等。 汇汇编编:将将汇汇编编语语言言源源程程序序转转换换成成机机器器语语言言目目标标程程序序的的过程称为汇编。过程称为汇编。 汇汇编编程程序序:能能将将汇汇编编语语言言源源程程序序转
3、转换换成成机机器器语语言言目目标标程序的系统软件称为汇编程序。程序的系统软件称为汇编程序。第3章51单片机程序设计汇编的方法汇编的方法:汇编的方法有两种:汇编的方法有两种1.手工汇编手工汇编: 人工查指令表,查出程序中每条指令对应的机人工查指令表,查出程序中每条指令对应的机器代码。早期的计算机使用。器代码。早期的计算机使用。2. .机器汇编机器汇编: 用计算机中的汇编程序对用户源程序进行汇编。用计算机中的汇编程序对用户源程序进行汇编。用机器汇编要提供给汇编一些信息,遵循汇编程用机器汇编要提供给汇编一些信息,遵循汇编程序的一些约定。这些由伪指令指定。序的一些约定。这些由伪指令指定。第3章51单片
4、机程序设计1)确定程序中每条汇编语言指令的指令机器码确定程序中每条汇编语言指令的指令机器码2)确定每条指令在存储器中的存放地址确定每条指令在存储器中的存放地址3)提供错误信息提供错误信息4)提供目标执行文件提供目标执行文件(*.OBJ/*.HEX)和列表文件和列表文件(*.LST) 地址地址 机器码机器码源程序源程序 ORG 2000H 2000H 78 30 MAIN: MOV R0,#30H 2002H E6 MOV A,R0 第3章51单片机程序设计1. 机器指令:指令系统中的全部指令。每条机器指令都机器指令:指令系统中的全部指令。每条机器指令都有对应的机器代码,可以被有对应的机器代码,
5、可以被CPU执行。执行。2. 伪指令:伪指令: 汇编控制指令,没有指令代码,只用于汇编汇编控制指令,没有指令代码,只用于汇编过程,为汇编程序提供汇编信息。过程,为汇编程序提供汇编信息。一、汇编语言指令类型一、汇编语言指令类型 宏汇编功能:将需要反复多次执行的程序段定义成一个宏宏汇编功能:将需要反复多次执行的程序段定义成一个宏指令名(宏定义)。编程时,可在程序中使用宏指令名来替指令名(宏定义)。编程时,可在程序中使用宏指令名来替代被定义的程序段(宏调用)。代被定义的程序段(宏调用)。3.2 伪指令伪指令第3章51单片机程序设计宏定义过程宏定义过程:宏调用过程:宏调用过程: 宏指令名宏指令名 实际
6、参数实际参数 宏指令名宏指令名 实际参数实际参数宏指令名宏指令名 MACRO 形式参数形式参数 ;被定义的程序段;被定义的程序段 ENDM第3章51单片机程序设计二伪指令二伪指令 常用伪指令及功能:常用伪指令及功能:1.起始指令起始指令 ORG nn功能:定义程序或数据块的起始地址。功能:定义程序或数据块的起始地址。指示此语句后面的程序指示此语句后面的程序或数据块以或数据块以nn为起始地址,连续存放在程序存储器中。为起始地址,连续存放在程序存储器中。 指令地址指令地址 机器码机器码源程序源程序 ORG 2000H 2000H 78 30 MAIN:MOV R0,#30H 2002H E6 MO
7、V A,R0 ORG 3000H 3000H 23 TAB: DB 23H,100,A 3001H 64 3002H 41第3章51单片机程序设计2.字字节节定定义义 标标号号: DB(字字节节常常数数,或字符或表达式)或字符或表达式)功功能能:指指示示在在程程序序存存储储器器中中以以标标号号为为起起始始地地址址的的单单元元里里存存放放的的数数为为字字节节数数据据(八八位位二二进进制数)。制数)。例例如如 LN:DB 32,C,25H,-1;LNLN+2 地地址址单单元元依依次次存存放放20H , 43H , 25H ,FFH地址地址数据数据LN20LN+143LN+225LN+3FF3. 字
8、定义字定义 标号:标号:DW (字常数或表达式(字常数或表达式)作用:作用: 指示在程序存储器中以标号为起始地址指示在程序存储器中以标号为起始地址的单元里存放的数为字数据(即的单元里存放的数为字数据(即16位的二进制数),位的二进制数),例如:例如:GH:DW 1234H,5678H,08GH1234GH+25678GH+40008第3章51单片机程序设计 5. 等值指令等值指令 标号标号 EQU(数值表达式)(数值表达式) 表示表示EQU两边的量等值,用于为标号或标识符赋值。两边的量等值,用于为标号或标识符赋值。例如:例如: X1 EQU 2000H X2 EQU 0FH MAIN: MOV
9、 DPTR,#X1 ; DPTR=2000H ADD A,#X2 ; A=A+0FH4保留字节保留字节 标号:标号:DS (数值表达式)(数值表达式)作用:作用: 指示在程序存储器中保留以标号为起始地址的若指示在程序存储器中保留以标号为起始地址的若干字节单元,其单元个数由数值表达式指定。干字节单元,其单元个数由数值表达式指定。例如例如 L1:DS 32 ; 从从L1地址开始保留地址开始保留32个存储单元。个存储单元。第3章51单片机程序设计6. 位定义位定义 标号标号 BIT 位地址位地址 作用:作用: 同同EQU指令,不过定义的是位操作地址。指令,不过定义的是位操作地址。例如例如 AIC B
10、IT P1.1。7.汇编结束汇编结束 END作用:指示源程序段结束。作用:指示源程序段结束。 END指令放在程序的最后。指令放在程序的最后。A51汇编程序还有一些其它的伪指令,列在教材表汇编程序还有一些其它的伪指令,列在教材表3-1中。中。第3章51单片机程序设计汇编语言程序设计步骤汇编语言程序设计步骤一.确定方案和计算方法二.了解应用系统的硬件配置、性能指标三.建立系统数学模型,确定控制算法和操作步骤四.合理分配存储器单元和了解I/O接口地址五.编制源程序1.按功能设计程序,明确各程序之间的相互关系2.用流程图表示程序结构和功能开始1 YN?3.程序中用注释说明指令在程序中的作用,方便阅读、
11、调试和修改第3章51单片机程序设计单片机原理、接口及应用单片机原理、接口及应用单片机原理、接口及应用单片机原理、接口及应用第10章C语言编程林海波林海波第3章51单片机程序设计内内 容容 提提 要要 C51程序结构程序结构 C51的数据类型的数据类型 数据的存贮类型和存贮模式数据的存贮类型和存贮模式 SFR、可寻址位、存储器和、可寻址位、存储器和I/O口的定义口的定义 C51的运算符的运算符 函函 数数 变量使用变量使用 第3章51单片机程序设计51系列单片机支持三种高级语言,即PL/M,C和BASIC。8052单片机内固化有解释BASIC语言,BASIC语言适用于简单编程而对编程效率运行速度
12、要求不高的场合;PL/M是一种结构化的语言,很象PASCAL,PL/M编译器好象汇编器一样产生紧凑的机器代码,可以说是高级汇编语言,但它不支持复杂的算术运算,无丰富库函数支持,学习PL/M无异于学习一种新的语言。C语言是一种通用的程序设计语言,其代码率高,数据类型及运算符丰富,并具有良好的程序结构,适用于各种应用的程序设计,是目前使用较广的单片机编程语言。第3章51单片机程序设计单片机的C语言采用C51编译器(简称C51)。由C51产生的目标代码短、运行速度高、所需存储空间小、符合C语言的ANSI标准,生成的代码遵循Intel目标文件格式,而且可与A51汇编语言或PL/M51语言目标代码混和使
13、用。第3章51单片机程序设计应用C51编程具有以下优点:(1)C51管理内部寄存器和存贮器的分配,编程时,无需考虑不同存储器的寻址和数据类型等细节问题;()程序由若干函数组成,具有良好的模块化结构;()有丰富的子程序库可直接引用,从而大大减少用户编程的工作量。()C语言和汇编语言可以交叉使用.汇编语言程序代码短、运行速度快、但复杂运算编程耗时。如果用汇编语言编写与硬件有关的部分程序,用C语言编写与硬件无关的运算部分程序,充分发挥两种语言的长处,可以提高开发效率。第3章51单片机程序设计10.1 C51程序结构程序结构 同标准C一样,C51的程序由一个个函数组成,这里的函数和其他语言的“子程序”
14、或“过程”具有相同的意义。其中必须有一个主函数main(),程序的执行从main()函数开始,调用其他函数后返回主函数main(),最后在主函数中结束整个程序而不管函数的排列顺序如何。第3章51单片机程序设计C语言程序的组成结构如下所示语言程序的组成结构如下所示: 全局变量说明/*可被各函数引用*/main()/*主函数*/局部变量说明/*只在本函数引用*/执行语句(包括函数调用语句)fun1(形式参数表)/*函数1*/形式参数说明局部变量说明执行语句(包括调用其他函数语句)funn(形式参数表)/*函数n*/形式参数说明局部变量说明执行语句第3章51单片机程序设计C语言的语句规则:1.每个变
15、量必须先说明后引用,变量名英文大小写是有差别的。2.C语言程序一行可以书写多条语句,但每个语句必须以“;”结尾,一个语句也可以多行书写为好。3.C语言的注释用/*/表示。4.“”花括号必须成对,位置随意,可在紧挨函数名后,也可另起一行,多个花括号可以同行书写,也可逐行书写,为层次分明,增加可读性,同一层的“”花括号对齐,采用逐层缩进方式书写。第3章51单片机程序设计10.2 C51的数据类型的数据类型 C51的数据有常量和变量之分。常量在程序运行中其值不变的量,可以为字符,十进制数或十六进制数(用0x表示)。常量分为数值型常量和符号型常量,如果是符号型常量,需用宏定义指令(#define)对其
16、进行定义(相当于汇编的“EQU”伪指令)如:#definePI3.1415那么程序中只要出现PI的地方,编译程序都译为3.1415。变量在程序运行中其值可以改变的量。 一个变量由变量名和变量值构成,变量名即是存贮单元地址的符号表示,而变量的值就是该单元存放的内容。定义一个变量,编译系统就会自动为它安排一个存贮单元,具体的地址值用户不必在意。第3章51单片机程序设计10.2.1 C51变量的数据类型变量的数据类型 无论哪种数据都是存放在存贮单元中的,每一个数据究竟要占用几个单元(即数据的长度)都要提供给编译系统,正如汇编语言中存放数据的单元要用DB或DW伪指令进行定义一样,编译系统以此为根据预留
17、存贮单元,这就是定义数据类型的意义.C51编译器支持数据类型见表10.1。第3章51单片机程序设计表10-1C51的数据类型第3章51单片机程序设计对表10.1作如下说明:1.字符型(char)、整型(int)和长整型(long)均有符号型(signed)和无符号型(unsigned)两种,如果不是必须,尽可能选择unsigned型,这将会使编译器省却符号位的检测,使生成的程序代码比signed类型短得多。2.程序编译时,C51编译器会自动进行类型转换,例如将一个位变量赋值给一个整型变量时,位型值自动转换为整型值;当运算符两边为不同类型的数据时,编译器先将低级的数据类型转换为较高级的数据类型,
18、运算后,运算结果为高级数据类型。3.51单片机内部数据存贮器的可寻址位(20H2FH)定义为bit型,而特殊功能寄存器的可寻址位(即地址为X0H和X8H的SFR的各位)只能定义为sbit类型。第3章51单片机程序设计10.2.2 关于指针型数据关于指针型数据 (1)关于指针型变量在汇编语言程序中,要取存贮单元m的内容可用直接寻址方式,也可用寄存器间接寻址方式,如果用R1寄存器指示m的地址,用R1取m单元的内容。相对应的在C语言中用变量名表示取变量的值(相当于直接寻址),也可用另一个变量(如P)存放m的地址,P就相当于R1寄存器。用*P取得m单元的内容(相当于汇编的间接寻址方式)这里P即为指针型
19、变量。下面表格表示两种语言将m单元的内容送n单元的对照语句。注:注: 上表省略了汇编语言程序中对符号地址上表省略了汇编语言程序中对符号地址n和和m用用EQU伪指令进行具体地伪指令进行具体地址定义的址定义的 语句以及语句以及C语言对变量语言对变量n、m和指针变量和指针变量P进行类型定义的语句,实进行类型定义的语句,实际程序设计中,此步是不可际程序设计中,此步是不可 缺少的。表中缺少的。表中&为取地址运算符,为取地址运算符,*为取内容运为取内容运算符。算符。 表10-2汇编语言和C语言的对照第3章51单片机程序设计(2)指针型数据的类型指针型数据的类型 由于C51是结合51单片机硬件的,51单片机
20、的不同存贮空间,有不同的地址范围,即使对于同一外部数据存贮器,又有用Ri分页寻址(Ri为八位)和用DPTR寻址(DPTR为十六位)两种寻址方式,而指针本身也是一个变量,有它存放的存贮区和数据长度。因此,在指针类型的定义中要说明:被指的变量的数据类型和存贮类型;指针变量本身的数据类型(占几个字节)和存贮类型(即指针本身存放在什么存贮区)。 例如类型定义为data或idata,表示指针指示内部数据存贮器;而pdata表示指针指向外部数据存贮器,用Ri间址。以上均为八位地址;而类型code/xdata表示指针指向外部程序存贮器或外部数据存贮器指针,本身(即被指示地址)应为十六位长度。如果想使指针能适
21、用于指向任何存贮空间,则可以定义指针为通用型,此时指针长度为3字节,第一字节表示存贮器类型编码,第二、三字节分别表示所指地址的高位和低位。第一字节表示的存贮器类型编码见表10-3: 表10-3通用型指针的存贮类型编码 第3章51单片机程序设计10.3 数据的存贮类型和存贮模式数据的存贮类型和存贮模式 10.3.1数据的存贮类型数据的存贮类型 C51是面向8XX51系列单片机及硬件控制系统的开发语言,它定义的任何变量必须以一定的存贮类型的方式定位在8XX51的某一存贮区中,否则便没有意义。因此在定义变量类型时,还必须定义它的存贮类型,C51的变量的存贮类型如表10-4所示:第3章51单片机程序设
22、计表10-4C51的变量的存贮类型 访问内部数据存贮器(idata)比访问外部数据存贮器(xdata)相对要快一些,因此,可将经常使用的变量置于内部数据存贮器中,而将较大及很少使用的数据变量置于外部数据存贮器中。例如定义变量x语句:datacharx。如果用户不对变量的存贮类型定义,则编译器承认默认存贮类型,默认的存贮类型由编译控制命令的存贮的模式部分决定。第3章51单片机程序设计10.3.2 存贮器模式存贮器模式 存贮器模式决定了变量的默认存贮器类型、参数传递区和无明确存贮区类型的说明。C51的存贮器模式有SMALL、LARGE和COMPACT(见表10-5)。 在固定的存贮器地址进行变量参
23、数传递是C51的一个标准特征,在SMALL模式下参数传递是在内部数据存贮区中完成的。LARGE和COMPACT模式允许参数在外部存贮器中传递。C51同时也支持混合模式,例如在LARGE模式下生成的程序可将一些函数分页放入SMALL模式中从而加快执行速度。例如设例如设C语言源程序为语言源程序为PROR.C,若使程序中的变量类型和参数传递区限定,若使程序中的变量类型和参数传递区限定 在在外部数据存贮区外部数据存贮区 ,有两种方法:,有两种方法: 方法方法1:用:用C51对对PROR.C进行编译时,使用命令进行编译时,使用命令C51 PROR.C COMPACT。 方法方法2:在程序的第一句加预处理
24、命令:在程序的第一句加预处理命令 #pragma compact 表10-5存贮器模式 第3章51单片机程序设计10.3.3 变量说明举例变量说明举例 datacharvar;/*字符变量var定位在片内数据存贮区*/charcodeMSG=PARAMETER:;/*字符数组MSG定位在程序存贮区*/unsignedlongxdataarray100;/*无符号长型数组定位在片外RAM区,每元素占4bytes*/floatidatax,y,z;/*实型变量x,y,z,定位在片内用间址访问的内部RAM区*/bitlock;/*位变量Lock定位在片内RAM可位寻址区*/unsignedintpd
25、atasion;/*无符号整型变量sion定位在分页的外部RAM*/unsignedcharxdatavector1044/*无符号字符型三维数组,定位在片外RAM区*/sfrP0=0x80;/*定义P0口,地址为80H*/charbdataflags;/*字符变量flags定位在可位寻址内部RAM区*/sbitflag0=flags0;/*定义flag0为flags.0*/第3章51单片机程序设计如果在变量说明时略去存贮器类型标志符,编译器会自动选择默认的存贮器类型。默认的存贮器类型由控制指令SMALL、COMPACT和LARGE限制。例如如果声明charvar,则默认的存贮器模式为SMAL
26、L,var放在data存贮区;如果使用COMPACT模式,var放入idata存贮区;在使用LARGE模式的情况下,var被放入外部数据存贮区(xdata存贮区)。10.3.4指针变量说明举例longxdata*px;/*指针px指向long型xdata区(每个数据占四个单元,指针自身在默认存贮器(如不指定编译模式在data区),指针长度为2个字节*/charxdata*datapd;/*指针pd指向字符型xdata区,自身在data区,长度2字节*/datacharxdata*pd;/*与上例等效*/dataint*pn;(和int*datapn及intr*pn等效)/*定义一个类型为int
27、型的通用型指针,指针自身在data区长度为3字节*/第3章51单片机程序设计在上例的指针声明中包含如下几个内容:1)指针变量名(如px)前面冠以“*”,表示px为指针型变量,此处*不带取内容之意。2)指针指向的存贮类型,即指向哪个存贮区,它决定了指针本身的长度(见表10.1)。存贮类型声明的位置在数据类型和指针名(如*px)之间,如无次项声明,则此指针型变量为通用型。3)指针指向的存贮区的数据类型,即被指向的存贮区以多少个单元作一个数据单位,当程序通过指针对该区操作时,将按此规定的单元个数的内容作为一个数据操作。4)指针变量自身的存贮类型,即指针处于什么区与自身的长度无关,该声明可位于声明语句
28、的开头,也可在“*”和变量名之间。此项由编译模式放在默认区,如无规定编译模式,通常在data区。第3章51单片机程序设计10.4 C51对对SFR、可寻址位、存储器和、可寻址位、存储器和I/O口的定义口的定义 10.4.1 特殊功能寄存器特殊功能寄存器SFR定义定义 C51提供了一种自主形式的定义方式,使用特定关键字sfr如sfrSCON=0x98;/*串行通信控制寄存器地址98H*/sfrTMOD=0x89;/*定时器模式控制寄存器地址89H*/ sfrACC=0xe0;/*A累加器地址E0H*/ sfrP1=0x90;/*P1端口地址90H*/定义了以后,程序中就可以直接引用寄存器名。C5
29、1也建立了一个头文件reg51.h(增强型为reg52.h),在该文件中对所有的特殊功能寄存器的进行了sfr定义,对特殊功能寄存器的有位名称的可寻址位进行了sbit定义,因此,只要用包含语句#include,就可以直接引用特殊功能寄存器名,或直接引用位名称。要特别注意:在引用时特殊功能寄存器或者位名称必须大写。第3章51单片机程序设计10.4.2 10.4.2 对位变量的定义对位变量的定义 C51对位变量的定义有三种方法:1.将变量用bit类型的定义符定义为bit类型:如bitmn;mn为位变量,其值只能是“0”或“1”,其位地址C51自行安排在可位寻址区的bdata区。2.采用字节寻址变量的
30、位的方法:如bdataintibase;/*ibase定义为整型变量*/sbitmybit=ibase15;/*mybit定义为ibase的D15位*/这里位是运算符“”相当于汇编中的“”,其后的最大取值依赖于该位所在的字节寻址变量的定义类型,如定义为char最大值只能为7。第3章51单片机程序设计3.对特殊功能寄存器的位的定义方法1:使用头文件及sbit定义符;多用于无位名的可寻址位。例如#includesbitP1_1=P11;/*P1-1为P1口的第1位*/sbitac=ACC7;/*ac定义为累加器A的第7位*/方法2:使用头文件reg51.h,再直接用位名称。例如#includeRS
31、1=1;RS0=0;方法3:用字节地址位表示例如sbitOV=0xD02;方法4:用寄存器名.位定义例如sfrPSW=0xd0;/*定义PSW地址为d0H*/sbitCY=PSW7;/*CY为PSW7*/第3章51单片机程序设计10.4.3 C51对存贮器和外接对存贮器和外接I/O口的绝对地址访问口的绝对地址访问 1.对存贮器的绝对地址访问利用绝对地址访问的头文件absacc.h可对不同的存贮区进行访问。该头文件的函数有:CBYTE(访问code区字符型)DBYTE(访问data区字符型)PBYTE(访问pdata或I/O区字符型)XBYTE(访问xdata或I/O区字符型)还有CWORD、D
32、WORD、PWORD和XWORD四个函数,它们的访问区域同上,只是访问的类型为int型。例:#include#definecomXBYTE0x07ff 那么后面程序com变量出现的地方,就是对地址为07ffH的外部RAM或I/O口进行访问。 第3章51单片机程序设计例:XWORD0=0x9988;即将9988H(int类型)送入外部RAM的0号和1号单元。使用中要注意:absacc.h一定要包含进程序,XBYTE必须大写。2.对外部I/O口的访问由于单片机的I/O口和外部RAM统一编址,因此对I/O口地址的访问可用XBYTE(MOVXDPTR)或PBYTE(MOVXRi)进行。例:XBYTE0
33、xEFFF=0x10;将10H输出到地址为EFFFH端口第3章51单片机程序设计10.5 C51的运算符的运算符 1赋值运算符:将“”的右边的值赋值给左边的变量.2.C51的算术运算符:(加或正号);(减或负号);*(乘号);/(除号);%(求余)优先级为:先乘除,后加减,先括号内,再括号外3.C51的关系运算符有六种:(小于);(大于);=(小于等于);=(大于等于);=(相等);!=(不相等)优先级:前四个高,后二个“=”和“!=”级别低。第3章51单片机程序设计4C51的逻辑运算符有三种:&(逻辑与);|(逻辑或);!(逻辑非);逻辑表达式和关系表达式的值相同,以0代表假,以1代表真。以
34、上三种运算的优先级见图10.1。5C51的按位操作的运算符有六种:&(按位与);(按位或);(按位异或);(位取反);(位右移)(注:补零移位)例1.a=0xf0H;表达式a=a值为0FH例2.a=0xea;表达式a2值为A8H,即a值左移两位,移位后空白位补0。6.自增、自减运算符:+i,-i(在使用i之前,先使i值加1,减1)i+,i-(在使用i之后,再使i值加1.,减1)例设i原值为5j=+i则j值为6,i值也为6j=i+则j值为5,i值为6| 非算术运算关系运算&和|= 赋值运算图图10-1 运算符的优先级运算符的优先级 第3章51单片机程序设计7复合赋值运算符:+=;-=;*=;/=
35、;%=;=;&=;=;|=。例:a+=b相当于a=a+b。a=7.相当于a=a7.。8.对指针操作的运算符:&取地址运算*间址运算符例a=&b;取b变量的地址送变量ac=*b;将以b的内容为地址的单元的内容送c这里要注意: “&”与按位与运算符的差别,如果“&”为“与”,&的两边必须为变量或常量;“*”与指针定义时指针前的“*”的差别。如char*pt,这里的“*”只表示pt为指针变量,不代表间址取内容的运算。第3章51单片机程序设计10.6 函函 数数 C语言程序由函数组成,下面介绍函数的要点。10.6.1函数的分类及定义从用户使用角度划分,函数分为库函数和用户自定义函数。库函数是编译系统为
36、用户设计的一系列标准函数(见本书附录二),用户只需调用,而无需自己去编写这些复杂的函数,如前面所用到的头文件reg51.h、absacc.h等,有的头文件中包括一系列函数,要使用其中的函数必须先使用#include包含语句,然后才能调用。用户自定义函数是用户根据任务编写的函数从参数形式上函数分为无参函数和有参函数。有参函数即是在在调用时,调用函数用实际参数代替形式参数,调用完返回结果给调用函数。第3章51单片机程序设计10.6.2 函数的定义函数的定义 函数以“”开始,以“”结束。 无参函数的定义:返回值类型 函数名() 函数体语句 如果函数没有返回值,可以将返回值类型设为void。 有参函数
37、的定义:返回值类型 函数名(形式参数表列)形式参数类型说明 函数体语句return(返回形参名) 也可以这样定义返回值类型 函数名(类型说明 形式参数表列) 函数体语句 return(返回参形名)其中形式参数表列的各项要用“,”隔开,通过return语句将需返回的值返回给调用函数。第3章51单片机程序设计10.6.3 函数的调用函数的调用 函数调用的形式为:函数名(实际参数表列);实参和形参的数目相等类型一致,对于无参函数当然不存在实际参数表列。函数的调用方式有三种:函数调用语句:即把被调函数名作为调用函数的一个语句;如fun1()。被调函数作为表达式的运算对象,如result=2*get(a
38、,b)此时get函数中的a,b应为实参,其以返回值参予式中的运算。被调函数作为另一个数的实际参数如m=max(a,get(a,b);函数get(a,b)作为函数max()的一个实际参数。第3章51单片机程序设计10.6.4对被调函数的说明对被调函数的说明 如果被调函数出现在主调函数之后,在主调函数前应对被调函数作以说明,形式为:返回值类型被调函数名(形参表列);如果被调函数出现在主调函数之前,可以不对被调函数说明。下面以一个简单例子来说明intfun1(a,b)inta,b;intc;c=a+b;return(c);main()intd,0u=3,v=2;d=2*fun(u,v);上例被调函数
39、在主调函数前,不用说明。第3章51单片机程序设计intfun1(a,b);main()intd,u=3,v=2;d=2*fun1(u,v);intfun1(a,b);inta,b;intc;c=a+b;return(c);上例中被调函数在主调函数后,在前面对被调函数进行说明。第3章51单片机程序设计10.7 变量使用变量使用 1.定位变量经常访问的数据对象放入在片内数据RAM中,这可在任一种模式(COMPACT/LARGE)下用输入存贮器类型的方法实现。访问片内RAM要比访问片外RAM快得多。在片内RAM由寄存器组、位数据区、栈和其它由用户用“data”类型定义的变量共享。由于片内RAM容量的
40、限制(128256字节,由使用的处理器决定),必须权衡利弊以解决访问效率和这些对象的数量之间的矛盾。2.只要有可能,使用局部函数变量编译器总是尝试在寄存器里保持局部变量。这样,将索引变量(如FOR和WHILE循环中计数变量)声明为局部变量是最好的,这个优化步骤只为局部变量执行。使用“unsignedchar/int”的对象通常能获得最好的结果。第3章51单片机程序设计3.尽可能使用最小数据类型MCS-51系列单片机是8位机,因此对具有“char”类型的对象的操作比“int”或“long”类型的对象方便得多。建议编程者只要能满足要求,应尽量使用最小数据类型。C51编译器直接支持所有的字节操作,因
41、而如果不是运算符要求,就不作“int”类型的转换,这可用一个乘积运算来说明,两“char”类型对象的乘积与8XX51操作码“MULAB”刚好相符。如果用整型完成同样的运算,则需调用库函数。4.只要有可能,使用“unsigned”数据类型8XX51单片机的CPU不直接支持有符号数的运算。因而C51编译必须产生与之相关的更多的代码以解决这个问题。如果使用无符号类型,产生的代码要少得多。第3章51单片机程序设计二、程序设计二、程序设计阶段阶段1方案制订阶段方案制订阶段l制订技术开发要求l制订实现方案,进行技术准备l评估整个项目开发需要的各方面资源l评估并确定开发周期第3章51单片机程序设计2 程序设
42、计阶段程序设计阶段p程序框架的划分p各个模块功能的细分p系统资源的分配p算法的设计p程序流程图的绘制第3章51单片机程序设计3 代码编写阶段代码编写阶段避免笔误,遵守规范u向前兼容原则u相互兼容原则第3章51单片机程序设计4 程序调试阶段程序调试阶段验证前面的工作,把程序调通(保证程序在各种可能的状态下都能按预期的要求工作)。测试解决BUG第3章51单片机程序设计5 程序维护阶段程序维护阶段程序交付后,根据要求进行升级或BUG消除的阶段养成良好的编程习惯自觉加强版本管理第3章51单片机程序设计三、编程思路三、编程思路1程序基本结构l初始化程序l主程序循环体第3章51单片机程序设计2 模块化程序
43、结构模块化程序结构第3章51单片机程序设计3 模块的事件驱动模块的事件驱动p由于程序是按顺序执行各个模块,而有些模块可能在本次循环中不具备执行的条件。p可用事件驱动的机制,加快主程序的循环速度,提升整个系统的性能p给每个模块设置“使能标志”,通过该标志来触发模块第3章51单片机程序设计4 调度机制调度机制顺序调度机制:缺点某些重要模块无法得到及时响应优先调度机制:可让优先级高的模块获得更多更及时的执行机会,缺点是排在末位的模块可能被阻塞第3章51单片机程序设计5 中断与前后台中断与前后台u轮询调度机制可以应对一般的任务,但遇到紧急事件还是无法保证及时响应,因此引入中断。u把实时性高的时间放在中
44、断中响应,实时性低的任务交给主程序(后台)调度。u极端情况:无中断,自己变现调度程序;中断丰富,全用中断实现。第3章51单片机程序设计四、如何看代码四、如何看代码p善用原理图“顺藤摸瓜”大法:顺着程序的流程一边看一边画原理图,一遍看完后,原理图出来了,程序的大体设计思想和设计结构也就凸现出来了。p建立RAM分配表“按图索骥”大法:将所有的RAM的功能登记下来,当你再看到程序对某个已经登记过的RAM单元操作时,就能猜出大概的功能来。p模块化“庖丁解牛”大法:看一个8K的大程序是很累人的,而看8个1K的小程序则似乎容易些。缝隙在哪里呢?就在“JMP”、“RET”之类指令的后面。第3章51单片机程序设计高明者了解他人的编程思想,中庸者学习他人的编程技巧,蠢笨者为了抄袭盗版,无耻者为了解密篡改。