您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 单片机C51程序设计(补充).
5.3.1KeilC语言1、概述KeilC语言的编译器及编译过程如图5-10所示。单片机C语言程序设计图5-10KeilC语言的编译器及编译过程在KeilC语言的软件包中,包含下列文件:①C51编译器KeilC51编译器是一个基于ANSIC标准的、针对80C51系列MCU的C编译器,生成的可执行代码快速、紧凑,在运行效率和速度上可以和汇编程序得到的代码相媲美。②A51宏汇编器A51宏汇编器是一个8051系列MCU的宏汇编器,支持8051及其派生系列的全部指令集。它把汇编语言汇编成机器代码。本汇编器允许定义程序中的每一个指令,在需要极快的运行速度,很小的代码空间,精确的硬件控制时使用。本汇编器的宏特性让公共代码只需要开发一次,从而节约了开发和维护的时间。A51汇编器将源程序汇编成可重定位的目标代码,并产生一个列表文件。其中可以包含也可不包含字符表及交叉参考信息。③BL51连接/定位器BL51连接/定位器是具有代码分段功能的连接/定位器,利用从库中提取的目标模块和由编译器或汇编器生成的一个或多个目标模块,处理外部和全局数据,并将可重定位的段分配到固定的地址上。所产生的一个绝对地址目标模块或文件包含不可重定位的代码和数据。所有的代码和数据被安置在固定的存储器单元中。此绝对地址目标文件可以用来:。写入EPROM或其它存储器件。。由uVision2调试器使用来模拟和调试。。由仿真器用来测试程序。④LIB51库管理器LIB51库管理器让你建立和维护库文件。库文件是格式化的目标模块(由编译器或汇编器产生)的集合。库文件提供了一个方便的方法来组合和使用大量的连接程序可能用到的目标模块。虽然KeilC51是一个兼容ANSIC的编译器,但为了支持80C51系列MCU还是加入了一些扩展的内容。C51编译器与ANSIC相比,扩展的内容包括:数据类型、存储器类型、存储模式、指针及函数(包括:定义函数的重入性、指定函数的寄存器组、指定函数的存储模式及定义中断服务程序)。2、KeilC对ANSIC的扩展前已述及,本书的读者在前修课程中已经学过了通用的C语言课程,因此在这里将不再叙述有关C语言的一般内容,仅简要地描述KeilC51对ANSIC的扩展。(1)数据类型KeilC51编译器支持的各种规格的数据类型列于表5-1。除了这些数据类型以外,变量可以组合成结构、联合及数组。表5-1KeilC51支持的数据类型数据表5-1所列的数据类型中,bit、sbit、sfr和sfr16等四种类型在ANSIC中没有,是C51编译器中新增的。sbit、sfr和sfr16类型的数据是用于操作80C51的特殊功能寄存器的。例如,下面的表达式:sfrP0=0x80;/*定义80C51P0口的特殊功能寄存器*/声明了一个变量P0,并且把它和位于0x80(80C51的P0口)处的特殊功能寄存器联系在一起。1)bit类型bit数据类型可能在变量声明参数列表和函数返回值中有用。一个bit变量的声明与其它数据类型相似,例如:bitdone_flag=0;/*位变量*/bittestfunc(bitflag1,bitflag2);/*位函数*/所有的bit变量放在80C51内部存储区的位段。因为这个区域只有16字节长,所以在某个范围内最多只能声明128个位变量。bit变量的声明中,应包含存储类型。但是因为bit变量存储在80C51的内部数据区,只能用data和idata存储类型,不能用别的存储类型。bit变量和bit声明有以下限制:一个位不能被声明为一个指针,例如:bit*ptr;/*非法*/不能用一个bit类型的数组,例如:bitware[5]/*非法*/·2)sbit、sfr和sfr16数据类型80C51系列MCU用特殊功能寄存器SFR来控制计时器、计数器、串口、并口和外围设备。它们的可以用位、字节和字访问。与此对应,编译器提供sbit、sfrs和fr16数据类型访问SFR。下面说明这些数据类型。ⅰ.sfr类型sfr和C的其它变量一样声明。例如:sfrP0=0x80;/*P0口,地址为80h*/sfrP1=0x90;/*P1口,地址为90h*/sfrP2=0xA0;/*P2口,地址为0A0h*/sfrP3=0xB0;/*P3口,地址为0B0h*/P0、P1、P2和P3是声明的SFR名。在等号(=)后指定的地址必须是一个常数值不允许用带操作数的表达式。传统的80C51系列支持SFR地址从0x80到0xFF。ⅱ.sfr16类型编译器提供sfr16数据类型,将两个8位的SFR作为一个16位的SFR来访问。访问该16位的SFR只能是低字节跟着高字节,即将低字节的地址用作sfr16声明的地址。例如:sfr16T2=0xCC;/*定时器2,T2L的地址为0CCh,T2H的地址为0CDh*/sfr16RCAP2=0xCA;/*RCAP2L的地址为0CAh,RCAP2H的地址为0CBh*/在这个例子中,T2和RCAP2被声明为16位SFR。sfr16声明和sfr声明遵循相同的原则。任何符号名可用在sfr16的声明中。等号(=)指定的地址,必须是一个常数值。不允许使用带操作数的表达式,而且必须是SFR的低位和高位字节中的低位字节的地址。ⅲ.sbit类型编译器用sbit数据类型来访问可位寻址的SFR中的位。例如:sbitEA=0xAF;(2)存储器类型80C51的存储区域有两个特奌:·程序存储器和数据存储器是截然分开的;·特殊功能寄存器与内部数据存储器是统一编址的。C51编译器支持80C51的这种存储器结构,能够访问80C51的所有存储器空间。针对80C51存储空间的多样性,提出了修饰存储空间的修饰符,用以指明所定义的变量应分配在什么样的存储空间,如表5-2所示。表5-2存储器类型1)、程序存储区程序的代码(CODE)存储区是只读的,不能写入。硬件决定最多可能有64KB的程序存储区。用code标识符来访问片内、片外统一编址的程序存储区,寻址范围为0~65535。在此空间存放程序编码和数据、表格。用间接寻址的方式訪问程序存储区数据,如MOVCA,@A+DPTR或MOVCA,@A+PC。2)、内部数据存储区内部的数据存储区是可读、可写的。80C51系列最多可有256字节的内部数据存储区。内部数据区可以分成三个不同的存储类型data、idata和bdata。data存储类型标识符通常是指低128字节的内部数据区,为片内直接寻址的RAM空间,寻址范围为0~127。在此空向内存取速度最快。idata存储类型标识符是指全部256个字节的内部存储区,为片内间接寻址的RAM空间,寻址范围为0~255。寻址方式为MOV@Ri。由于只能间接寻址,访问速度比直接寻址慢。bdata存储类型标识符是指可位寻址的16字节内部存储区(20H~2FH),位地址范围为0~127。本空间允许按字节和按位寻址。在本区域可以声明可位寻址的数据类型。3)、外部数据存储区外部数据存储区是可读、可写的。可通过一个数据指针加载一个地址来间接访问外部数据区。因此,访问外部数据存储区比访问内部数据存储区来得慢。外部数据存储区最多可有64KB。这些地址不一定都用来作为数据存储区。因为,硬件设计可能把外围设备影射到该存储区。编译器提供两种不同的存储类型,访问外部数据xdata和pdata。xdata存储类型标识符是指外部数据存储区(64KB)内的任何地址,寻址范围为0~65535。寻址方式为MOVX@DPTR。pdata存储类型标识符仅指一页或256字节的外部数据存储区,寻址范围为0~255。寻址方式为MOVX@Ri。在定义变量时,通过指明存储器类型,可以将所定义的变量存储在指定的存储区域中。访问内部数据存储器将比访问外部数据存储器快的多。因此,应该把频繁使用的变量放置在内部数据存储器中,把很少使用的变量放在外部数据存储器中。在变量的声明中,可以包括存储器类型和signed或unsigned属性。如:chardatavar1;charcodetext[]=ENTERPARAMETER;unsignedlongxdataarray[100];floatidatax,y,z;unsignedintpdatadimension;unsignedcharxdatavector[10][4][4];charbdataflags;如果在变量的定义中,没有包括存储器类型,将自动选用默认的存储器类型。(3)存储模式在C51编译器中,可以在命令行用SMALL,COMPACT和LARGE参数定义存储模式。存储模式决定了默认的存储器类型。定义变量时,若指定了存储器类型,将屏蔽掉由存储模式所决定的默认的存储器类型。1)、小(SMALL)模式在这种模式下,所有变量都默认定义在内部数据存储器中。这和用data显式定义变量起到相同的作用。该模式的特点是,变量访问是非常快速的。然而,此时所有的数据对象,包括堆栈都必须放在内部RAM中。堆栈空间面临溢出,因为堆栈占用空间的多少依赖于各个子程序的调用嵌套的深度。在典型应用中,如果,将BL51连接/定位器配置成可覆盖内部数据存储器中的变量时,这种模式将是最好的选择。2)、紧凑(COMPACT)模式在这种模式下,所有变量都默认存放在外部数据存储器的一页中。这和用pdata显式定义变量起到相同的作用。该页地址的高字节往往通过P2口输出。编译器不会设置P2口的输出值,必须在启动代码中设置。此模式最多只能提供256字节的变量。这种限制来自于间接寻址所使用的R0,R1(MOVX@R0/R1)。这种模式不如SMALL模式高效,所以变量的访问不够快。不过它比LARGE模式要快。3)、大(LARGE)模式在大模式下,所有的变量都默认在外部存储器(xdata)中。这和用xdata显式定义变量起到相同的作用。数据指针(DPTR)用来寻址。通过DPTR进行存储器的访问的效率很低。此数据访问类型比SMALL和COMPACT模式需要更多的代码。一般情况下,应该使用小(SMALL)模式,它产生最快,最紧凑,效率最高的代码。在定义变量时,最好要指定存储器类型。只有当应用不可能在SMALL模式下操作时,才需要往上增加你的存储模式。(4)指针C51编译器支持用星号(*)进行指针声明。可以用指针完成在标准C语言中有的所有操作。由于80C51及其派生系列所具有的独特结构,C51编译器支持两种不同类型的指针:通用指针和存储器指针。1)、通用指针通用或未定型的指针的声明和标准C语言中一样。如:char*s;/*stringptr*/int*numptr;/*intptr*/long*state;/*longptr*/通用指针需要三个字节来存储。第一个字节用来表示存储器类型,第二个字节是指针的高字节,第三字节是指针的低字节。通用指针可以用来访问所有类型的变量,而不管变量存储在哪个存储空间中。因而许多库函数都使用通用指针。通过使用通用指针,一个函数可以访问数据,而不用考虑它存储在什么存储器中。通用指针很方便,但是也很慢。在所指向目标的存储空间不明确的情况下,它们用的最多。2)、存储器指针存储器指针或类型确定的指针在定义时要包含一个存储器类型说明,并且总是指向此说明的特定存储器空间。例如:chardata*str;/*指向data区域的字符串*/intxdata*numtab;/*指向xdata区域的int*/longcode*powtab;/*指向code区域的long*/正是由于存储器类型在编译时已经确定,通用指针中用来表示存储器类型的字节就不再需要了。指向idata,data,bdata和pdata的存储器指针使用一个字节来保存;指向code和xdata的存储器指针用两个字节来保存。由此可见,使用存储器指针比通用指针效率要高,速度要快。当然,存储器指针的使用不是很方便。只有在所指向目标的存储空间明确并不会变化的情况下,才用它。(5)函数1)、重入函数函数的嵌套调用是指当一个函数正被调用尚未返回时,又被本函数或其它函数再次调用的情况,只有等到后次调用返回到了本次,本次被暂时搁
本文标题:单片机C51程序设计(补充).
链接地址:https://www.777doc.com/doc-2594078 .html