1、第四章第四章 4-3 C51的头文件与库函数的头文件与库函数4-5 C51的应用技巧的应用技巧随着随着80C5180C51单片机硬件性能的提升,尤其是片内程单片机硬件性能的提升,尤其是片内程序存储器容量的增大和时钟工作频率的提高,已基本序存储器容量的增大和时钟工作频率的提高,已基本克服了高级语言产生代码长、运行速度慢、不适合单克服了高级语言产生代码长、运行速度慢、不适合单片机使用的致命缺点。由此片机使用的致命缺点。由此C51C51已经得到广泛的推广和已经得到广泛的推广和应用。应用。采用采用C51C51程序设计语言,编程者只需了解变量和常程序设计语言,编程者只需了解变量和常量的存储类型与量的存储
2、类型与80C5180C51单片机存储空间的对应关系,而单片机存储空间的对应关系,而不必深入了解单片机的硬件和接口。不必深入了解单片机的硬件和接口。C51C51编译器会自动编译器会自动完成变量的存储单元的分配。完成变量的存储单元的分配。4.1.1 C51语言概述语言概述#include /*文件包含,文件包含,51寄存器说明寄存器说明*/main()/*主函数主函数*/int x,y,z;/*变量定义变量定义*/if(xy)z=x;/*比较大小,求最大值比较大小,求最大值*/else z=y;C51程序示例:程序示例:C语言编程与汇编语言编程相比的优势语言编程与汇编语言编程相比的优势1)与硬件无
3、关性较高,对编程者硬件基础要求较低。可)与硬件无关性较高,对编程者硬件基础要求较低。可移植性好移植性好。2)容易理解和掌握,完全模块化,有各种函数库,大量)容易理解和掌握,完全模块化,有各种函数库,大量库函数可用,编程效率高,代码复用率高。库函数可用,编程效率高,代码复用率高。3)与其它高级语言相比,生成的代码质量高,执行速度)与其它高级语言相比,生成的代码质量高,执行速度较快,对硬件的操控能力强。较快,对硬件的操控能力强。4)有完善的编程和调试工具,灵活方便,便于项目维护)有完善的编程和调试工具,灵活方便,便于项目维护管理管理。缺点:缺点:1)对于代码执行时间不能精确掌控,所以)对于代码执行
4、时间不能精确掌控,所以对于时序有严对于时序有严格要求的情况,最好采用汇编语言格要求的情况,最好采用汇编语言。2)在大量使用)在大量使用data区域的内存变量时,容易产生区域的内存变量时,容易产生堆栈溢堆栈溢出出,从而产生不可预测的错误。,从而产生不可预测的错误。2)与汇编语言编程相比,代码规模和速度还有差距与汇编语言编程相比,代码规模和速度还有差距。4.1.2 C51的标识符、常量和关键字的标识符、常量和关键字标识符标识符用来标识源程序中某个对象的名字,这些对象用来标识源程序中某个对象的名字,这些对象可以是语句、数据类型、函数、变量、数组等。可以是语句、数据类型、函数、变量、数组等。标识符标识
5、符区分大小写区分大小写,第一个字符必须是字母第一个字符必须是字母或下划线。或下划线。C51中有些库函数的标识符是以下划线开头的,所以中有些库函数的标识符是以下划线开头的,所以一般不要以下划线开头命名标识符一般不要以下划线开头命名标识符。常量常量:凡以数字:凡以数字0开头的数字序列,一律作为开头的数字序列,一律作为八进制数八进制数处理;凡处理;凡以以0 x开头开头,后面跟若干数字的,一律作为,后面跟若干数字的,一律作为十六进十六进制数制数处理;其它作为处理;其它作为十进制数十进制数处理。处理。关键字关键字:ANSI C标准关键字和标准关键字和C51编译器的扩展关键编译器的扩展关键字一览表见主教材
6、字一览表见主教材145-147页。页。例如:例如:unsigned char code Flag=0 x0f;就是声明一个无符号的就是声明一个无符号的char型变量型变量Flag,并给他赋初值,并给他赋初值为为0 x0f;并且声明他所在的存储空间在片内统一编址的;并且声明他所在的存储空间在片内统一编址的ROM中。中。声明中,如果没有修饰符,则数据默认的存储空间为声明中,如果没有修饰符,则数据默认的存储空间为data型,也就是在片内型,也就是在片内RAM中。中。C51的数据声明的一般格式如下的数据声明的一般格式如下类型说明符类型说明符修饰符修饰符 标识符标识符=初值初值4.1.3 C514.1.
7、3 C51的数据类型的数据类型C C语言中的基本数据类型语言中的基本数据类型类型类型符号符号关键字关键字数的数的取值取值范围范围所占位数所占位数整型整型字符型字符型实型实型有有无无(signed)int16-3276832767(signed)short16-3276832767(signed)long32-2147483648214748364716unsigned int0655353204294967295unsigned long intunsigned short int16065535有有float323.4e-383.4e38有有double有有char8-128127无无uns
8、igned char80255指针型指针型*1B3B对象的地址对象的地址C C5151的数据类型扩充定义的数据类型扩充定义例:例:sfr P1=0 x90;sfr16 T2=0 xCC;sbit OV=PSW2;sbit P10=0 x900;或或 sbit P10=P10;类型类型关键字关键字所占位数所占位数数的表示范围数的表示范围特殊功能寄存器声明特殊功能寄存器声明sfr1B(16bit)025516位特殊功能寄存器声明位特殊功能寄存器声明sfr162B(32bit)065535位变量数据声明位变量数据声明bit1bit0或或1可寻址位(特殊功能位)声明可寻址位(特殊功能位)声明sbit1
9、bit0或或1 对对C51编译器来说,编译器来说,short和和int是相同类型,是相同类型,double和和float是同一类型;是同一类型;低地址存高字节,高地址存低字节;低地址存高字节,高地址存低字节;有符号数符号位在最低字节的最高位;有符号数符号位在最低字节的最高位;C51编译器能识别的数据类型编译器能识别的数据类型数数 据据 类类 型型长长 度度取值范围取值范围unsigned char1B0255char1B-128+127unsigned int2B065535int2B-32768+32767unsigned long4B04294967295long4B-2147483648
10、+2147483647float4B 1.175494E-38 3.402823E+38*1B3B对象的地址对象的地址bit位位0或或1sfr1B0255sfr162B065535sbit位位0或或1数组类型:数组类型:数组是一组数据,其中的每一个数据元素都属于同一数组是一组数据,其中的每一个数据元素都属于同一类型,类型,各元素可以用数组名和下标来唯一确定各元素可以用数组名和下标来唯一确定。定义格式类。定义格式类似于数据定义:似于数据定义:数据类型数据类型 数组名数组名常量表达式常量表达式多维数组的定义:多维数组的定义:数据类型数据类型 数组名数组名常量表达式常量表达式 常量表达式常量表达式
11、例:例:int xdata xx 15;char code str=“How are you?”;指针类型:指针类型:在在C语言中为了能够实现直接对内存单元进行操作,引语言中为了能够实现直接对内存单元进行操作,引入了指针类型的数据。指针是专门用来确定其它数据类型的入了指针类型的数据。指针是专门用来确定其它数据类型的地址的。因此,地址的。因此,一个变量的地址被称为该变量的指针一个变量的地址被称为该变量的指针。指针。指针变量的定义格式为:变量的定义格式为:数据类型数据类型 存储器类型存储器类型 *标识符标识符例如:例如:“&a”为变量为变量a的地址;的地址;“*p”为指针变量所指向的变量。为指针变
12、量所指向的变量。其中,其中,“标识符标识符”为所定义的指针变量名;为所定义的指针变量名;“数据类数据类型型”说明该指针变量所指向的变量的类型。说明该指针变量所指向的变量的类型。指针变量的引用:指针有关的运算符有两个:地址运指针变量的引用:指针有关的运算符有两个:地址运算符算符“&”和间接访问运算符和间接访问运算符“*”。用用typedeftypedef重新定义数据类型的名称重新定义数据类型的名称在在C语言中为了简化输入,可以根据自己的需语言中为了简化输入,可以根据自己的需要,对前面介绍的数据类型重新定义。格式为:要,对前面介绍的数据类型重新定义。格式为:例如:例如:typedef unsing
13、ed char uchar;即在之后的程序中都可以用即在之后的程序中都可以用uchar 代表代表unsinged char 。typedef unsinged long ulong;即在之后的程序中都可以用即在之后的程序中都可以用ulong 代表代表unsinged longtypedef 已有数据类型已有数据类型 新的数据类型新的数据类型4.1.4 变量的存储种类(属性)变量的存储种类(属性)变量是一种在程序执行过程中,其数值不断变变量是一种在程序执行过程中,其数值不断变化的量。同化的量。同ANSI C一样,一样,C51规定变量必须先定义规定变量必须先定义后使用。后使用。C51对变量的进行定
14、义的格式如下:对变量的进行定义的格式如下:存储种类存储种类 数据类型数据类型 存储器类型存储器类型 变量名表变量名表其中,存储种类(属性)和存储器类型是可选其中,存储种类(属性)和存储器类型是可选项。项。存储种类是指变量在程序执行过程中的作用范存储种类是指变量在程序执行过程中的作用范围。变量的存储种类有四种,分别为:围。变量的存储种类有四种,分别为:u自动(自动(auto)默认值,变量为函数内有效。默认值,变量为函数内有效。u外部(外部(extern)变量对所有函数有效。变量对所有函数有效。u静态(静态(static)u寄存器(寄存器(register)编译系统自动生成。编译系统自动生成。使用
15、外部种类存储符使用外部种类存储符extern定义的变量称为外定义的变量称为外部变量部变量。在一个函数体内,要使用一个已在该函数。在一个函数体内,要使用一个已在该函数体外或别的程序模块文件中定义过的外部变量时,体外或别的程序模块文件中定义过的外部变量时,该变量在本函数体内要用该变量在本函数体内要用extern说明。说明。当片内当片内RAM资源紧张时,不建议将外部变量放资源紧张时,不建议将外部变量放在片内在片内RAM。使用存储种类说明符使用存储种类说明符static定义的变量称为静态定义的变量称为静态变量变量。静态变量分为局部静态变量和全局静态变量。静态变量分为局部静态变量和全局静态变量。局部静态
16、变量是在两次函数调用之间仍能保持局部静态变量是在两次函数调用之间仍能保持其值的局部变量其值的局部变量。有些程序要求在多次调用之间仍。有些程序要求在多次调用之间仍然保持变量的值,使用自动变量无法作用到这一点。然保持变量的值,使用自动变量无法作用到这一点。使用全局变量有时会带来意外的副作用,这时可采使用全局变量有时会带来意外的副作用,这时可采用局部静态变量。用局部静态变量。使用存储种类说明符使用存储种类说明符register定义的变量称为定义的变量称为寄存器变量。寄存器变量。80C51访问寄存器的速度最快,通常访问寄存器的速度最快,通常将使用频率最高的那些变量定义为寄存器变量。将使用频率最高的那些
17、变量定义为寄存器变量。C51编译器能自动识别程序中使用频率最高的变量,编译器能自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,用户无需专门声明。并自动将其作为寄存器变量,用户无需专门声明。4.1.5 C-514.1.5 C-51数据的存储类型数据的存储类型定义变量时,除了说明存储种类外,还允许说定义变量时,除了说明存储种类外,还允许说明变量的存储器类型。明变量的存储器类型。存储类型与数据存放的物理存储类型与数据存放的物理存储区间和寻址方式有关,存储器类型指明该变量存储区间和寻址方式有关,存储器类型指明该变量所处的单片机的内存空间。所处的单片机的内存空间。80C51系列单片机有程序存
18、储器和数据存储器。系列单片机有程序存储器和数据存储器。数据存储器又分片内和片外数据存储器,片内数据数据存储器又分片内和片外数据存储器,片内数据存储器还分直接寻址区和间接寻址区。所以存储器还分直接寻址区和间接寻址区。所以C51的的存储类型分别对应存储类型分别对应code、data、idata、xdata以以及根据及根据80C51系列特点而设定的系列特点而设定的pdata类型。类型。存储器存储器类型类型长度长度数据范数据范围围存储空间位置存储空间位置描述描述data8位位0255 直接寻址片内数据存储器低直接寻址片内数据存储器低128B,访问速度最快,访问速度最快bdata1位位0/1可位寻址的片
19、内数据存储器(地址可位寻址的片内数据存储器(地址20H2FH共共16B)允许位和字节混合访问)允许位和字节混合访问idata8位位0255间接寻址片内数据存储器间接寻址片内数据存储器256B。允许访问片内全。允许访问片内全部地址,速度较快部地址,速度较快pdata8位位0255分页寻址片外数据存储器分页寻址片外数据存储器256B,使用指令,使用指令MOVX Rn访问,需要访问,需要2个指令周期速度较慢个指令周期速度较慢xdata16位位065535寻址片外数据存储器寻址片外数据存储器64KB,使用指令,使用指令MOVX DPTR访问,速度最慢访问,速度最慢code16位位065535寻址程序存
20、储器区寻址程序存储器区64KB,使用指令,使用指令MOVC A+DPTR访问访问对对data区的寻址是最快的,所以应该把使用频区的寻址是最快的,所以应该把使用频率高的变量放在率高的变量放在data区,由于空间有限,必须注意区,由于空间有限,必须注意使用使用data区,区,data区除了包含程序变量外,还包含区除了包含程序变量外,还包含了堆栈和寄存器组了堆栈和寄存器组data区。区。在在SMALL存储模式下,未说明存储器类型时,存储模式下,未说明存储器类型时,变量默认被定位在变量默认被定位在data区区。如果在变量定义时省略了存储器类型标识符,如果在变量定义时省略了存储器类型标识符,C51编译器
21、会选择默认的存储器类型。默认的存储编译器会选择默认的存储器类型。默认的存储器类型由器类型由SMALL、COMPACT和和LARGE存储模式存储模式指令决定。指令决定。1)data区区当在当在DATA区的区的位寻址区定义变量位寻址区定义变量,这个变量,这个变量就可进行位寻址,并且声明位变量。这对状态寄存就可进行位寻址,并且声明位变量。这对状态寄存器来说十分有用,因为它可以单独使用变量的每一器来说十分有用,因为它可以单独使用变量的每一位,而不一定要用位变量名引用位变量。位,而不一定要用位变量名引用位变量。idata区也可以存放使用比较频繁的变量,区也可以存放使用比较频繁的变量,使用使用寄存器作为指
22、针进行寻址寄存器作为指针进行寻址。在寄存器中设置。在寄存器中设置8位地址位地址进行间接寻址,与外部存储器寻址比较,它的指令进行间接寻址,与外部存储器寻址比较,它的指令执行周期和代码长度都比较短。执行周期和代码长度都比较短。2)bdata区区3)idata区区在这两个区声明变量和在其他区的语法是一样在这两个区声明变量和在其他区的语法是一样的,的,pdata区只有区只有256B,而,而xdata区可达区可达65536B code区即区即80C51的程序代码区,所以代码区的的程序代码区,所以代码区的数据是不可改变的,数据是不可改变的,80C51的代码区不可重写。一的代码区不可重写。一般代码区中可存放
23、数据表,跳转向量和状态表般代码区中可存放数据表,跳转向量和状态表 4)pdata和和xdata区区5)code区区一个变量的存储器模式确定了一个变量的存储器模式确定了未声明存储器类未声明存储器类型型的变量在内存中的地址空间。在的变量在内存中的地址空间。在SMALL模式下,模式下,该 变 量 在该 变 量 在 8 0 C 5 1 单 片 机 的 内 部单 片 机 的 内 部 R A M 中;在中;在COMPACT和和LARGE模式下,该变量在模式下,该变量在80C51单片单片机的外部机的外部RAM中。中。建议在编写源程序时,把存储模式设定为建议在编写源程序时,把存储模式设定为SMALL(默认,即
24、对存储模式不作声明),再在程(默认,即对存储模式不作声明),再在程序中把序中把xdata、pdata和和idata等类型变量进行专门声等类型变量进行专门声明。明。C51编译器允许采用三种存储模式:小编译模式编译器允许采用三种存储模式:小编译模式SMALL、紧凑编译模式、紧凑编译模式COMPACT、大编译模式、大编译模式LARGE。4.1.5 C-514.1.5 C-51数据的存储模式数据的存储模式例:例:数据类型数据类型 存储类型存储类型 变量变量char data var1;char data var1;bit data flags;bit data flags;unsigned char
25、xdata vextor10;unsigned char xdata vextor10;运算符就是完成某种特定运算的符号。运算符就是完成某种特定运算的符号。C51的数据运算操作与标准的数据运算操作与标准C语言基本相同,具有十语言基本相同,具有十分丰富的运算符,对数据有很强的表达能力分丰富的运算符,对数据有很强的表达能力:运运算符按其表达式中与运算符的关系(含有运算符算符按其表达式中与运算符的关系(含有运算符的数量)可分为单目运算符、双目运算符和三目的数量)可分为单目运算符、双目运算符和三目运算符。运算符。4.2.1 C-514.2.1 C-51的运算符的运算符一、算术运算符一、算术运算符运算符
26、运算符范例范例说明说明+A+b加或取正值运算符加或取正值运算符-A-b减或取负值运算符减或取负值运算符*A*b乘运算符乘运算符/A/b除运算符除运算符%A%b模(取余)运算符,如模(取余)运算符,如8%5=3+A+等同于等同于A=A+1-A-等同于等同于A=A-1一、赋值运算符一、赋值运算符使用使用“=”的赋值语句格式如下:的赋值语句格式如下:注意注意“=”与与“=”两个运算符和赋值运算符两个运算符和赋值运算符“=”结结合后使用的区别。合后使用的区别。变量变量=表达式表达式;注意注意“=”与与“=”两个运算符和赋值运算符两个运算符和赋值运算符“=”结合后使结合后使用的区别。用的区别。例例1:a
27、=1;b=+a;其运算过程是其运算过程是a加加1变为变为2,然后赋值给,然后赋值给b,即:,即:b=2,a=2。例例2:a=1;b=a+;其运算过程是赋值给其运算过程是赋值给b,然后,然后a加加1变为变为2,即:,即:b=1,a=2。三、关系运算符三、关系运算符C51中有中有6种关系运算符:种关系运算符:大于大于=大于等于大于等于=小于等于小于等于=测试等于测试等于!=测试不等于测试不等于关系表达式的值是真关系表达式的值是真”和和“假假”,用,用“1”和和“0”表示。表示。四、逻辑运算符四、逻辑运算符逻辑与:条件式逻辑与:条件式1&条件式条件式2。逻辑或:条件式逻辑或:条件式1|条件式条件式2
28、。逻辑非:!条件式。逻辑非:!条件式。五、位运算符五、位运算符C51中共有中共有6种位运算符:种位运算符:&按位与按位与|按位或按位或 按位异或按位异或 按位取反按位取反 右移右移六、复合运算符六、复合运算符就是在赋值运算符就是在赋值运算符“=”的前面加上其他运算符。的前面加上其他运算符。运算符运算符范例范例说明说明+=加法赋值加法赋值A+=b等同于等同于A=A+b-=减法赋值减法赋值*=乘法赋值乘法赋值/=除法赋值除法赋值%=取模赋值取模赋值=右移位赋值右移位赋值&=逻辑与赋值逻辑与赋值|=逻辑或赋值逻辑或赋值=逻辑异或赋值逻辑异或赋值=逻辑非赋值逻辑非赋值4.2.2 绝对地址的访问绝对地址
29、的访问*1.使用指针使用指针采用指针的方法,可实现在采用指针的方法,可实现在C51程序中对任意程序中对任意指定的存储器地址进行操作。指定的存储器地址进行操作。uchar idata ivar1;uchar xdata*xdp;/*定义一个指向定义一个指向xdata存储器空间的指针存储器空间的指针*/char data*dp;/*定义一个指向定义一个指向DATA存储器空间的指针存储器空间的指针*/uchar idata*idp;/*定义一个指向定义一个指向idata存储器空间的指针存储器空间的指针*/xdp=0 x1000;/*xdata指针赋值,指向指针赋值,指向xdata存储器地址存储器地址
30、1000H处处*/*xdp=0 x5A;/*将数据将数据5AH送到送到xdata的的1000H单元单元*/dp=0 x61;/*DATA指针赋值,指向指针赋值,指向DATA存储器地址存储器地址61H处处*/*dp=0 x23;/*将数据将数据23H送到送到DATA的的61H单元单元*/idp=&ivar1;/*idp指向指向idata区变量区变量ivar1*/*idp=0 x16;/*等价于等价于ivar1=0 x16*/2.使用使用C51扩展关键字扩展关键字 _at_ 使用使用_at_对指定的存储器空间的绝对地址进行定对指定的存储器空间的绝对地址进行定位,一般格式如下:位,一般格式如下:存储
31、器类型存储器类型 数据类型数据类型 标识符标识符 _at_ 常数常数 uchar xdata xram0 x8000 _at_ 0 x0000;/*在外部在外部RAM空间空间0000H处定义了一个一维数组处定义了一个一维数组*/例如例如 使用使用_at_定义的变量只能为全局变量。定义的变量只能为全局变量。与一般与一般C C语言的结构相同,以语言的结构相同,以main()main()函数为程序人口,函数为程序人口,程序体中包含若干语句还可以包含若干函数。程序体中包含若干语句还可以包含若干函数。C C5151函数的一般格式函数的一般格式 类型类型 函数名(参数表)函数名(参数表)数据说明部分数据说
32、明部分 语句执行部分语句执行部分 4.4.1 C51的程序结构的程序结构C C语言的结构化特征非常明显语言的结构化特征非常明显:C C语言源程序总语言源程序总是由若干个函数组成,以是由若干个函数组成,以main()main()函数为程序入口,函数为程序入口,程序体中包含若干语句还可以包含若干函数调用。程序体中包含若干语句还可以包含若干函数调用。C C语言中的函数很多可以重复利用,形成了函语言中的函数很多可以重复利用,形成了函数库数库,程序员只需按照要求调用,极大地节省了开,程序员只需按照要求调用,极大地节省了开发者的时间和精力,大大降低了出错几率。发者的时间和精力,大大降低了出错几率。4.4.
33、1 C51的程序结构的程序结构从程序控制语句以及函数的使用上来讲,从程序控制语句以及函数的使用上来讲,C51与标准与标准C几乎没有什么明显的区别几乎没有什么明显的区别。只是在函数的。只是在函数的使用上,由于单片机系统的资源有限,它的编译系使用上,由于单片机系统的资源有限,它的编译系统统不允许太多的程序嵌套不允许太多的程序嵌套。在前面已多次使用过以在前面已多次使用过以“#”号开头的预处理命令。如号开头的预处理命令。如包含命令包含命令#include,宏定义命令,宏定义命令#define等。等。凡是以凡是以“#”开头的开头的均为预处理命令均为预处理命令。在源程序中这些命令都放在函数之外,而且。在源
34、程序中这些命令都放在函数之外,而且一般都放在源文件的前面,它们称为一般都放在源文件的前面,它们称为预处理部分预处理部分。所谓预处理是指在进行编译的第一遍扫描所谓预处理是指在进行编译的第一遍扫描(词法扫描和词法扫描和语法分析语法分析)之前所作的工作之前所作的工作。预处理是语言的一个重要功能,。预处理是语言的一个重要功能,它由预处理程序负责完成。当对一个源文件进行编译时,系统它由预处理程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分作处理,处理将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的编译。完毕自动进入对源程序的编译。语言提供
35、了多种预处理功能,如宏定义、文件包含、语言提供了多种预处理功能,如宏定义、文件包含、条件编译等。合理地使用预处理功能编写的程序便于阅读、修条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。本章介绍常用的改、移植和调试,也有利于模块化程序设计。本章介绍常用的几种预处理功能。几种预处理功能。4.4.2 4.4.2 文件预处理与头文件文件预处理与头文件一、宏定义一、宏定义 在语言源程序中允许在语言源程序中允许用一个标识符来表示一个字符串,用一个标识符来表示一个字符串,称为称为“宏宏”。被定义为。被定义为“宏宏”的标识符称为的标识符称为“宏名宏名”。在编。在
36、编译预处理时,译预处理时,对程序中所有出现的对程序中所有出现的“宏名宏名”,都用宏定义中,都用宏定义中的字符串去代换的字符串去代换,这称为,这称为“宏代换宏代换”或或“宏展开宏展开”。宏定义是由源程序中的宏定义是由源程序中的宏定义命令宏定义命令完成的。宏代换是完成的。宏代换是由预处理程序自动完成的。由预处理程序自动完成的。宏定义的一般形式为:宏定义的一般形式为:#define 标识符标识符 字符串字符串“define”为宏定义命令。为宏定义命令。“标识符标识符”为所定义的宏名。为所定义的宏名。“字符串字符串”可以是常数、表达式、或含有参数的表达式、可以是常数、表达式、或含有参数的表达式、格式串
37、等。格式串等。在程序中多次使用宏,可以简化源程序的输入。与使在程序中多次使用宏,可以简化源程序的输入。与使用函数相比,会占用较多内存,但执行速度快用函数相比,会占用较多内存,但执行速度快。例如:例如:#define M (y*y+3*y)二、文件包含命令二、文件包含命令 文件包含是文件包含是C预处理程序的另一个重要功能。预处理程序的另一个重要功能。文件包含文件包含是用指定文件的全部内容替换该预处理命令行是用指定文件的全部内容替换该预处理命令行。即一个程序。即一个程序文件将另一个指定文件的内容完全包含进来。文件将另一个指定文件的内容完全包含进来。在程序设计中,文件包含是很有用的。一个大的程序可在
38、程序设计中,文件包含是很有用的。一个大的程序可以分为多个模块,由多个程序员分别编程。有些公用的符号以分为多个模块,由多个程序员分别编程。有些公用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使用。这样,可避免在每个文件开包含命令包含该文件即可使用。这样,可避免在每个文件开头都去书写那些公用量,从而节省时间,并减少出错。头都去书写那些公用量,从而节省时间,并减少出错。#include 文件名文件名 或:或:#include 。文件包含的对象最为常见的是头文件(扩展名文件包含的对象最为常见的是头文件(扩展名.h)
39、。在)。在前面我们已多次用此命令包含过库函数的头文件。文件包含前面我们已多次用此命令包含过库函数的头文件。文件包含命令行的一般形式为:命令行的一般形式为:系统提供了丰富的系统文件,称为库文件系统提供了丰富的系统文件,称为库文件。C51的强的强大功能及其高效率的重要体现之一在于,其提供了丰富的可大功能及其高效率的重要体现之一在于,其提供了丰富的可直接调用的库函数。使用库函数使程序代码简单、结构清晰、直接调用的库函数。使用库函数使程序代码简单、结构清晰、易于调试和维护,易于调试和维护,C的库文件分为两类,一类是扩展名为的库文件分为两类,一类是扩展名为“.h”的文件,的文件,称为称为头文件头文件,在
40、前面的包含命令中我们已多次使用过。在,在前面的包含命令中我们已多次使用过。在“.h”文件中包含了常量定义、文件中包含了常量定义、类型定义、宏定义、函数原类型定义、宏定义、函数原型以及各种编译选择设置等信息。另一类是函数库,包括了型以及各种编译选择设置等信息。另一类是函数库,包括了各种函数的目标代码,供用户在程序中调用。各种函数的目标代码,供用户在程序中调用。为了使用为了使用51单片机的内部资源,如定时器、中断、单片机的内部资源,如定时器、中断、I/O等,等,需要将说明相应的功能寄存器的头文件加载在程序中需要将说明相应的功能寄存器的头文件加载在程序中。如前面所使用的如前面所使用的reg51.h等
41、。因此,等。因此,C51系列头文件集中体系列头文件集中体现了各系列芯片的不同功能现了各系列芯片的不同功能。通常在程序中调用一个库函数时,要在调用之前包含通常在程序中调用一个库函数时,要在调用之前包含该函数原型所在的该函数原型所在的.h 文件。文件。部分库函数不适合单片机处理系统部分库函数不适合单片机处理系统,因此被排除在外,因此被排除在外,如字符屏幕和图形函数。如字符屏幕和图形函数。部分库函数的定义与标准部分库函数的定义与标准C有很大不同有很大不同,如,如printf和和scanf函数,在函数,在C51中用于串口数据的发送和接收。中用于串口数据的发送和接收。C51与标准与标准ANSI C库函数
42、的不同库函数的不同:一、本征库函数和非本征库函数一、本征库函数和非本征库函数C51提供的提供的本征函数在编译时直接将固定的代码插入本征函数在编译时直接将固定的代码插入当前行当前行,而不是用,而不是用ACALL和和LCALL语句实现的,这样就大语句实现的,这样就大大提高了函数访问的效率,程序执行更快。而大提高了函数访问的效率,程序执行更快。而非本征函数则非本征函数则必须由必须由ACALL及及LCALL调用调用。reg51.h,reg52.hreg51.h,reg52.h定义特殊功能寄存器和位寄存器;定义特殊功能寄存器和位寄存器;math.hmath.h数学函数。本分类给出了各种数学计算函数数学函
43、数。本分类给出了各种数学计算函数stdio.hstdio.h输入输出函数。该分类用于处理包括文件、控输入输出函数。该分类用于处理包括文件、控制台等各种输入输出设备,各种函数以制台等各种输入输出设备,各种函数以“流流”的方式实现的方式实现 intrins.h intrins.h 内部函数内部函数ctype.hctype.h字符处理函数。本类别函数用于对单个字符进字符处理函数。本类别函数用于对单个字符进行处理,包括字符的类别测试和字符的大小写转换行处理,包括字符的类别测试和字符的大小写转换stdlib.hstdlib.h实用工具函数。实用工具函数。string.hstring.h字符串处理。本分类
44、的函数用于对字符串进行字符串处理。本分类的函数用于对字符串进行合并、比较等操作;合并、比较等操作;absacc.habsacc.h绝对地址访问函数。绝对地址访问函数。三、三、C51常用库函数:常用库函数:4.4.2 C-514.4.2 C-51的基本语句的基本语句与标准与标准C C语言基本相同:语言基本相同:if if 选择语言选择语言 switch/caseswitch/case 多分支选择语言多分支选择语言whilewhile 循环语言循环语言 do-whiledo-while 循环语言循环语言forfor 循环语言循环语言1.第一种形式为基本形式:第一种形式为基本形式:if if(表达式
45、表达式)语句语句其语义是:如果表达式的值为真,则执行其语义是:如果表达式的值为真,则执行其后的语句,其后的语句,否则不执行该语句。其过否则不执行该语句。其过程可表示为下图。程可表示为下图。一、一、if语句的三种形式语句的三种形式2.第二种形式为第二种形式为:if-elseif(表达式表达式)语句语句1;else 语句语句2;其语义是:如果表达式的值为真其语义是:如果表达式的值为真,则执行语句,则执行语句1,否则执行语句,否则执行语句2。3.当有多个分支选择时,可采用当有多个分支选择时,可采用if-else-if语句,其一般形式语句,其一般形式为:为:if(表达式表达式1)语句语句1;else
46、if(表达式表达式2)语句语句2;else if(表达式表达式3)语句语句3;else if(表达式表达式m)语句语句m;else 语句语句n;其语义是:依次判断表达式的值,当出现某个值为真时其语义是:依次判断表达式的值,当出现某个值为真时,则执行其对应的语句。然后跳到整个,则执行其对应的语句。然后跳到整个if语句之外继续执行语句之外继续执行程序。程序。如果所有的表达式均为假,则执行语句如果所有的表达式均为假,则执行语句n。然后继续。然后继续执行后续程序。执行后续程序。二、二、switch语句语句语言还提供了另一种用于多分支选择的语言还提供了另一种用于多分支选择的switch语句,语句,其其一
47、般形式为:一般形式为:switch(表达式表达式)case常量表达式常量表达式1:语句语句1;case常量表达式常量表达式2:语句语句2;case常量表达式常量表达式n:语句语句n;default :语句语句n+1;其语义是:计算表达式的值。并逐个与其后的常量表达式其语义是:计算表达式的值。并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,即执值相比较,当表达式的值与某个常量表达式的值相等时,即执行其后的语句,然后不再进行判断,继续执行后面所有行其后的语句,然后不再进行判断,继续执行后面所有case后后的语句。如表达式的值与所有的语句。如表达式的值与所有case后的常量
48、表达式均不相同时,后的常量表达式均不相同时,则执行则执行default后的语句。后的语句。while语句的一般形式为:语句的一般形式为:while(表达式表达式)语句语句其中表达式是循环条件,其中表达式是循环条件,语句为循环体。语句为循环体。while语句的语义是:计语句的语义是:计算表达式的值,当值为真算表达式的值,当值为真(非非0)时,时,执行循环体语句。其执行循环体语句。其执行过程可用下图表示。执行过程可用下图表示。三、while语句do-while语句的一般形式为语句的一般形式为:do 语句语句 while(表达式表达式);这个循环与这个循环与while循环的不同在循环的不同在于于:它
49、先执行循环中的语句它先执行循环中的语句,然后然后再判断表达式是否为真再判断表达式是否为真,如果为如果为真则继续循环;如果为假真则继续循环;如果为假,则终则终止循环。因此止循环。因此,do-while循环至循环至少要执行一次循环语句。其执少要执行一次循环语句。其执行过程可用下图表示。行过程可用下图表示。四、四、do-while语句语句在在C语言中,语言中,for语句使用最为灵活,它完全可以取代语句使用最为灵活,它完全可以取代 while 语句。它的一般形式为语句。它的一般形式为:for(表达式表达式1;表达式;表达式2;表达式;表达式3)语句语句它的执行过程如下:它的执行过程如下:1)先求解表达
50、式先求解表达式1。2)求解表达式求解表达式2,若其值为真(非,若其值为真(非0),则执行),则执行for语句中指语句中指定的内嵌语句,然后执行下面第定的内嵌语句,然后执行下面第3)步;若其值为假()步;若其值为假(0),则结束循环,转到第,则结束循环,转到第5)步。)步。3)求解表达式求解表达式3。4)转回上面第转回上面第2)步继续执行。)步继续执行。5)循环结束,执行循环结束,执行for语句下面的一个语句。语句下面的一个语句。其执行过程可用下图表示。其执行过程可用下图表示。五、五、for语句语句for语句最简单的应用形式也是最容语句最简单的应用形式也是最容易理解的形式如下:易理解的形式如下: