首页 keil软件数据类型

keil软件数据类型

举报
开通vip

keil软件数据类型数据类型     在标准C语言中,存在着如下六种基本数据类型:     1、char:字符型;     2、short = short int:短整型     3、int:整型     4、long = long int:长整型     5、float:单精度浮点型     6、double:双精度浮点型     而面向51单片机的Keil uVision4对此进行了简化, 因此,可以理解为只存在如下四种基本数据类型:     1、char:字符型     2、int = short = short int:整型 ...

keil软件数据类型
数据类型     在标准C语言中,存在着如下六种基本数据类型:     1、char:字符型;     2、short = short int:短整型     3、int:整型     4、long = long int:长整型     5、float:单精度浮点型     6、double:双精度浮点型     而面向51单片机的Keil uVision4对此进行了简化, 因此,可以理解为只存在如下四种基本数据类型:     1、char:字符型     2、int = short = short int:整型     3、long = long int:长整型     4、float = double:单精度浮点型 其中,基本整型数据类型又可以通过signed关键词扩展为有符号的signed char、signed int、signed long类型,或通过unsigned关键词扩展为无符号的unsigned char、unsigned int、unsigned long类型;而对于不加关键词扩展的char、int、long本身,Keil uVision4则一律认为是signed类型(和c语言一致,均是默认为是有符号数字类型)。     应对51单片机硬件的一些特点,Keil uVision4还扩展了bit、sbit、sfr、sfr16等四种特殊基本数据类型,它们都是标准C中所没有的。其中:     1、bit:声明一个普通的位变量。例如:"bit flag;"。     2、sbit:声明特殊功能寄存器中的某一位。例如,使用"sbit TI = SCON^0;",就声明了TI为特殊功能寄存器SCON的第0位。     3、sfr:声明一个8位寄存器为特殊功能寄存器。例如,将51单片机内存地址0x98处的存储单元声明为8位特殊功能寄存器SCON,可以使用"sfr SCON = 0x98;"语句。     4、sfr16:声明一个16位的寄存器为特殊功能寄存器。为了将51单片机内存地址0xCC处开始的连续两个存储单元声明为一个统一的16位特殊功能寄存器T2,可以使用"sfr16 T2 = 0xCC;"语句。 需要注意的是,在Keil uVision4中,用sbit、sfr、sfr16声明特殊功能寄存器变量或特殊功能寄存器位变量时,其声明语句都只能放在函数外,而不能放在函数内,否则出现语法错误;而用bit声明普通位变量时,声明语句既可放在函数外,也可放在函数内(凡是带s的只能放在函数外)。此外,bit、sbit、sfr、sfr16都不支持指针和数组扩展,因此,不能定义bit、sbit、sfr、sfr16型指针和数组,且由这四种类型定义时就像普通类型定义一样,后边需加分号。当然,根据C语言标准,无论是sbit、sfr、sfr16还是bit,变量必须在使用之前(至少在使用之时)声明:这一点是显然的。     对于初学者来说,其实没有必要深究sbit、sfr、sfr16的用法,它们通常用在51单片机的系统自带头文件中,一般情况下无需用户关心。     表1整理了Keil uVision4支持的各种基本数据类型和属性,希望读者认真理解和领会。     表1 Keil uVision4面向51单片机的基本数据类型各种属性一览表       ╭════════════════════════════════╮       ║类  别║  数  据  类  型  ║长 度║          值  域            ║       ║════════════════════════════════║       ║      ║unsigned char    ║1字节║0~255                      ║       ║字符型║signed char      ║1字节║-128~+127                  ║       ║      ║char              ║1字节║-128~+127                  ║       ║════════════════════════════════║       ║      ║unsigned short int║2字节║0~65535                    ║       ║      ║signed short int  ║2字节║-32768~+32767              ║       ║      ║short int        ║2字节║-32768~+32767              ║       ║      ║════════════════════════════║       ║      ║unsigned short    ║2字节║0~65535                    ║       ║整  型║signed short      ║2字节║-32768~+32767              ║       ║      ║short            ║2字节║-32768~+32767              ║       ║      ║════════════════════════════║       ║      ║unsigned int      ║2字节║0~65535                    ║       ║      ║signed int        ║2字节║-32768~+32767              ║       ║      ║int              ║2字节║-32768~+32767              ║       ║════════════════════════════════║       ║      ║unsigned long int ║4字节║0~4294967295                ║       ║      ║signed long int  ║4字节║-2147483648~+2147483647    ║       ║      ║long int          ║4字节║-2147483648~+2147483647    ║       ║长整型║════════════════════════════║       ║      ║unsigned long    ║4字节║0~4294967295                ║       ║      ║signed long      ║4字节║-2147483648~+2147483647    ║       ║      ║long              ║4字节║-2147483648~+2147483647    ║       ║════════════════════════════════║       ║      ║float            ║4字节║±1.75494E-38~±3.402823E+38║       ║浮点型║double            ║4字节║±1.75494E-38~±3.402823E+38║       ║════════════════════════════════║       ║      ║bit              ║1位  ║0,1                        ║       ║位  型║sbit              ║1位  ║0,1                        ║       ║════════════════════════════════║       ║      ║sbit              ║1位  ║0,1                        ║       ║SFR 型║sfr              ║1字节║0~255                      ║       ║      ║sfr16            ║2字节║0~65535                    ║       ╰══════════════════════════════ reg51.头文件剖析         我们平时写单片机应用程序的时候,所使用的头文件大多都是用reg51.h或是用reg52.h。 打开  reg52.h  头文件,会发现是由大量的 sfr ,sbit的声明组成,甚至于还有sfr16.其实这样的声明都是与单片机内部功能寄存器(特殊功能寄存器)联系起来的,下面对其做出详细解释 sfr:  声明变量 SFR 声明一个变量,它的声明与其它的C变量声明基本相同,唯一的区别,SFR在声明的同时为其指定特殊功能寄存器作为存储地址,而不同于C变量声明的整型,字符型等等由编译器自动分配存储空间。   如reg52.h头文件,第一条声明就是sfr P0 = 0x80; 此处声明一个变量P0,并指定其存储地址为特殊功能寄存器0x80;,在加入reg52.h头文件后。编写应用程序时P0就可以直接使用而无需定义,对P0的操作就是,对内部特殊功能寄存器(0x80对应用MCU的P0口)的操作,可进行读写操作。 如果将第一条声明改为sfr K0    = 0x80; 那么,如果要把单片机的P0口全部拉低,则不能写P0=0x00;而应保存后再在应用程序中写成K0=0x00;否则编译器会提示“P0为未定义标识符”   使用方法:     sfr  [variable]  =  [address]  //为变量分配一个特殊功能寄存器。   1  等号右边,只能是十进制,十六进制整型的数据常量,,不允许带操作符的表达式       经典的8051内核支持的SFR地址从0x80H~0xFF 飞利浦80C51MX系列0x180H~0x1FF   2  SFR不能声明于任何函数内部,包括main函数。只能声明于函数外。   3  用SFR声明一个变量后,不能用取地址运算符&获取其地址, 编译无法通过,编译器会提示非法操作。   4  有一点须特别注意,51内核0x80~0xff,为特殊功能寄存器地址区间,但并不是所有的地址都有定义,如果说你所用的MCU芯片上对于某个地址没有定义,那么用sfr在定义变量的时候,不要把变量的地址分配到未定义的特殊功能寄存器上,虽然编译时能通过,用KEIL仿真时貌似是没有问题,但下载到芯片里运行时,是会出问题的。比如说,向一个未定义的特殊功能寄存器执行读操作,读出来的就是一个未知的数。(读者可自行测试,先把串口通信调通,然后做一个简单的人机交互。读出一个数后,再发给计算机,用串口调试助手或是串口监控查看。这用方法在仿真的时候很有用。)所以具体那些特殊功能寄存器能够用,就要查看你使用的芯片手册。 5 若遇到增强性的单片机,只要知道其扩展的特殊功能寄存器的地址,用SFR定 就可以很方便进行编程。 sbit:  声明变量   sbit 同样是声明一个变量,和SFR 使用方法类似,但是SBIT是用来声明一个位变量,因为,在51系列的应用中,非常有必要对SFR的单个位进行存取,而通过bit 数据类型,使其具备位寻址功能。       如,在reg52.h中有如下声明           sfr IE    = 0xA8;           sbit EA    = IE^7; sbit ET2  = IE^5; //8052 only sbit ES    = IE^4; sbit ET1  = IE^3; sbit EX1  = IE^2; sbit ET0  = IE^1; sbit EX0  = IE^0;   所以,对EA的操作即是对IE最高位的操作。 但如果想让 SP  DPL  DPH  PCON  TMOC  TL0  TL1  TH0  TH1  SBUF这些特殊功能寄存器具备位寻址,采用上述如IE类似的定义,是不行的,虽然修改后,在编译的时候不会出现错误,但只要用到你定义的位变量名时就会出错。原因是,只有特殊功能寄存器的地址是8的倍数(十六进制以0或8结尾)才能进行位寻址。 打开reg52.h头文件可以看到,所有用sbit声明了的特殊功能寄存器的地址均是以0或8结尾 如硬要达到上述要求,可用带参的宏定义来完成。此处不做详细说明(意义并不大)。 下面对sbit的使用做详细介绍: 随着8051的应用,非常有必要对特殊功能寄存器的单个bit位进行存取,C51编译器通过sbit 数据类型,提供了对特殊功能寄存器的位操作。       以下是sbit的三种应用形式: 一, sbit  name = sfr-name^bit-position;   sfr  PSW =0xD0;   sfr  IE  =0xA8;     sbit  OV= PSW^2;   sbit  CY=PSW^7;   sbit  EA= IE^7; 二, sbit  name= sft-address^bit-position;         sbit  OV =0xD0^2;         sbit  CY =0xD0^7;         sbit  EA =0xA8^7; 三, sbit  name= sbit-address;         sbit  OV =0xD2;         sbit  CY =0xD7;         sbit  EA =0xAF; 现对上述三种形式的声明做必要的说明       第一种形式sbit  name = sfr-name^bit-position;如sbit  OV= PSW^2;  当中的这个特殊功能寄存器必须在此之前已经用sfr 定义,否则编译会出错。 bit-position范围从0~7;       第二种形式  sbit  name= sft-address^bit-position如sbit  OV =0xD0^2;  与第一种形式不同之外在于,此处直接使用PSW的地址.第一种形式须先定义PSW       第三种形式.  sbit  name= sbit-address  如sbit  OV =0xD2 是直接用的OV的地址 OV的地址计算方式,是OV所在的寄存器地址加上OV的bit-position                           注意:             不是所有的SFR都可位寻址。只有特殊功能寄存器的地址是8的倍数(十六进制以0或8结尾)才能进行位寻址,并且sbit声明的变量名,虽可以是任意取,但是最好不要以下划线开头,因为以下划线开头的都保留给了C51的头文件做保留字。 sfr16: 声明变量       许多8051的派生型单片机,用两个连续地址的特殊功能寄存器,来存储一个16bit的值。例如,8052就用了0xCC和0xCD来保存定时/计数寄存器2的高字节和低字节。编译器提供sfr16这种数据类型,来保存两个字节的数据。虚拟出一个16bit的寄存器。       如下:               sfr16 T2 = 0xCC     存储方面为小端存储方式,低字节在前,高字节在后。定义时,只写低字节地址,如上,则定义T2为一个16位的特殊功能寄存器。 T2L= 0CCh, T2H= 0CDh     使用方法:     sfr  [variable]  =  [low_address]      1  等号右边,只写两个特殊功能寄存器的低地址,且只能是十进制,十六进制的整型数据常量,不允许带操作符的表达式   2  SFR不能声明于任何函数内部,包括main函数。只能声明于函数外。   3  用SFR声明一个变量后,不能用取地址运算符&获取其地址, 编译无法通过,编译器会提示非法操作。       4 当你向一个sfr16写入数据的时候,KEIL CX51 编译器生成的代码,是先写高字节,后写低字节,(可通过返汇编窗口查看)在有些情况下,这并非我们所想要的操作顺序。使用时,须注意。       5 当你所要写入sfr16的数据,当是高字节先写还是低字节先写非常重要的时候,就只能用sfr 这个关键字来定义,并且任意时刻只保存一个字节,这样操作才能保证写入正确。 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// C51常用头文件 在KEIL 中,对于单片机所使用的头文件,除了reg51 reg52以外,还有一些从各芯片制商的官网下载与reg51,reg52功能类似的头文件,需了解透外,还要对各类型单片机均可通用且相当有用的的头文件,做相应的了解。因为,内部所包含的函数与宏定义,可以及大的方便我们编写应用程序。 1字符函数  ctype.h     1  extern bit isalpha(char);         功能:检查参数字符是否为英文字母,是则返回1 2 extern bit isalnum(char)     功能:检查字符是否为英文字母或数字字符,是则返回1 3 extern bit iscntrl(char)             功能:检查参数值是否在0x00~0x1f 之间或等于0x7f,是则返回1 4  extern bit isdigit(char)     功能: 检查参数是否为数字字符,是则返回1 5  extern bit isgraph(char)             功能: 检查参数值是否为可打印字符,是则返回1,可打印字符为0x21~0x7e 6 extern bit isprint(char)     功能:除了与isgraph相同之外,还接受空格符0x20 7 extern bit ispunct(char)   功能:不做介绍。 8 extern bit islower(char)     功能:检查参数字符的值是否为小写英文字母,是则返回1 9 extern bit isupper(char)             功能:检查参数字符的值是否为大写英文字母,是则返回1 10 extern bit isspace(char)     功能:检查字符是否为下列之一,空格,制表符,回车,换行,垂直制表符和送纸。如果为真则返回1 11 extern bit isxdigit(char)             功能:检查参数字符是否为16进制数字字符,是则返回1 12 extern char toint(char)     功能:将ASCII字符0~9  a~f(大小写无关)转换成对应的16进制数字, 返回值00H~0FH 13 extern char tolower(char)             功能:将大写字符转换成小写形式,如字符变量不在A~Z之间,则不作转换而直接返回该字符 14 extern char toupper(char)     功能:将小写字符转换成大写形式,如字符变量不在a~z之间,则不作转换而直接返回该字符 15 define toascii(c)  ((c)&0x7f) 功能:该宏将任何整形数值缩小到有效的ASCII范围之内,它将变量和0x7f相与从而去掉第7位以上的所有数位 16 #define tolower(c)  (c-‘A’+’a’) 功能:该宏将字符与常数0x20 逐位相或 17 #define toupper(c)  ((c)-‘a’+’A’) 功能:该宏将字符与常数0xdf 逐位相与 2数学函数 math.h extern int    abs  (int  val); extern char  cabs  (char  val); extern long  labs  (long  val); extern float  fabs  (float  val); 功能:返回绝对值。上面四个函数,除了形参和返回值不一样之外, 其它功能完全相同。 extern float exp    (float val); extern float log    (float val); extern float log10  (float val);   功能: exp  返回eval         log  返回 val 的自然对数         log10 返回 以10为底,val的对数         extern float sqrt  (float val);   功能:      返回val的正平方根       extern int rand()();       extern void srand()(int n);         功能:  rand()返回一个0到32767之间的伪随机数,srand用来将随机数发生器初始化成一个已知的(期望)值。         Keil uVision3中的math.h库中,不包含此函数。       extern float sin  (float val); extern float cos  (float val); extern float tan  (float val);   功能:  返回val的正弦,余弦,正切值。val为弧度  fabs(var) <=65535 extern float asin  (float val); extern float acos  (float val); extern float atan  (float val); extern float atan2 (float y, float x);   功能: asin 返回val的反正弦值。acos 返回val的反余弦值。         atan 返回val的反正切值。         asin atan acos的值域均为  -π/2~+π/2         atan2返回x/y,的反正切值,其值域为-π~+π extern float sinh  (float val); extern float cosh  (float val); extern float tanh  (float val);   功能:cosh返回var的双曲余弦值,sinh返回var的双曲正弦值,         tanh返回var的双曲正切值。 extern float ceil  (float val);   功能:  向上取整,返回一个大于val的最小整数。 extern float floor (float val);   功能:  向下取整,返回一个小于val的最大整数。 extern float pow  (float x, float y);   功能: 计算计算xy的值。当(x=0,y<=0)或(x<0.y不是整数)时会发生错误。 extern void fpsave(struct FPBUF *p) extern void fprestore(struct FPBUF *p)   功能:fpsave 保存浮点了程序的状态,fprestore恢复浮点子程序的原始状态,当中断程序中需要执行浮点运算时,这两个函数是很有用的。       注:  Keil uVision3中的math.h库中,不包含此函数。 3绝对地址访问 absacc.h #define CBYTE ((unsigned char volatile code  *) 0) #define DBYTE ((unsigned char volatile data  *) 0) #define PBYTE ((unsigned char volatile pdata *) 0) #define XBYTE ((unsigned char volatile xdata *) 0)   功能:CBYTE  寻址    CODE区         DBYTE  寻址    DATA区         PBYTE  寻址    XDATA(低256)区         XBYTE  寻址    XDATA区   例: 如下指令在对外部存储器区域访问地址0x1000       xvar=XBYTE[0x1000];       XBYTE[0x1000]=20; #define CWORD ((unsigned int volatile code  *) 0) #define DWORD ((unsigned int volatile data  *) 0) #define PWORD ((unsigned int volatile pdata *) 0) #define XWORD ((unsigned int volatile xdata *) 0)   功能:与前面的一个宏相似,只是它们指定的数据类型为unsigned int .。         通过灵活运用不同的数据类型,所有的8051地址空间都是可以进行访问。 如 DWORD[0x0004]=0x12F8; 即内部数据存储器中(0x08)=0x12; (0x09)=0xF8 4 内部函数 intrins.h extern unsigned char _cror_    (unsigned char  var, unsigned char  n); extern unsigned int  _iror_    (unsigned int    var, unsigned char  n); extern unsigned long _lror_    (unsigned long  var, unsigned char  n);   功能:将变量var 循环右移 n 位。 上三个函数的区别在于,参数及返回值的类型不同 extern unsigned char _crol_    (unsigned char  var, unsigned char  n); extern unsigned int  _irol_    (unsigned int    var, unsigned char  n); extern unsigned long _lrol_    (unsigned long  var, unsigned char  n);   功能:将变量var 循环左移 n 位。 上三个函数的区别在于,参数及返回值的类型不同   例如:     #include       void main()         {           unsigned int y;           y=0x0ff0;           y=_irol_(y,4);    //y=0xff00           y=_iror_(y,4);    //y=0x0ff0 } void  _nop_(void);   功能:_nop_产生一个8051单片机的NOP指令,C51编译器在程序调用_nop_ 函数的地方,直接产生一条NOP指令。
本文档为【keil软件数据类型】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_219945
暂无简介~
格式:doc
大小:53KB
软件:Word
页数:0
分类:生活休闲
上传时间:2017-09-19
浏览量:34