A. 什么是keil c51
Keil
C51是美国Keil
Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部分组合在一起。运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。
B. keil c51软件的作用是什么
编译程序,是单片机C语言的主要编译工具
C. Keil C51语言具有哪些特点
Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。用过汇编语言后再使用C来开发,体会更加深刻。 Keil C51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。下面详细介绍Keil C51开发系统各部分功能和使用。 2. Keil C51单片机软件开发系统的整体结构 C51工具包的整体结构,如图(1)所示,其中uVision与Ishell分别是C51 for Windows和for Dos的集成开发环境(IDE),可以完成编辑、编译、连接、调试、仿真等整个开发流程。开发人员可用IDE本身或其它编辑器编辑C或汇编源文件。然后分别由C51及A51编译器编译生成目标文件(.OBJ)。目标文件可由LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件(.ABS)。ABS文件由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如EPROM中。
D. keil软件的作用是什么 谁能分享
软件介绍:
keil c51是一款应用于plc编程的软件开发工具,它拥有强大的仿真器、调试器、宏汇编器、单板计算机以及符合生产标准的Keil C编译器,在嵌入式软件开发的基础上有深层次的研发进展,帮助您在嵌入式开发上准确模拟硬件配置,以详尽的测试报告对定量的数据进行简单合理的分析。
所需工具:点击下载 keil c51
安装教程
1、在本站下载好安装包,双击运行“c51v956.exe”程序,弹出软件安装向导,点击“Next”开始安装;
2、勾选“I agree to all the terms”同意许可证协议,协议内容自行决定是否浏览,点击“Next”继续安装;
3、自定义软件安装目录,默认路径为“C:Keil_v5”,安装路径选择时不要带有英文符号的路径,点击“Next”进行安装
4、填写个人基本信息,完成后点击“Next”跳过;
5、等待安装进度完成,点击“finish”完成安装;
功能介绍
1、BL51链接器/定位器:组合由C51和A51产生的可重定位的目标模块,生成绝对目标模块。
2、A51宏汇编器:从89C51汇编源代码产生可重定位的目标模块。
3、OH51目标文件至HEX格式的转换器,从绝对目标模块生成Intel Hex文件。
4、μVision4 for Windows:是一个集成开发环境,它将项目管理、程序调试、源代码编辑等组合在一个功能强大的环境中
5、RTX-51实时操作系统:简化了复杂的实时应用软件项目的设计。
6、C51国际际准化C交叉编译器:从C源代码产生就可以重定位的目标模块。
7、LIB51库管理器:从目标模块生成连接器可以使用的库文件。
软件特色
1、Software packs – MDK软件包
这部分较MDK v4版本做出了很大的更新。Software packs分为Device、CMSIS、MDK Professional Midleware三个小部分,包含了各类可用的设备驱动。。
MDK v5可以在Software packs窗口选择需要安装或者更新的软件组件。
2、MDK Core – MDK核心
MDK Core包含微控制器开发所有的所有组件,包括IDE(uVision5)、编辑器、ARM C/C++编辑器、uVision调试跟踪器和Pack Installer。
3、uVision5 IDE集成开发界面
uVision5 IDE 集成开发环境与uVision4相差不大,在编译工具栏右侧多了两个绿色按钮,Manage Run-time Environment和Pack Installer按钮。
MDK Core是一个独立的安装包,大概300M左右大小,可以到ARM国内代理商米尔科技官网下载正式版本。下载安装以后就可以一直使用,如果Keil有芯片支持、CMSIS或者中间库的升级,直接通过Software packs本地升级即可。
E. gcc编译器和嵌入式keil的C51编译器有什么不
前者是通用的C语言编译器,后者相当于是个定制版。C51中定义了一些原先C语言中没有的类型以及寄存器定义、同时鉴于单片机通常只有几KB的内存空间进行了代码生成量优化,专门用于单片机的开发,这些都是在GCC这样标准的ANSI C编译器中所没有的。
F. keil c51的简介
支持8051微控制器体系结构的Keil开发工具,适合每个阶段的开发人员,不管是专业的应用工程师,还是刚学习嵌入式软件开发的学生。 Keil C51目前由ARM国内授权代理商提供技术支持和销售等相关服务。 产业标准的Keil C编译器、宏汇编器、调试器、实时内核、单板计算机和仿真器,支持所有的251系列微控制器,帮助你如期完成项目进度。
以下图表显示Keil的开发工具以及它们相互之间的接口。
KEIL C51开发工具旨在解决嵌入式软件开发商面临的复杂问题。
当你开始一个新项目,只需简单的从设备数据库选择使用的设备,uVision IDE将设置好所有的编译器、汇编器、链接器和存储器选项。
包含大量的例程,帮助你着手使用最流行的嵌入式8051设备。
Keil μVision调试器准确地模拟8051设备的片上外围设备(IC、CAN、UART、SPI、中断、I/O端口、A/D转换器、D/A转换器和PWM模块)。模拟帮助你了解硬件配置,避免在安装问题上浪费时间。 此外,使用模拟器你可以在没有目标设备的情况下编写和测试应用程序。
当你准备在目标硬件上测试软件应用时,可以使用MON51、MON390、NONADI、或者FlashMON51目标监视器、ISD51 In-System调试器、ULINK USB-JTAG适配器在目标系统上下载并测试程序代码。
G. keil c51的所有头文件,其作用。
我来回答你的问题吧,前几天对这个方面有一定的深入了解,也写下了大量的笔记
虽然C编程的时候,对于不同的芯片,有不同的头文件,但是,万变不离其宗。
只要学会了写自己的头文件,就可以应付各类型号单片机了,就算你用的是AT89C2052,还是AT89C51,STC12C等等,都可以用一个头文件reg51.h 不过要做相应的修。
以下是我对reg51.h个人的见解:(对于你很有用的) 后面带上了在编写C51时带用的头文件,及其内部函数和宏定义的详细解说。
想了解如下方面的知识来来邮[email protected]
一, 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指令。
H. “Keil C51”下如何让编译器优先使用片内“RAM”
C51内存结构深度剖析
在编写应用程序时,定义一个变量,一个数组,或是说一个固定表格,到底存储在什么地方;当定义变量大小超过MCU的内存范围时怎么办;如何控制变量定义不超过存储范围;以及如何定义变量才能使得变量访问速度最快,写出的程序运行效率最高。以下将一一解答。
1 六类关键字(六类存储类型)
data idata xdata pdata code bdata
code: code memory (程序存储器也即只读存储器)用来保存常量或是程序。code memory 采用16位地址线编码,可以是在片内,或是片外,大小被限制在64KB
作用:定义常量,如八段数码表或是编程使用的常,在定义时加上code 或明确指明定义的常量保存到code memory(只读)
使用方法:
char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
此关键字的使用方法等同于const
data data memory (数据存储区)只能用于声明变量,不能用来声明函数,该区域位于片内,采用8位地址线编码,具有最快的存储速度,但是数量被限制在128byte或更少。
使用方法:
unsigned char data fast_variable=0;
idata idata memory(数据存储区)只能用于声明变量,不能用来声明函数. 该区域位于片内,采用8位地址线编码,内存大小被限制在256byte或更少。该区域的低地址区与data memory地址一致;高地址区域是52系列在51系列基础上扩展的并与特殊功能寄存器具有相同地址编码的区域。即:data memory是idata memory的一个子集。
xdata xdata memory 只能用于声明变量,不能用来声明函数,该区域位于MCU
外部,采用16位地址线进行编码,存储大小被限制在64KB以内。
使用方法:
unsigned char xdata count=0;
pdata pdata memory 只能用于声明变量,不能用来声明函数,该区域位于MCU外部,采用8位地址线进行编码。存储大小限制在256byte. 是xdata memory的低256byte。为其子集。
使用方法
unsigned char pdata count=0;
bdata bdata memory 只能用于声明变量,不能用来声明函数。该区域位于8051内部位数据地址。定义的量保存在内部位地址空间,可用位指令直接读写。
使用方法:
unsigned char bdata varab=0
注:有些资料讲,定义字符型变量时,在缺省unsigned 时,字符型变量,默认为无符号,与标准C不同,但我在Keil uVision3中测试的时候发现并非如此。在缺省的情况下默认为有符号。或许在以前的编译器是默认为无符号。所以看到有的资料上面这样讲的时候,要注意一下,不同的编译器或许不同。所以我们在写程序的时候,还是乖乖的把unsigned signed 加上,咱也别偷这个懒。
2函数的参数和局部变量的存储模式
C51 编译器允许采用三种存储器模式:SMALL,COMPACT 和LARGE。一个函数的存储器模式确定了函数的参数的局部变量在内存中的地址空间。处于SMALL模式下的函数参数和局部变量位于8051单片机内部RAM中,处于COMPACT和LARGE模式下的函数参数和局部变量则使用单片机外部RAM。在定义一个函数时可以明确指定该函数的存储器模式。方法是在形参表列的后面加上一存储模式。
示例如下:
#pragma large //此预编译必须放在所有头文前面
int func0(char x,y) small;
char func1(int x) large;
int func2(char x);
注:
上面例子在第一行用了一个预编译命令#pragma 它的意思是告诉c51编译器在对程序进行编译时,按该预编译命令后面给出的编译控制指令LARGE进行编译,即本例程序编译时的默认存储模式为LARGE.随后定义了三个函数,第一个定义为SMALL存储模式,第二个函数定义为LARGE第三个函数未指定,在用C51进行编译时,只有最后一个函数按LARGE存储器模式处理,其它则分别按它们各自指定的存储器模式处理。
本例说明,C51编译器允许采用所谓的存储器混合模式,即允许在一个程序中将一些函数使用一种存储模式,而其它一些则按另一种存储器模式,采用存储器混合模式编程,可以充分利用8051系列单片机中有限的存储器空间,同时还可以加快程序的执行速度。
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
注:用以上八个函数,可以完成对单片机内部任意ROM和RAM进行访问,非常方便。还有一种方法,那就是用指钟,后面会对C51的指针有详细的介绍。
4寄存器变量(register)
为了提高程序的执行效率,C语言允许将一些频率最高的那些变量,定义为能够直接使用硬件寄存器的所谓的寄存器变量。定义一个变量时,在变量类型名前冠以“register” 即将该变量定义成为了寄存器变量。寄存器变量可以认为是一自动变量的一种。有效作用范围也自动变量相同。由于计算机寄存器中寄存器是有限的。不能将所有变量都定义成为寄存器变量,通常在程序中定义寄存器变量时,只是给编译器一个建议,该变量是否真正成为寄存器变量,要由编译器根据实际情况来确定。另一方面,C51编译器能够识别程序中使用频率最高的变量,在可能的情况下,即使程序中并未将该变量定义为寄存器变量,编译器也会自动将其作为寄存器变量处理。被定义的变量是否真正能成为寄存器变量,最终是由编译器决定的。
5内存访问杂谈
1指钟
指钟本身是一个变量,其中存放的内容是变量的地址,也即特定的数据。8051的地址是16位的,所以指针变量本身占用两个存储单元。指针的说明与变量的说明类似,仅在指针名前加上“*”即可。
如 int *int_point; 声明一个整型指针
char *char_point; 声明一个字符型指针
利用指针可以间接存取变量。实现这一点要用到两个特殊运算符
& 取变量地址
* 取指针指向单元的数据
示例一:
int a,b;
int *int_point; //定义一个指向整型变量的指针
a=15;
int_point=&a; //int_point指向 a
*int_point=5; //给int_point指向的变量a 赋值5 等同于a=5;
示例二:
char i,table[6],*char_point;
char_point=table;
for(i=0;i<6;i++)
{
char_point=i;
char_point++;
}
注:
指针可以进行运算,它可以与整数进行加减运算(移动指针)。但要注意,移动指针后,其地址的增减量是随指针类型而异的,如,浮点指针进行自增后,其内部将在原有的基础上加4,而字符指针当进生自增的时候,其内容将加1。原因是浮点数,占4个内存单元,而字符占一个字节。
宏晶科技最新一代STC12C5A360S2系列,每一个单片机出厂时都有全球唯一身份证号码(ID号),用户可以在单片机上电后读取内部RAM单元F1H~F7H的数值,来获取此单片机的唯一身份证号码。使用MOV @Ri 指令来读取。下面介绍C51 获取方法:
char id[7]={0};
char i;
char idata *point;
for(i=0;i<7;i++)
{
id[i]=*point;
point++;
}
(此处只是对指针做一个小的介绍,达到访问内部任何空间的方式,后述有对指针使用的详细介绍)
2对SFR,RAM ,ROM的直接存取
C51提供了一组可以直接对其操作的扩展函数
若源程序中,用#include包含头文件,io51.h 后,就可以在扩展函数中使用特殊功能寄存器的地址名,以增强程序的可读性:
注 此方法对SFR,RAM,ROM的直接存取不建议使用.因为,淡io51.h这个头文件在KEIL中无法打开,可用指针,或是采用absacc.h头文件,
I. 为什么KEIL编译按钮是灰色的
要把c文件添加到目录下。
然后分别由C51及C51编译器编译生成目标文件(.obj)。目标文件可由LIB51 创建生成库文件,也可以与库文件一起经L51 连接定位生成绝对目标文件(.abs)。
abs文件由OH51 转换成标准的hex 文件,以供调试器dScope51 或tScope51 使用进行源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如EPROM中。
(9)keilc51编译器的作用扩展阅读:
Keil C51标准C编译器为8051微控制器的软件开发提供了C语言环境,同时保留了汇编代码高效,快速的特点。C51编译器的功能不断增强,使你可以更加贴近CPU本身,及其它的衍生产品。
C51已被完全集成到μVision2的集成开发环境中,这个集成开发环境包含:编译器,汇编器,实时操作系统,项目管理器,调试器。μVision2 IDE可为它们提供单一而灵活的开发环境。
J. keiluvision2软件编程
KeiluVision2是德国KeilSoftware公司出品的51系列兼容单片机C语言软件开发系统,使用接近于传统c语言的语法来开发,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用,而且大大的提高了工作效率和项目开发周期,他还能嵌入汇编,您可以在关键的位置嵌入,使程序达到接近于汇编的工作效率。KEILC51标准C编译器为8051微控制器的软件开发提供了C语言环境,同时保留了汇编代码高效,快速的特点。C51编译器的功能不断增强,使你可以更加贴近CPU本身,及其它的衍生产品。C51已被完全集成到uVision2的集成开发环境中,这个集成开发环境包含:编译器,汇编器,实时操作系统,项目管理器,调试器。uVision2IDE可为它们提供单一而灵活的开发环境。