您好,欢迎访问三七文档
C-51程序设计11FranklinC-511.1FranklinC-51数据类型FranklinC-51编译器支持下列数据类型:数据类型长度值域bit1字节0或1signedchar1字节-128~+127unsignedchar1字节0~255signedint2字节-32768~+32867unsignedint2字节0~65535signedlong4字节-2147483648~+2147483647unsignedlong4字节0~4294967295float4字节±1.176E-38~±3.40E+38指针1~3字节对象地址sbit1位0或1sfr1字节0~255sfr162字节0~65535编译的数据类型(如结构)包含上表所列的数据类型。由于8051系列是8位机,因而不存在字节校准问题。这意味着数据结构成员是顺序放置的。数据类型的转换:当计算结果隐含着另外一种数据类型时,数据类型可以自动进行转换,例如,将一个位变量赋给一个整型变量时,位型值自动转换为整型值,有符号变量的符号也能自动进行处理。这些转换也可以用C语言的标准指令进行人工转换。1.2数据类型的物理结构1.2.1bit“bit”类型只有1位,不允许有位指针和位数组。位对象始终位于8051CPU的可寻址RAM空间。如果程序控制流允许,L51将位对象交迭。1.2.2signed/unsignedchar;data/idata/pdata指针“char”类型标量和基于存贮器的“data/idata/pdata”指针具有1个字节长度(8bits)。1.2.3signed/unsignedint/short;xdata/code指针“int”和“short”类型标量及指向xdata/code区域的指针具有2字节长度(16bits)。整型值(或偏移)0x1234以下面方式保存在内存中:地址:+0+1内容:0x120x342C-51程序设计1.2.4signed/unsignedlong“long”类型标量长为4个字节(32bits),值0x12345678以下面方式放置:地址:+0+1+2+3内容:0x120x340x560x781.2.5“一般”指针“一般”指针包括3个字节:2字节偏移和1字节存贮器类型:地址:+0+1+2内容:存贮器类型偏移高位偏移低位第一个字节代表了指针的存贮器类型,存贮器类型编码如下:存贮器类型IDATAXDATAPDATADATACODE值12345使用其它类型值可能导致不可预测的程序动作。XDATA类型的0x1234地址作为指针表示如下:地址:+0+1+2内容:0x020x120x34当用常数作指针时,必须注意正确定义存贮器类型和偏移。下例将值0x41写入绝对地址为0x8000的外部数据存贮器:#defineXBYTE((char*)0x20000L)XBYTE[0x8000]=0x41;上例中用其它常数索引或索引变量也起作用。这样,各种存贮器类型的绝对地址可以一种非常有效的方式访问。但有一个例外,即SFR。注意:绝对地址定义为“long”型常量,低16位包含偏移,高8位表明了xdata类型。为了表示这种指针,必须用长整数来定义存贮器类型。C51编译器不检查指针常数,用户必须选择有实际意义的值。1.2.6float“float”类型为4个字节(32位),使用的格式与IEEE-754标准(32位)具有24位精度,尾数的高位始终为“1”,因而不保存,位的分布如下:1位符号8位指数位23位尾数符号位是最高位,尾数为最低的位,内存中按字节存贮如下:地址:+0+1+2+3内容:MMMMMMMMMMMMMMMMEMMMMMMMSEEEEEEE其中:S:符号位,1=负,0=正C-51程序设计3E:指数(在两个字节中),偏移为127M:23位尾数,最高位“1”浮点值——12.5的十六进制为0xC1480000,它按下面方式存贮:地址:+0+1+2+3内容:0x000x000x480xc18051不包括捕获浮点错误(例外)的中断向量。用户软件因此必须对错误条件作出适当反应。下面推荐一种方法(也可以用其它可靠办法):“union”用来保存浮点值,这个“union”必须包括一个“float”和一个“unsignedlong”,以根据IEEE对错误作出响应。除了通常浮点值外,IEEE标准可能出错的条件以下面二进制值表示,为检查可能出现的计算错误,可在计算后进行检查。因为当执行一个运算时考虑了每个运算符的错误状态并且该状态被送到结果中。NaN0xFFFFFFF不是一个数+INF0x7F80000正无穷(正溢出)-INF0XFF80000负无穷(负溢出)1.3C-51的扩充定义1.3.1特殊功能寄存器的声明MSC-51系列包括多种寄存器,其中一些具有特殊功能,如定时器,端口的控制寄存器等,为了能够直接访问这些寄存器,C51编译器提供了一种定义的自主形式,这是必要的,因为这些定义与标准C语言是不兼容的。为了支持这些特殊功能寄存器(SFR)的声明,引入了关键词“sfr”,语法如下:sfr-dcl:sfrsfr_name=int_constant例:sfrp0=0x80;sfrp1=0x90;必须注意的是“sfr”后不是一个地址而是一个名字。因此上例中名字P0和P1(port0和port1)定义为特殊功能寄存器并被赋予相应的绝对地址,名字可按意愿自由选取,源文件中不应有先定义的sfr名字。“=”号后的地址必须是常数,不允许带有运算符的表达式,这个常数表达式必须在特殊功能寄存器的地址范围内,位于0X80到0XFF之间。8051系列寄存器数量和类型是极其不同的,因此建议将所有特别的“sfr”声明放入一个头文件,头文件包括8051一些系列成员中的SFR定义。进一步的定义可由用户用一文件编辑器产生。1.3.2对SFR的16位数据访问在新的8051系列产品中,SFR在功能上经常组合为16位的,为了有效的访问这类SFR,使用定义“sfr16”,当“SFR”的高端直接位于低端后时,对SFR16位的访问是可能的。例如8052的定时器2就是这种情况,16位声明的语法与“sfr”相同,SFR低地址部分必须作4C-51程序设计为sfr16的地址:例:sfr16T2=0xCC/*Timer2:T2L=0CCH,T2H=0CDH*/sfr16RCAP2=0xCA/*RCAP2L=0CAH,PCAP2H=0CBH*/本例中,T2(由T2L和T2H组成)和RCAP2(由RCAP2L和RCAP2H组成)被定义为16位SFR,即使在这种情况下,声明中的名字后仍不是赋值语句,而是一个SFR地址,高字节必须直接位于低字节之后,这种声明适用于所有新的SFR,但不能用于Timer0和Timer1。1.3.3SBIT:特殊功能位声明在典型的8051应用问题中,经常需要单独访问SFR中的位,C51扩充功能使之成为可能,特殊位,象SFR一样,不与标准C语言兼容,使用保留字“sbit”可访问位寻址对象。与SFR声明一样,用保留字“sbit”声明某些特殊位接受符号名,“=”后语句将绝对值地址赋给变量名,这种地址分配有三种方法:方法1:sfr_name^int_constant当字节是特殊功能寄存器的地址可用这个方法。sfr_name必须是已定义的SFR的名字,“^”后的语句定义了基地址上的特殊位的位置,该位置必须是一个0~7的数。例:sfrPSW=0xD0;sfrLE=0xA8;sbitOV=PSW^2;sbitCY=PSW^7;方法2:int_constant^int_constant这种方法以一整常数作基地址,该值必须在0x80~0xFF之间,并能被8整除,确定位的位置方法同上。例:sbitOV=0xD0^2;sbitCV=0xD0^7;sbitEA=0xA8^7;方法3:int_constant这种方法是将位的绝对地址赋给变量,地址必须位于0x80~0xFF之间。例:sbitOV=0xD2;sbitCY=0xD7;sbitEA=0xAF;特殊功能位代表了一个独立的声明类,它不能与其它声明和位域互换。1.3.4BIT:位标量声明除了通常的C数据类型外,C51编译器支持“bit”数据类型,对此有下列扩充与限制:(1)函数可包含类型为“bit”的参数,也可将其作为返回值。bitbfunc(bitb0,bitb1){/*……*/return(b1);C-51程序设计5}注:使用禁止中断(#pragmadisable)或包含明确的寄存器组切换(usingn)的函数不能返回位值,在这种情况下,编译器会识别出来并产生一个错误信息。(2)位标量声明的语法及C声明的语义staticbitdirction_bit;externbitlock_printer_port;bitdisplay_invers;(3)对于位声明的限制位不能声明为一个指针(bit*bit_poiter)不存在位数组(bitb_array[5])位声明中允许定义存贮器类型,位都被放入一个位段,它总是在8051内部RAM中,因此存贮器类型限制为DATA或IDATA,声明为其它存贮器类型都将导致编译出错。1.3.5可位寻址对象可位寻址对象指可以字节或位寻址的对象,当对象位于MSC-51可寻址RAM中时会有这种情况,C51允许带“bdata”类型的对象放入可位寻址存贮器中。bdataintibase;/*位寻址指针int*/bdatacharbary[4];/*位寻址数组arrray*/使用“sbit”声明可独立访问可位寻址对象的位:sbitmybit0=ibase^0;sbitmybit15=ibase^15;sbitary07=bary[0]^7;sbitary37=bary[3]^7;对象“ibase”和“bary”也可位寻址:ary37=0;/*寻址“bary[3]”中的位7*/ibase=-1;/*寻址字节地址*/mybit15=0;/*寻址“ibase”的位15*/sbit声明要求基址对象的存贮器类型为“bdata”,否则只有绝对的位声明方法是合法的。位位置(‘^’操作符号后)的最大值依赖于指定的基类型,这个值于char/uchar而言是0~7,对于int/uint/short/ushort而言是0~15,对于long/ulong而言是0~31。在编译器内存贮器类型bdata与data一样操作,并且只作与可再定位的sbit的运算。注:可位寻址的的段长最大不能超过16字节,可再定位的sbit声明自动转为公共的(PBULIC)以使它们能被其它C模块使用。模块1:sbitary37=bary[3]^7;模块2:externbitary37;sbit声明也可为结构和函数所用:unionlft{floatmf;longml;};bdatastructbad{charml;unionlftu;}tcp;6C-51程序设计sbittcpf31=tcp.u.ml^31;/*浮点限制*/sbittcpml0=tcp.ml^0;sbittcmpl7=tcp.ml.^7;注:位位置的指定不能直接被float类型所用,如果需要这样做,浮点标量必须与一个长整型标量一起放入一个联合中并且位位置必须由长整型标题指定(见上例)。1.4存贮器类型C51编译器完全支持8051微处理器及其系列的结构,可完全访问MCS-51硬件系统所有部分。每个变量可准确地赋予不同的存贮器类型(data,idata,pdata,xdata,code)。访问内部数据存贮器(idata)要比访问外部数据存贮器(xdata)相对要快一些,因此,可将经常使用的变量置于内部数据存贮器中,而将较大及很少使用的数据单元置于外部数据存贮器中。存贮器类型描述data直接寻址内部数据存贮器,访问变量速度最快(128bytes)bdata可位寻址内部数据存贮器,允许位与字节混合访问(16bytes)iIdata间接寻址内部数据存贮器,可访问全部地址空间(256bytes)pPdata分页(256bytes)外
本文标题:c51程序设计
链接地址:https://www.777doc.com/doc-7025589 .html