《单片机的C语言编程.ppt》由会员分享,可在线阅读,更多相关《单片机的C语言编程.ppt(119页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第4 4章章 单片机的单片机的C C语言编程语言编程 单片机应用系统是由硬件和软件组成的,这是与一般的数字逻单片机应用系统是由硬件和软件组成的,这是与一般的数字逻辑电路系统的不同之处。辑电路系统的不同之处。汇编语言汇编语言是能够利用单片机所有特性直接控制硬件的唯一语言,是能够利用单片机所有特性直接控制硬件的唯一语言,对于一些需要直接控制硬件的场合,汇编语言是必不可少的。对于一些需要直接控制硬件的场合,汇编语言是必不可少的。但汇编语言不是一种结构化的程序设计语言,对于较复杂的单但汇编语言不是一种结构化的程序设计语言,对于较复杂的单片机应用系统,它的编写效率很低。片机应用系统,它的编写效率很低。
2、为了提高软件的开发效率,许多软件公司致力于单片机为了提高软件的开发效率,许多软件公司致力于单片机高级语高级语言言的开发研究,许多型号的单片机内部的开发研究,许多型号的单片机内部ROMROM已经达到已经达到64KB64KB甚至更大,甚至更大,且具备在且具备在系统编程系统编程(ISP,In System ProgrammableISP,In System Programmable)功能,进一)功能,进一步推动了步推动了高级语言高级语言在单片机应用系统开发中的应用。在单片机应用系统开发中的应用。51 51系列单片机支持三种高级语言系列单片机支持三种高级语言:PL/MPL/M、C C、BASICBAS
3、IC BASIC BASIC语言适用于简单编程而对编程效率、运行速度要求不高语言适用于简单编程而对编程效率、运行速度要求不高的场合,的场合,80528052单片机内固化有单片机内固化有BASICBASIC语言解释器。语言解释器。PL/MPL/M是一种结构化的语言,很象是一种结构化的语言,很象PASCALPASCAL,PL/MPL/M编译器好象汇编编译器好象汇编器一样产生紧凑的机器代码,可以说是高级汇编语言,但它不支持器一样产生紧凑的机器代码,可以说是高级汇编语言,但它不支持复杂的算术运算,无丰富库函数支持,学习复杂的算术运算,无丰富库函数支持,学习PL/MPL/M无异于学习一种新无异于学习一种
4、新的语言。的语言。C C语言是一种通用的程序设计语言,其语言是一种通用的程序设计语言,其代码率高代码率高,数据类型及,数据类型及运算符丰富,并具有良好的运算符丰富,并具有良好的程序结构程序结构,适用于各种应用的程序设计,适用于各种应用的程序设计,是目前使用最广的单片机编程语言。是目前使用最广的单片机编程语言。C C语言作为一种非常方便的语言而得到广泛的支持,很多硬件语言作为一种非常方便的语言而得到广泛的支持,很多硬件开发都用开发都用C C语言编程,如:各种单片机、语言编程,如:各种单片机、DSPDSP、ARMARM等。等。C C语言程序本身不依赖于机器硬件系统语言程序本身不依赖于机器硬件系统,
5、基本上不作修改或仅,基本上不作修改或仅做简单修改就可将程序从不同的单片机中做简单修改就可将程序从不同的单片机中移植移植过来直接使用。过来直接使用。C C语言提供了很多数学函数并支持浮点运算,开发效率高,故语言提供了很多数学函数并支持浮点运算,开发效率高,故可缩短开发时间,增加程序可缩短开发时间,增加程序可读性可读性和和可维护性可维护性。单片机的单片机的C C语言编程称为语言编程称为C51C51编程编程,应用,应用C51C51编程具有以下优点:编程具有以下优点:(1 1)C51C51编译器编译器管理内部寄存器和存贮器的分配,编程时,无需管理内部寄存器和存贮器的分配,编程时,无需考虑不同存储器的寻
6、址和数据类型等细节问题考虑不同存储器的寻址和数据类型等细节问题;(2 2)程序有规范的结构,可分成不同的函数,这种方式具有良)程序有规范的结构,可分成不同的函数,这种方式具有良好的好的模块化结构,使已编好程序容易移植模块化结构,使已编好程序容易移植;(3 3)有丰富的)有丰富的子程序库子程序库可直接引用,可直接引用,具有较强的数据处理能力具有较强的数据处理能力,从而大大减少用户编程的工作量;从而大大减少用户编程的工作量;(4 4)C C语言和汇编语言可以交叉使用语言和汇编语言可以交叉使用。汇编语言程序代码短、运行速度快、但复杂运算编程耗汇编语言程序代码短、运行速度快、但复杂运算编程耗 时。时。
7、用汇编语言编写与硬件有关的部分程序用汇编语言编写与硬件有关的部分程序,用用C C语言编写与硬件无关语言编写与硬件无关的运算部分程序的运算部分程序,充分发挥两种语言的长处,提高开发效率。,充分发挥两种语言的长处,提高开发效率。C51C51编译器(编译器(Keil CKeil C)与标准)与标准ANSI CANSI C编译器的主要区别编译器的主要区别 单片机单片机C C编译器之所以与编译器之所以与ANSI CANSI C有所不同,主要是由于它们所有所不同,主要是由于它们所针对的针对的硬件系统硬件系统有其各自不同的特点。有其各自不同的特点。C51C51的特点和功能主要是的特点和功能主要是80C518
8、0C51单片机自身特点引起的。单片机自身特点引起的。(1 1)头文件头文件:5151单片机有不同的厂家和系列,不同单片机的主单片机有不同的厂家和系列,不同单片机的主要区别在于内部资源,为了实现内部资源功能,只需将相应的功能要区别在于内部资源,为了实现内部资源功能,只需将相应的功能寄存器的头文件加载在程序中,就可实现指定的功能。寄存器的头文件加载在程序中,就可实现指定的功能。因此,因此,C51C51系列头文件集中体现了各系列芯片的不同功能。系列头文件集中体现了各系列芯片的不同功能。(2 2)数据类型数据类型:由于由于5151系列器件包含了位操作空间和丰富的位系列器件包含了位操作空间和丰富的位操作
9、指令,因此操作指令,因此 C51C51比比ANSI CANSI C多一种多一种位类型位类型。(3 3)数据存储类型数据存储类型:5151系列单片机有程序存储器和数据存储器。系列单片机有程序存储器和数据存储器。数据存储器又分片内和片外数据存储器。片内数据存储器还分直接数据存储器又分片内和片外数据存储器。片内数据存储器还分直接寻址区和间接寻址区,分别对应寻址区和间接寻址区,分别对应codecode、datadata、idataidata、xdataxdata以及根以及根据据80C5180C51系列特点而设定的系列特点而设定的pdatapdata类型。类型。(4 4)数据运算操作和程序控制数据运算操
10、作和程序控制:从数据运算操作和程序控制语从数据运算操作和程序控制语句以及函数的使用上来讲,它们几乎没有什么明显的区别。只是在句以及函数的使用上来讲,它们几乎没有什么明显的区别。只是在函数的使用上,函数的使用上,由于单片机系统的资源有限,它的编译系统不允许由于单片机系统的资源有限,它的编译系统不允许太多的程序嵌套太多的程序嵌套。由于由于5151系列单片机是系列单片机是8 8位机,所以位机,所以扩展扩展1616位字符位字符UnicodeUnicode不被不被C51C51支持。支持。ANSI C ANSI C所具备的所具备的递归特性不被递归特性不被C51C51支持支持,所以在,所以在C51C51中如
11、果要使中如果要使用递归特性,必须用用递归特性,必须用REETRANTREETRANT关键字声明。关键字声明。(5 5)C51C51与标准与标准ANSI CANSI C库函数库函数:部分库函数不适合单片机处理部分库函数不适合单片机处理系统,因此被排除在外,如字符屏幕和图形函数。系统,因此被排除在外,如字符屏幕和图形函数。也有一些库函数继续使用,但这些库函数是厂家针对硬件特点也有一些库函数继续使用,但这些库函数是厂家针对硬件特点相应开发的,与相应开发的,与ANSI CANSI C的构成和用法有很大的区别,如的构成和用法有很大的区别,如printfprintf和和scanfscanf。在。在ANSI
12、 CANSI C中,这两个函数通常用作中,这两个函数通常用作屏幕打印屏幕打印和和接收字符接收字符,而在而在C51C51中,主要用于中,主要用于串口数据的发送和接收串口数据的发送和接收。4.1 C514.1 C51程序结构特点程序结构特点同标准同标准C C一样,一样,C51C51的程序是由函数组成。的程序是由函数组成。C C语言的函数以语言的函数以“”“”开始,以开始,以“”“”结束。结束。其中必须有一个其中必须有一个主函数主函数mainmain()(),程序的执行从主函数,程序的执行从主函数main()main()开始,调用其开始,调用其他函数后返回主函数他函数后返回主函数main()main
13、(),最后,最后在主函数中结束整个程序在主函数中结束整个程序,而不管函数的排列而不管函数的排列顺序如何。顺序如何。C C语言的语句规则:语言的语句规则:1.1.每个变量必须先说明后引用。每个变量必须先说明后引用。2.C 2.C语言程序一行可以书写多条语句,但每个语句必须以语言程序一行可以书写多条语句,但每个语句必须以“;”结尾,一个语句也可以多行书写。结尾,一个语句也可以多行书写。3.C 3.C语言的注释用语言的注释用/*/*/表示。表示。4.“”4.“”花括号必须成对花括号必须成对,位置随意,多个花括号可同行书写,位置随意,多个花括号可同行书写,也可逐行书写也可逐行书写。为层次分明,增加可读
14、性,同一层的为层次分明,增加可读性,同一层的“”花括对齐,采用花括对齐,采用逐层缩进逐层缩进方式书写。方式书写。C C语言程序的组成结构:语言程序的组成结构:全局变量全局变量说明说明 /*/*可被各函数引用可被各函数引用*/mainmain()/*()/*主函数主函数*/局部变量局部变量说明说明 /*/*只在本函数引用只在本函数引用*/执行语句执行语句(包括函数调用语句包括函数调用语句););fun1fun1(形式参数表形式参数表)/*)/*函数函数1*/1*/形式参数说明形式参数说明 局部变量说明局部变量说明 执行语句执行语句(包括调用其他函数语句包括调用其他函数语句)funnfunn(形式
15、参数表形式参数表)/*)/*函数函数n*/n*/形式参数说明形式参数说明 局部变量说明局部变量说明 执行语句执行语句 标识符标识符用来标识源程序中某个对象的名字,这些对象可以是语用来标识源程序中某个对象的名字,这些对象可以是语句、数据类型、函数、变量、数组等。句、数据类型、函数、变量、数组等。标识符区分大小写,第一个标识符区分大小写,第一个字符必须是字母或下划线。字符必须是字母或下划线。C51C51中有些库函数的标识符是以下划线开头的,所以中有些库函数的标识符是以下划线开头的,所以一般不要以一般不要以下划线开头命名标识符下划线开头命名标识符。C51C51编译器规定标识符最长可达编译器规定标识符
16、最长可达255255个字符,但只有前面个字符,但只有前面3232个字个字符在编译时有效符在编译时有效,因此在编写源程序时标识符的长度不要超过,因此在编写源程序时标识符的长度不要超过3232个个字符,这对于一般应用程序来说已经足够了字符,这对于一般应用程序来说已经足够了。关键字关键字是编程语言保留的特殊标识符,有时又称为是编程语言保留的特殊标识符,有时又称为保留字保留字,它,它们具有固定名称和含义,们具有固定名称和含义,在在C C语言的程序编写中不允许标识符与关语言的程序编写中不允许标识符与关键字相同键字相同。与其他计算机语言相比,与其他计算机语言相比,C C语言的关键字较少,语言的关键字较少,
17、ANSI CANSI C标准一共标准一共规定了规定了3232个关键字。个关键字。Keil C51 Keil C51编译器的关键字除了有编译器的关键字除了有ANSI CANSI C标准的标准的3232个关键字外还个关键字外还根据根据5151单片机的特点单片机的特点扩展了相关的关键字扩展了相关的关键字。在。在Keil C51Keil C51开发环境的开发环境的文本编辑器中编写文本编辑器中编写C C程序,系统可以把保留字以不同颜色显示,程序,系统可以把保留字以不同颜色显示,缺缺省颜色为蓝色省颜色为蓝色。4.2 4.2 C51C51的标识符和关键字的标识符和关键字关键字用途说明auto存储种类说明用以
18、说明局部变量,缺省值为此break程序语句退出最内层循环体case程序语句switch语句中的选择项char数据类型说明单字节整型数或字符型数据const存储类型说明在程序执行过程中不可更改的常量值continue程序语句转向下一次循环default程序语句switch语句中的失败选择项do程序语句构成dowhile循环结构double数据类型说明双精度浮点数else程序语句构成ifelse选择结构enum数据类型说明枚举extern存储种类说明在其他程序模块中说明了的全局变量float数据类型说明单精度浮点数for程序语句构成for循环结构goto程序语句构成goto转移结构if程序语句构成
19、ifelse选择结构ANSI CANSI C标准关键字(标准关键字(1 1)ANSI CANSI C标准关键字(标准关键字(2 2)关键字用途说明int数据类型说明基本整型数long数据类型说明长整型数register存储种类说明使用CPU内部寄存的变量return程序语句函数返回short数据类型说明短整型数signed数据类型说明有符号数,二进制数据的最高位为符号位sizeof运算符计算表达式或数据类型的字节数static存储种类说明静态变量struct数据类型说明结构类型数据switch程序语句构成switch选择结构typedef数据类型说明重新进行数据类型定义union数据类型说明联
20、合类型数据unsigned数据类型说明无符号数据void数据类型说明无类型数据volatile数据类型说明该变量在程序执行中可被隐含地改变while程序语句构成while和dowhile循环结构Keil C51Keil C51编译器扩展的关键字编译器扩展的关键字(1 1)关键字用途说明_at_地址定位为变量定义存储空间绝对地址alien函数特性说明声明与PL/M51兼容的函数bdata存储器类型说明可位寻址的内部RAMbit位标量声明声明一个位标量或位类型的函数code存储器类型说明程序存储器空间compact存储器模式使用外部分页RAM的存储模式data存储器类型说明直接寻址的8051内部数
21、据存储器idata存储器类型说明间接寻址的8051内部数据存储器interrupt中断函数声明定义一个中断函数large存储器模式使用外部RAM的存储模式pdata存储器类型说明“分页”寻址的8051外部数据存储器_priority_多任务优先声明RTX51的任务优先级reentrant再入函数声明定义一个再入函数sbit位变量声明声明一个可位寻址变量sfr特殊功能寄存器声明声明一个特殊功能寄存器(8位)Keil C51Keil C51编译器扩展的关键字编译器扩展的关键字(2 2)关键字用途说明sfr16特殊功能寄存器声明声明一个16位的特殊功能寄存器small存储器模式内部RAM的存储模式_
22、task_任务声明定义实时多任务函数using寄存器组定义定义8051的工作寄存器组xdata存储器类型说明8051外部数据存储器4.3 C514.3 C51的数据类型的数据类型C51C51的数据有常量和变量之分。的数据有常量和变量之分。常量常量 在程序运行中在程序运行中其值不变其值不变的量。的量。数值型常量数值型常量:可以为十进制数、:可以为十进制数、十六进制数十六进制数(用用0 x0 x表示表示)和字和字符(符(括号括起)。括号括起)。符号型常量符号型常量:用符号表示常量,此符号需用宏定义指令:用符号表示常量,此符号需用宏定义指令(#define)(#define)对其进行对其进行 定义定
23、义(相当于汇编的相当于汇编的“EQU”EQU”伪指令伪指令)。变量变量 在程序运行中其值可以改变的量。在程序运行中其值可以改变的量。定义一个变量,编译系统就会自动为它安排一个存贮区,具体定义一个变量,编译系统就会自动为它安排一个存贮区,具体的地址值的地址值 ,用户不必在意。,用户不必在意。一个变量由一个变量由变量名变量名和和变量值变量值构成构成.变量名:存贮单元地址的符号表示。变量名:存贮单元地址的符号表示。变量的值:变量所在地址单元存放的内容。变量的值:变量所在地址单元存放的内容。数据类型:数据的长度。数据类型:数据的长度。C51C51编译器支持数据类型编译器支持数据类型数数 据据 类类 型
24、型长长 度度值值 域域位位型型bit1Bit0或或1字字符符型型signedchar1Byte-128+127unsignedchar1Byte0255整整形形signedint2Byte-32768+32767unsignedint2Byte065535signedlong4Byte-2147483648+2147483647unsignedlong4Byte04294967295实型实型Float4Byte1.176E-383.40E+38指针型指针型data/idata/pdata1Byte1字节地址字节地址code/xdata2Byte2字节地址字节地址通用指针通用指针3Byte其中其
25、中1字节为储存器类型编码,字节为储存器类型编码,2,3字节为地字节为地址偏移量址偏移量访问访问SFR的数据类的数据类型型sbit1Bit0或或1sfr1Byte0255sfr162Byte065535 1 1、在、在C51C51语语言程序中,有可能会出言程序中,有可能会出现现在运算中数据在运算中数据类类型不一致型不一致的情况。的情况。C51C51允允许许任何任何标标准数据准数据类类型的型的隐隐式式转换转换,隐隐式式转换转换的的优优先先级顺级顺序如下:序如下:bitbitcharcharintintlonglongfloatfloatsignedsignedunsignedunsigned 2
26、2、也就是、也就是说说,当,当charchar型与型与intint型型进进行运算行运算时时,先自,先自动对动对charchar型型扩扩展展为为intint型,然后与型,然后与intint型型进进行运算,运算行运算,运算结结果果为为intint型。型。C51C51除了除了支持支持隐隐式式类类型型转换转换外,外,还还可以通可以通过过强强制制类类型型转换转换符符“()()”对对数据数据类类型型进进行人行人为为的的强强制制转换转换。3 3、字符型、字符型(char)(char)、整型、整型(int)(int)和长整型和长整型(long)(long)均有符号型均有符号型(signed)(signed)和
27、无符号型和无符号型(unsigned)(unsigned)两种,如果不是必须,两种,如果不是必须,尽可能选择尽可能选择unsignedunsigned型型,这将会使编译器省却符号位的检测,使生成的程序代,这将会使编译器省却符号位的检测,使生成的程序代码比码比signedsigned类型短得多。类型短得多。C5l C5l编译器除了能支持以上这些基本数据类型之外,还能支持一编译器除了能支持以上这些基本数据类型之外,还能支持一些复杂的组合型数据类型,如数组类型、指针类型、结构类型、联些复杂的组合型数据类型,如数组类型、指针类型、结构类型、联合类型等这些复杂的数据类型。合类型等这些复杂的数据类型。4.
28、4 4.4 数据的存储类型和存储模式数据的存储类型和存储模式 同同ANSI CANSI C一样,一样,C51C51规定变量必须先定义后使用。规定变量必须先定义后使用。C51C51对变量对变量的进行定义的格式如下:的进行定义的格式如下:存储种类存储种类 数据类型数据类型 存储器类型存储器类型 变量名表变量名表 其中,存储种类和存储类型是可选项。其中,存储种类和存储类型是可选项。一、变量的存储种类一、变量的存储种类 按变量的有效作用范围可以将其划分为局部变量和全局变量;按变量的有效作用范围可以将其划分为局部变量和全局变量;还可以按变量的的存储方式为其划分存储种类。还可以按变量的的存储方式为其划分存
29、储种类。在在C C语言中变量有四种存储种类,即自动语言中变量有四种存储种类,即自动(auto)(auto)、外部、外部(extern)(extern)、静态、静态(static)(static)和寄存器和寄存器(register)(register)。这四种存储种类与全局变量和局部变量之间的关系如图所示这四种存储种类与全局变量和局部变量之间的关系如图所示 1 1、自动变量(、自动变量(autoauto)定义一个变量时,在变量名前面加上存储种类说明符定义一个变量时,在变量名前面加上存储种类说明符“auto”auto”,即将该变量定义为自动变量。自动变量是,即将该变量定义为自动变量。自动变量是C
30、C语言中使用最为广泛语言中使用最为广泛的一类变量。的一类变量。自动变量的作用范围在定义它的函数体或复合语句内部,只有自动变量的作用范围在定义它的函数体或复合语句内部,只有在定义它的函数内被调用,或是定义它的复合语句被执行时,编译在定义它的函数内被调用,或是定义它的复合语句被执行时,编译器才为其分配内存空间,开始其生存期。当函数调用结束返回,或器才为其分配内存空间,开始其生存期。当函数调用结束返回,或复合语句执行结束时,自动变量所占用的内存空间就被释放,变量复合语句执行结束时,自动变量所占用的内存空间就被释放,变量的值当然也就不复存在,其生存期结束。的值当然也就不复存在,其生存期结束。自动变量始
31、终是相对于函自动变量始终是相对于函数或复合语句的局部变量。数或复合语句的局部变量。一、变量的存储种类一、变量的存储种类 2 2、外部变量、外部变量(extern)(extern)使用存储种类说明符使用存储种类说明符“extern”extern”定义的变量称为外部变量。定义的变量称为外部变量。按照缺省规则,凡是在所有函数之前,在函数外部定义的变量按照缺省规则,凡是在所有函数之前,在函数外部定义的变量都是外部变量,定义时可以不写都是外部变量,定义时可以不写externextern说明符。但是,在一个函数说明符。但是,在一个函数体内说明一个已在该函数体外或别的程序模块文件中定义过的外部体内说明一个已
32、在该函数体外或别的程序模块文件中定义过的外部变量时,则必须要使用变量时,则必须要使用externextern说明符。说明符。一个外部变量被定义之后,它就被分配了固定的内存空间。一个外部变量被定义之后,它就被分配了固定的内存空间。外部变量的生存期为程序的整个执行时间,即在程序的执行期外部变量的生存期为程序的整个执行时间,即在程序的执行期间外部变量可被随意使用,当一条复合语句执行完毕或是从某一个间外部变量可被随意使用,当一条复合语句执行完毕或是从某一个函数返回时,外部变量的存储空间并不被释放,其值也仍然保留。函数返回时,外部变量的存储空间并不被释放,其值也仍然保留。因此,因此,外部变量属于全局变量
33、外部变量属于全局变量。C C语言允许将大型程序分解为若干个独立的程序模块文件,各语言允许将大型程序分解为若干个独立的程序模块文件,各个模块可分别进行编译,然后再将它们连接在一起。个模块可分别进行编译,然后再将它们连接在一起。2 2、外部变量、外部变量(extern)(extern)在这种情况下,如果某个变量需要在所有程序模块文件中在这种情况下,如果某个变量需要在所有程序模块文件中使用,只要在一个程序模块文件中将该变量定义成全局变量,而在使用,只要在一个程序模块文件中将该变量定义成全局变量,而在其它程序模块文件中用其它程序模块文件中用externextern说明该变量是已被定义过的外部变量说明该
34、变量是已被定义过的外部变量就可以了。就可以了。函数是可以相互调用的,因此函数都具有外部存储种类的函数是可以相互调用的,因此函数都具有外部存储种类的属性。属性。定义函数时如果冠以关键字定义函数时如果冠以关键字externextern即将其明确定义为一个外部即将其明确定义为一个外部函数。例如函数。例如extern int func2(char aextern int func2(char a,b)b)。如果在定义函数时省。如果在定义函数时省略关键字略关键字externextern,则隐含为外部函数。如果要调用一个在本程序模,则隐含为外部函数。如果要调用一个在本程序模块文件以外的其它模块文件所定义的
35、函数,则必须要用关键字块文件以外的其它模块文件所定义的函数,则必须要用关键字externextern说明被调用函数是一个外部函数。对于具有外部函数相互调说明被调用函数是一个外部函数。对于具有外部函数相互调用的多模块程序,可用用的多模块程序,可用C51C51编译器分别对各个模块文件进行编译,编译器分别对各个模块文件进行编译,最后最后L51L51连接定位器将它们连接成为一个完整的程序。连接定位器将它们连接成为一个完整的程序。一、变量的存储种类一、变量的存储种类 3 3、静态变量(、静态变量(staticstatic)使用存储种类说明符使用存储种类说明符“static”static”定义的变量称为静
36、态变量。静定义的变量称为静态变量。静态变量分为局部静态变量和全局静态变量。态变量分为局部静态变量和全局静态变量。局部静态变量不象自动变量那样只有当函数调用它时才存在,局部静态变局部静态变量不象自动变量那样只有当函数调用它时才存在,局部静态变量始终都是存在的,但只能在定义它的函数内部进行访问,退出函数之后,变量始终都是存在的,但只能在定义它的函数内部进行访问,退出函数之后,变量的值仍然保持,但不能进行问。量的值仍然保持,但不能进行问。全局静态变量,它是在函数外部被定义的,作用范围从它的定全局静态变量,它是在函数外部被定义的,作用范围从它的定义点开始,一直到程序结束。义点开始,一直到程序结束。当一
37、个当一个C C语言程序由若干个模块文件所组成时,全局静态变量始终存在,语言程序由若干个模块文件所组成时,全局静态变量始终存在,但它只能在被定义的模块文件中访问,其数据值可为该文件内的所有函数共享,但它只能在被定义的模块文件中访问,其数据值可为该文件内的所有函数共享,退出该文件后,虽然变量的值仍然保持着,但不能被其它模块文件访问。局部退出该文件后,虽然变量的值仍然保持着,但不能被其它模块文件访问。局部静态变量是一种在两次函数调用之间仍能保持其值的局部变量。有些程序需要静态变量是一种在两次函数调用之间仍能保持其值的局部变量。有些程序需要在多次调用之间仍然保持变量的值,使用自动变量无法实现这一点,使
38、用在多次调用之间仍然保持变量的值,使用自动变量无法实现这一点,使用全局变量有时又会带来意外的副作用,这时就可采用局部静态变量。全局变量有时又会带来意外的副作用,这时就可采用局部静态变量。一、变量的存储种类一、变量的存储种类 4 4、寄存器变量、寄存器变量(register)(register)为了提高程序的执行效率,为了提高程序的执行效率,C C语言允许将一些使用频率最高的语言允许将一些使用频率最高的那些变量,定义为能够直接使用硬件寄存器的所谓寄存器变量。那些变量,定义为能够直接使用硬件寄存器的所谓寄存器变量。定义一个变量时在变量名前而冠以存储种类符号定义一个变量时在变量名前而冠以存储种类符号
39、“register”register”即将即将该变量定义成为了寄存器变量。该变量定义成为了寄存器变量。寄存器变量可以被认为是自动变量的一种,它的有效作用范围寄存器变量可以被认为是自动变量的一种,它的有效作用范围也与自动变量相同。也与自动变量相同。C51C51编译器能够识别程序中使用频率最高的变量,在可能的情编译器能够识别程序中使用频率最高的变量,在可能的情况下,即使程序中并未将该变量定义为寄存器变量,编译器也会自况下,即使程序中并未将该变量定义为寄存器变量,编译器也会自动将其作为寄存器变量处理。动将其作为寄存器变量处理。因此,用户无须专门声明寄存器变量。因此,用户无须专门声明寄存器变量。4.4
40、 4.4 数据的存储类型和存储模式数据的存储类型和存储模式二、数据的存储类型二、数据的存储类型 C51C51是面向是面向8XX518XX51系列单片机及硬件控制系统的开发语言,它定系列单片机及硬件控制系统的开发语言,它定义的任何变量必须以一定的存储类型的方式定位在义的任何变量必须以一定的存储类型的方式定位在8XX518XX51的某一存的某一存储区中,否则便没有意义。因此在定义变量类型时,还必须定义它储区中,否则便没有意义。因此在定义变量类型时,还必须定义它的存储类型,的存储类型,C51C51的变量有如下几种存储类型:的变量有如下几种存储类型:存储器类型存储器类型描描述述data直接寻址内部数据
41、存储区直接寻址内部数据存储区,访问变量速度最快访问变量速度最快(128Byte)bdata可为寻址内部数据存储区可为寻址内部数据存储区,允许位与字节混合访问允许位与字节混合访问(16Byte)idata间接寻址内部数据存储区间接寻址内部数据存储区,可访问全部内部地址空间可访问全部内部地址空间(256Byte)pdata分页分页(256Byte)外部数据存储区外部数据存储区,由操作码由操作码MOVXRi访问访问xdata外部数据存储区外部数据存储区(64KB),由操作码由操作码MOVXDPTR访问访问code程序存储区程序存储区(64KB),由操作码由操作码MOVCA+DPTR访问访问 如果在变
42、量定义时省略了存储器类型标识符,如果在变量定义时省略了存储器类型标识符,C51C51编译器会选编译器会选择默认的存储器类型。默认的存储器类型由择默认的存储器类型。默认的存储器类型由SMALLSMALL、COMPACTCOMPACT和和LARGELARGE存储模式指令决定。存储模式指令决定。1 1)datadata区区 对对datadata区的寻址是最快的,所以应该把使用频率高的变量放在区的寻址是最快的,所以应该把使用频率高的变量放在datadata区,由于空间有限,必须注意使用区,由于空间有限,必须注意使用datadata区,区,datadata区除了包含程区除了包含程序变量外,还包含了堆栈和
43、寄存器组序变量外,还包含了堆栈和寄存器组datadata区。区。在在SMALLSMALL存储模式下,未说明存储器类型时,变量默认被定位存储模式下,未说明存储器类型时,变量默认被定位在在datadata区。区。2 2)bdatabdata区区 当在当在DATADATA区的位寻址区定义变量,这个变量就可进行位寻址,区的位寻址区定义变量,这个变量就可进行位寻址,并且声明位变量。这对状态寄存器来说十分有用,因为它可以单独并且声明位变量。这对状态寄存器来说十分有用,因为它可以单独使用变量的每一位,而不一定要用位变量名引用位变量。使用变量的每一位,而不一定要用位变量名引用位变量。3 3)idataidat
44、a区区 idata idata区也可以存放使用比较频繁的变量,使用寄存器作为指区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。在寄存器中设置针进行寻址。在寄存器中设置8 8位地址进行间接寻址,与外部存储位地址进行间接寻址,与外部存储器寻址比较,它的指令执行周期和代码长度都比较短。器寻址比较,它的指令执行周期和代码长度都比较短。4 4)pdatapdata和和xdataxdata区区 在这两个区声明变量和在其他区的语法是一样的,在这两个区声明变量和在其他区的语法是一样的,pdatapdata区只区只有有256B256B,而,而xdataxdata区可达区可达65536B 65536B
45、 5 5)codecode区区 code code区即区即80C5180C51的程序代码区,所以代码区的数据是不可改变的程序代码区,所以代码区的数据是不可改变的,的,80C5180C51的代码区不可重写。一般代码区中可存放数据表,跳转的代码区不可重写。一般代码区中可存放数据表,跳转向量和状态表。向量和状态表。如果用户不对变量的存贮如果用户不对变量的存贮 类型定义,则编译器承认默认存贮类型定义,则编译器承认默认存贮类型,默认的存贮类型由编译控制命令的存贮的模式部分类型,默认的存贮类型由编译控制命令的存贮的模式部分 决定。决定。三、数据的存储模式三、数据的存储模式 在固定的存贮器地址进行变量参数传
46、递是在固定的存贮器地址进行变量参数传递是C51C51的一个标准特征,的一个标准特征,定义了变量、参数传递区的存贮器模式,也就是默认了变量和参数定义了变量、参数传递区的存贮器模式,也就是默认了变量和参数传递区存贮器类型、无需再对变量和参数传递区的存贮器类型进行传递区存贮器类型、无需再对变量和参数传递区的存贮器类型进行说明。说明。存贮器模式决定了变量的默认存贮器类型、参数传递区和无明存贮器模式决定了变量的默认存贮器类型、参数传递区和无明确存贮区类型的说明。确存贮区类型的说明。有三种存贮器模式:有三种存贮器模式:SMALLSMALL、LARGELARGE和和COMPACTCOMPACT存储器模式存储
47、器模式描描述述SMALL参数及局部变量放入可直接寻址的内部数据存储参数及局部变量放入可直接寻址的内部数据存储区(区(128Byte,默认存储器类型是默认存储器类型是DATA)COMPACT参数及局部变量放入分页外部数据存储区(最大参数及局部变量放入分页外部数据存储区(最大256Byte,默认存储类型是默认存储类型是PDATA)LARGE参数及局部变量直接放入外部数据存储器(最大参数及局部变量直接放入外部数据存储器(最大64KB,默认存储器类型为,默认存储器类型为XDATA)1 1小小(SMALL)(SMALL)模式模式 所有变量都默认在所有变量都默认在80518051的内部数据存储器中。这和用
48、的内部数据存储器中。这和用datadata显式显式定义变量起到相同的作用。定义变量起到相同的作用。2 2紧凑紧凑(COMPACT)(COMPACT)模式模式 此模式中,所有变量都默认在此模式中,所有变量都默认在80518051的外部数据存储器的一页中。的外部数据存储器的一页中。3 3大大(LARGE)(LARGE)模式模式 在大模式下,所有的变量都默认在外部存储器中在大模式下,所有的变量都默认在外部存储器中(xdata)(xdata)。为了能够直接访问这些特殊功能寄存器为了能够直接访问这些特殊功能寄存器 ,C51C51编译器扩充了关编译器扩充了关键字键字sfrsfr和和sfrl6sfrl6,利
49、用这种扩充关键字可以在,利用这种扩充关键字可以在C C语言源程序中直语言源程序中直接对接对805l805l单片机的特殊功能寄存器进行定义。定义方法如下:单片机的特殊功能寄存器进行定义。定义方法如下:sfr特殊功能寄存器名地址常数特殊功能寄存器名地址常数;例如:sfr P00 x80;*定义IO口P0,其地址为80H *例如:例如:设设C语言源程序为语言源程序为PROR.C,若使程序中的变量类型和参数,若使程序中的变量类型和参数传递区限定在外部数据存贮区传递区限定在外部数据存贮区,有两种方法:,有两种方法:方法方法1:在程序的第一句加预处理命令:在程序的第一句加预处理命令#pragmacompa
50、ct。方法方法2:用:用C51对对PROR.C进行编译时,使用编译控制命令进行编译时,使用编译控制命令:C51PROR.CCOMPACT。四、变量说明举例四、变量说明举例datacharvar;/*字符变量字符变量var定位在片内定位在片内RAM区区charcodeMSG=ENTERPARAMETER:/*字符数组定位在程序存贮区字符数组定位在程序存贮区*/unsignedlongxdataarray100;/*无符号长无符号长型数组定位在片外型数组定位在片外RAM区,每区,每元素占元素占4bytes*/floatidatax,y,z;/*实型变量实型变量x,y,z,定位在片内用,定位在片内用