第3章C51单片机编程语言3.1单片机编程语言概述3.2C51程序设计基础3.3函数、数组、指针的应用3.4C51程序结构3.5C51程序设计3.1单片机编程语言概述51单片机的编程语言可以是汇编语言,也可以是高级语言,如由C语言演变而成的C51语言等。汇编语言产生的目标代码短,占用的存储空间小,执行速度快,能充分发挥单片机的硬件功能。但对于复杂的应用来讲使用汇编语言编程复杂,程序的可读性和可移植性不强。高级语言产生的目标代码长,占用的存储空间大,执行速度慢。但这是相对于汇编语言来讲的,其实C语言在大多数情况下的机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言,编程效率也大大高于汇编语言。如果应用系统的存储空间比较小,且对实时性的要求很高,则应选用汇编语言。如果系统的存储空间比较大,且对实时性的要求不是很高,则应选用C51语言。如果系统中有部分模块对实时性的要求很高,而其它模块对实时性的要求不是很高,则可以将两种语言结合,程序的主体部分使用C51编程,对实时性的要求高的模块用汇编语言编程,然后将汇编语言程序模块嵌入到C51语言程序当中。无论是高级语言还是汇编语言写的源程序都必须转换成目标程序,单片机才能执行。目前很多公司都将编辑器、汇编器、编译器、连接/定位器、符号转换程序做成了软件包,称为集成开发环境,如KeiluVision、MedWin等。3.1单片机编程语言概述使用C语言有以下的优点:•C语言具有结构化和模块化特点,便于阅读和维护。•C语言可移植性好,很多微控制器都支持C编译器。功能化的代码能够很方便的从一个工程移植到另一个工程,从而减少了开发时间。•C语言编写的程序比汇编语言编写的程序更符合人们的思考习惯,开发者可以更专心的考虑算法,而不是考虑一些细节问题。这样可以减少编程出错的机率,从而提高开发效率,减少调试的时间。•C语言和微控制器是相对独立的,开发者不必知道处理器的具体内部结构和处理过程。当基于新型的微控制器开发程序时,可以很快上手,减少学习时间和程序开发时间。3.2C51程序设计基础关键字用途说明_at_地址定位为变量进行存储器绝对空间地址定位alien函数特性声明用以声明与PL/M51兼容的函数bdata存储器类型声明可位寻址的8051内部数据存储器bit位变量声明声明位变量或位类型函数code存储器类型声明8051程序存储器空间compact存储器模式指定使用8051外部分页寻址数据存储空间data存储器类型声明直接寻址的8051内部数据存储器far存储器类型声明8051外部数据存储器idata存储器类型声明间接寻址的8051内部数据存储器interrupt中断函数声明定义中断服务函数3.2.1C51扩展关键字large存储器模式指定使用8051外部数据存储空间pdata存储器类型声明分页寻址的8051外部数据存储器_priority_多任务优先声明规定RTX51或RTX51Tiny的任务优先级reentrant可重入函数声明定义可重入函数sbit位变量声明声明可位寻址的特殊功能位sfr特殊功能寄存器声明声明8位的特殊功能寄存器sfr16特殊功能寄存器声明声明16位的特殊功能寄存器small存储器模式指定使用8051内部数据存储空间_task_任务声明定义实时多任务函数using寄存器组定义定义8051的工作寄存器组xdata存储器类型声明8051外部数据存储器3.2.1C51扩展关键字符号含义&按位与|按位或^按位异或~按位取反。一元运算符左移操作。左边移出的位舍去,右边移入的位补0右移操作。右边移出的位舍去,左边移入的位对无符号数补0;对有符号数补符号位3.2.2C51位运算符例:unsignedcharx=0x55;unsignedchary=0x37;unsignedcharz;z=x&y;则z=0x15z=x|y;则z=0x77z=x^y;则z=0x62z=~x;则z=0xAAz=x2;则z=0x54z=x1;则z=0x2A3.2.2C51位运算符3.2.3C51数据类型数据类型C51专用长度取值范围signedchar单字节-128to+127unsignedchar单字节0to255signedint2字节-32768to+32767unsignedint2字节0to65535signedlong4字节-2147483648to+214746483647unsignedlong4字节0to4294967295float4字节±1.175494E-38to±3.402823E+38*1~3字节对象的地址数据类型C51专用长度取值范围bit专用1位0或1sbit专用1位0或1sfr专用1字节0~255sfr16专用2字节0~655353.2.3C51数据类型3.2.4常量及变量在C51中变量定义的格式如下:•[存储种类]数据类型[存储器类型]变量名表;变量定义中可使用的存储种类(StorageClasses)有四种:•自动(auto)•外部(extern)•静态(static)•寄存器(register)变量定义时,如果省略存储种类选项,则该变量将为自动(auto)变量(默认)。auto类型:•在定义它的函数体内部有效;•进入定义它的函数体时动态分配内存,退出函数体时所占用的内存区域被释放(局部变量);•变量的默认存储种类。register类型:•作用域与寿命和auto型相同;•编译器尽可能将该类变量放在CPU的寄存器中,以提高存储速度。通常选择访问频率较高的变量定义为该类型,以提高效率。3.2.4常量及变量_存储种类extern类型•可以在一个应用的多个程序文件中均有效;•存放在内存的静态存储区。直到该程序结束,分配的内存才被释放(全局变量)。可在函数间传递信息,在函数内被修改时,修改值会传递给其它函数。static类型•局部变量作用域与auto类相同;寿命与extern类相同。数据值在两次调用之间一直保持,占用的内存空间在程序结束才释放。•全局变量仅在定义它的程序文件内有效;寿命与extern类相同。作用范围受限的全局变量,仅在定义它的文件中有效。3.2.4常量及变量_存储种类8051系列微处理器采用了哈佛结构,即程序存储器和数据存储器是分离的。8051系列微处理器提供了三种不同类型的存储区域(memoryareas):•程序存储区(programmemory)•内部数据存储区(internaldatamemory)•外部数据存储区(externaldatamemory)这三种存储区域均从地址0开始编址,通过采用不同的寻址指令来解决地址重叠的问题。3.2.4常量及变量_存储区域3.2.4常量及变量_存储区域存储器类型存储区域大小描述code程序存储区64KB用来说明常量data直接寻址的内部数据存储区128B访问速度快idata间接寻址的内部数据区256B可访问整个内部数据区域bdata位寻址的内部数据存储区16B可使用位寻址或字节寻址来访问这一区域xdata外部数据存储或64KB使用DPTR来访问外部数据存储器pdata分页的外部数据存储区256B利用R0,R1来访问分页的外部数据存储器3.2.4常量及变量_存储区域chardatavar1;charcodetext[]=ENTERPARAMETER:;unsignedlongxdataarray[100];floatidatax,y,z;unsignedintpdatadimension;unsignedcharxdatavector[10][4][4];charbdataflags;说明:声明变量时存储区修饰符和数据类型修饰符的位置可以互换,即chardatax;和datacharx;是完全等效的。不过从兼容性考虑,建议使用前一种格式。3.2.4常量及变量_举例如果在变量声明时未声明变量的存储器类型,则该变量的存储器类型,由程序的存储模式来决定。•小模式(smallmodel):默认data区•紧凑模式(compactmodel):默认pdata区•大模式(largemodel):默认xdata区注意:除非应用在特殊的场合,否则SMALL存储模式可以提供最快和最有效的代码。3.2.4常量及变量_存储模式3.2.5C51中的特殊数据类型C51中有几种ANSIC所没有的特殊数据类型,这些数据类型是和存储区域和存储器类型的概念密切相关的。•位变量•可位寻址的对象•特殊功能寄存器位变量(BitTypes)是指用一个二进制位表示的变量。位数据类型可以用来说明变量,参数表,函数返回值等。位数据变量声明和基本的数据类型声明一样。所有的位变量都存储在内部数据区的位寻址段中。因为该段只有16个字节长,所以在一个作用域内最多只能声明128个位变量。注意:由于位变量只能存储在内部数据存储区的位变量区内,因此只能使用data和idata两种存储器类型修饰符,其它存储器类型是非法的。3.2.5C51中的特殊数据类型——位变量例位变量的使用staticbitdone_flag=0;/*位变量*/bittestfunc(bitflag1,bitflag2)/*位函数返回类型及参数*/{…return(0);/*位类型返回值*/}3.2.5C51中的特殊数据类型——位变量8051系列的微控制器提供了一个独立的内存区,用来存放特殊功能寄存器(specialfunctionregister,SFR)。SFR用来在程序中控制定时器,计数器,串行I/O,端口I/O操作,以及外设的操作。SFR驻留在地址0X80到0XFF空间,可按字节寻址或按字寻址,某些寄存器还可以按位寻址。8051系列微控制器中SFR的个数和类型是变化的。C51没有预先定义SFR的名字,而是提供了许多8051兼容芯片的包含文件,这些文件对芯片的SFR进行了定义。CX51编译器用sfr,sfr16,sbit来进行SFR定义。3.2.5C51中的特殊数据类型——特殊功能寄存器•sfr:定义8位特殊功能寄存器sfr可以用来定义8051单片机的8位特殊功能寄存器。sfr占用一个字节内存单元,取值范围是0~255。SFR的声明和C变量的声明格式是一样的,只不过使用的修饰符不是char或int而是sfr。例如:sfrP0=0x80;/*Port-0,address80h*/sfrP1=0x90;/*Port-1,address90h*/sfrP2=0xA0;/*Port-2,address0A0h*/sfrP3=0xB0;/*Port-3,address0B0h*/P0,P1,P2,P3是sfr声明的特殊功能寄存器的名称。特殊功能寄存器名称是一个合法的C标识符。等号后的地址必须是数值常量,不允许使用带运算符的表达式。3.2.5C51中的特殊数据类型——特殊功能寄存器•sfr16:定义16位特殊功能寄存器8051芯片可以将两个8位SFR作为一个16位寄存器来访问。条件是这两个SFR必须处在相邻地址上,并且是低字节在高字节地址的前面。C51提供了sfr16数据类型来进行16位特殊功能寄存器的声明,声明时低字节地址被用来作为sfr16的地址。例如:sfr16T2=0xCC;/*Timer2:T2L0CCh,T2H0CDh*/sfr16RCAP2=0xCA;/*RCAP2L0CAh,RCAP2H0CBh*/在这个例子中,T2和RCAP2被声明为16位的特殊功能寄存器。sfr16声明和sfr声明的规则相同。3.2.5C51中的特殊数据类型——特殊功能寄存器•sbit:定义特殊功能位sbit用来访问SFR中的可寻址位和其它可位寻址对象的可寻址位。在8051应用中,经常需要对SFR中的可寻址位(特殊功能位)进行独立访问。可以用sbit数据类型来将SFR中的可寻址位声明为特殊功能位。sbitEA=0xAF;上例中将EA定义为地址0XAF,对8051而言这是中断使能寄存器(IE)的中断许可位。3.2.5C51中的特