问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

keil软件里面c语言包含哪些头文件?做什么用的?尽量多列举点

发布网友 发布时间:2022-04-24 12:43

我来回答

4个回答

热心网友 时间:2022-04-18 09:06

我来回答你的问题吧,前几天对这个方面有一定的深入了解,也写下了大量的笔记
虽然C编程的时候,对于不同的芯片,有不同的头文件,但是,万变不离其宗。
只要学会了写自己的头文件,就可以应付各类型号单片机了,就算你用的是AT89C2052,还是AT89C51,STC12C等等,都可以用一个头文件reg51.h 不过要做相应的修。

以下是我对reg51.h个人的见解:(对于你很有用的) 后面带上了在编写C51时带用的头文件,及其内部函数和宏定义的详细解说。
想了解如下方面的知识来来邮amwjie72@163.com
一, C51内存结构深度剖析
二, reg51.头文件剖析
三, 浅淡变量类型及其作用域
四, C51常用头文件
五, 浅谈中断
六, C51编译器的*
七, 小淡C51指针

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
reg51.头文件剖析

我们平时写单片机应用程序的时候,所使用的头文件大多都是用的的reg51.h或是用reg52.h。会写C51的人都会用,但对其头文件内部的定义有所了解的人确并不多。
下面对其内部做详细解释,方便读者作进一步的了解,并能运用各类型号的单片机。因为增强型号的单片机的增强功能都是通过特殊功能寄存器控制。

打开 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<intrins.h>
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指令。

热心网友 时间:2022-04-18 10:24

包含的头文件很多,我的uVision2有一百四五十个头文件,你可以在Keil\C51\INC里查看
在Keil\C51\INC里,你可以看见不同公司的文件夹,里面都有不同型号单片机的头文件,这些头文件里大部分是位定义和特殊寄存器的定义。
比如你说的AT89X52.H和AT89X51.H吧,52比51多一个定时器,那就多了那个特殊寄存器的定义,
再比如REG52.H这个头文件吧,它不对应一款单片机,它是52的通用寄存器定义头文件
还有一些是标准C语言的头文件,比如stdio.h,math.h,string.h,float.h等等

热心网友 时间:2022-04-18 11:59

at是atmel公司出产的一系列单片机编程头文件,还有别的公司出产的,也有头文件,一般的你可以打开keil的程序来查看有哪些头文件,C:\Keil\C51\INC\Atmel,这个文件夹内都是atmel公司的,其他的也类似

热心网友 时间:2022-04-18 13:50

是的,每一种单片机对应一种头文件,并且这些还都是固定的。
记住就行了。这些头文件就是定义一些地址用什么样的字符表示。
为的是编程时写着方便。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
通达信主力指标公式汇总(2023版附源码) 有什么类似地下城与勇士的手机游戏 有没有类似于DNF的游戏 苹果手机类似地下城的游戏 有什么类似地下城与勇士的手机游戏 我的系统是WIN732,为什么玩不了光晕2,一点开就弹一个对话框出来说:无法... 玩诛仙电脑配置诛仙3要求电脑配置 ...永磁为什么要跌啊?东方财富金力永磁股吧?金力永磁股票最初..._百度... 怎么找回注销的微信号 如果把手机号码和微信号同时销户后期还能找回微信号吗? 仓储与库存有什么区别? 仓位和库位的区别 keil uvision4 用c语言编译没有错误,但是个别语句被忽略了没有编译成汇编语言。怎么回事啊? volatile到底有没有用? Keil uVision5为何编译时,不产生“变量在使用前未赋初值(is used before its value is set)”的警告? 我要在keil中头文件声明和C文件定义头文件中的变量,可是我在头文件中声明后再到C文件中定义的时候 keil中pdata是关键字吗 keil c51优化等级介绍 keil 处理浮点数问题。 如何保证全部变量不被优化 keil 为什么keil 不加volatile也没问题 怎样在手机里的word 二手房使用公积金贷款最低首付比例是多少? 二手房首付比例是多少? 安卓手机里的word文档在哪个文件夹 二手房按揭贷款首付多少? 二手房的贷款首付一般需要多少 买二手房首付怎么算,比如买55万的房子,首付多少,税费一共要交多少?可以贷款多少? 二手房一般最低首付多少? 目前想买二手房,按揭贷款的话首付最低要付多少? 如何用柚子皮除臭? 柚子皮有什么作用?可以用来除臭吗? keil奇怪问题 keil C code区 数组定义问题 keil c51中如何在中断中改变全局变量的值? Keil C51下如何让编译器优先使用片内RAM keil主函数循环体可以单步调试吗?比如: keil里面为什么if条件满足了,但里面有一调语句执行不了? c语言*(volatile unsigned char xdata *) 0x2f5f,这个表示方法是什么意思? 单片机keil编程-流水灯-的问题 keil+proteus仿真arm,keil设置导致串口乱码问题 小米手机锁了怎么恢复出厂设置 小米手机忘记了锁屏密码怎样恢复出厂设置? 我的小米手机恢复出厂设置后就设备锁锁住了。小米帐号密码也忘记了。 小米手机设备锁锁了恢复出厂设置设备还是锁着吗? 我的苹果手机打电话听筒里面怎么有杂音? 为什么苹果xs通话时会有杂音? 求军婚完结小说,甜宠无虐,越多越好。 带上详细的介绍。 最好是自己看... 苹果11听筒杂音严重该怎么弄呢? 军婚小说排行榜前10名 小主子军婚系宠小说 军婚小说,重生小说都可以