导航:首页 > 源码编译 > keilc51编译键

keilc51编译键

发布时间:2022-05-16 14:31:46

❶ “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头文件,

❷ keil c51 编译C语言 怎么单步执行 那个键子在哪啊

Debug--找到图中所示按钮即为单步运行

❸ 如何使用KeilC51创建一个工程文件

如何使用KeilC51创建一个工程文件

建立一个项目:

点击工程菜单中选择弹出的下拉式菜单中的新建 工程...,接着弹出一个标准Windows文件对话窗口,在"文件名"中输入您的第一个程序项目名称,这里我们用"test",这是笔者惯用的名称,大家不必照搬就是了,只要符合Windows文件规则的文件名都行。"保存"后的文件扩展名为uv2,这是KEIL uVision2项目文件扩展名,以后我们可以直接点击此文件以打开先前做的项目。

这时会弹出让你选择单片机型号的对话框,我们选择ATMEL---AT89C51

然后点击Target 1前面的“+”,出现Source Group 1,选中右键点选“增加文件到组 Source Group 1”

这时选择文件类型为Asm 源文件,再选中001.asm文件,再按添加,在随后出现的提示框中按“确定”

仿真器采用Mon51协议,在使用之前应必须对软件项目进行如下设置:

1、单击工程菜单,再在下拉菜单中单击"目标target 1属性" 在下图中,单击"Target"输入仿真器的工作频率(11.0592MHz)。

2、在调试菜单中点选"Keil Monitor-51 Driver",即选择了STC89C516RD硬件仿真器。

3、单击“R外围设备”选Target Setup设置选项选择您要使用串口(必须和实际相符合),波特率 38400。

如果被仿真的目标板使用12MHZ或者是11.0592MHZ晶振时波特率选择38400,如果被仿真的目标板使用6MHZ晶振时波特率选择18400。

4、如果需要生成HEX代码给编程器烧写芯片的话,需要选中“生成 HEX 文件”的选项,按钮“选择OBJ文件夹...”是用来选择最终HEX文件的存放目录的。

5、按F7快捷键可以进行编译,编译成功后如会出现上图红箭头所指的文字,表示编译成功!

然后可以进行硬件仿真了,将仿真器放入51单片机试验开发板的40脚活动插座中,这时仿真器的电源由实验开发板提供。

现在按Ctrl+F5可以进入仿真,这时再按F5全速运行状态。

这时你会看到实验板开发板P1的八个红色LED,轮流点亮,表示运行成功,你可以查看相关的变量和参数,非常方便,这里我们完整演示一个汇编语言的仿真过程,其实KEIL C最擅长的还是C语言,建议有基础的网友尽量采用C语言。

当首次使用一新的工程调试时可能出现下面的界面,说明KEIL软件和仿真器之间通讯失败,原因是你尚未

设定好串口及波特率。

请按选Settings然后按下图设好串口(根据你的实际使用端口,以下假定为COM1)及波特率。

然后按F7,进行通讯连接,再按Ctrl+F5可以进入仿真,这时再按F5全速运行状态。

❹ keil里面编译的c51问题

你注意以下几个关键点:
uint ad_covert() //
{
uint temp1,temp2;

temp1=258;
return (temp1); //返回AD转换数据 取八位结果
}

这些,都没有问题,如果正常的话,函数永远返回的是 常数258,.
但是,如果你的 result 定义成 uchar类型的,那么,result的结果就永远都是2.
因为uchar类型的数据,是8位数据,最大的数是 255,所以,对于大于 255的数字,就相当于对256取余数,因为你的函数永远返回 258,大于 255,所以对256取余数的结果是 2。
这就是为什么总是 2的原因,如果你的result定义成 uint类型,那么,结果就永远是 258.

❺ KEIL C51的编译指令#pragma noiv什么意思

这样的问题直接查软件的帮助就可以找到啊。

编译指令NOIV
默认值:INTVECTOR(0)
描述:NOIV(NOINTVECTOR)编译指令会抑制生成中断向量。借助这个编译指令,用户可以采用其它的编程工具产生中断向量,从而与本软件联合使用。

❻ 关于Keil C51编译的问题

COMMON.C(1): warning C500: LICENSE ERROR (R208: RENEW LICENSE ID CODE (LIC))
好像是说注册错误,要装破解版;
MAIN.C(9): error C202: 'TRO': undefined identifier第九行错误,应是TR0, O与0应区分

❼ keil C51程序编译的问题

如果你的H头文件包含在每个.C文件中,那就是说你的每个.C文件都定义了sbuf[20],KEIL就会提示你说你的sbuff[20]重复定义。我理解的应该是这个问题吧?

解决办法,要么用条件编译区分sbuff的作用域,就是在哪些.c文件中使用。
要么在一个.c文件中定义sbuff,在H文件中用外部声明包含进去,比如:
extern unsigned char data char sbuf[20];这样在其他的.C文件中,sbuff是引用而不是定义了。

一般都是采用第二种方式,H文件只存放外部声明。

❽ Keil C51编译的问题!

你主程序里没有别的程序代码了?
单片机在编译时,首先是进行编译预处理(头文件包括指令,宏定义处理,条件编译,各种伪指令等),然后再进入优化编译阶段,再进行汇编过程,接着是程序链接。

你在主程序中定义,unsigned char a[2]={1,2};数组,并分配两个存储单元。虽然在语法上是没有错,程序也能正确被编译。但程序在真正进行实质链接时,由于你并没有真正进行功能性的程序指定,编译时它会生成很多冗余的汇编代码,按照你定义的单元。上面生成的汇编,你如果仔细看,很多的条件跳转语句都是转到不同的内存单元。如:
DJNZ R7,C:001F //R7寄存器相减为0则转到001F,否则顺序执行。
DJNZ R7,C:004B
DJNZ R7,C:003F
INC DPTR
F2 MOVX @R0,A
INC R0
DJNZ R7,C:004B
而实际,编写程序,也没有你以上的那种做法,不可能只分配内存单元,而不做任何其它事情。我想,你这样做,无非就是想做个实验罢了。

❾ KEIL C51多文件编译

首先主函数只能存在于一个文件中,这个文件可以直接取名mian.c这样比较方便管理。然后按功能分其它文件,分别编写XX.h和XX.c文件,在XX.h中写入函数的声明和全局变量的定义,在XX.c中写函数的具体内容,并且在XX.c中要include“XX.h”,在mian.c中include所有的.h文件。这样就可以正常编译和烧写了。最终生成的还是一个hex文件

阅读全文

与keilc51编译键相关的资料

热点内容
汽车小压缩机拆解 浏览:825
云桌面卡是因为服务器的原因吗 浏览:377
qd123压缩机 浏览:969
pn532读取加密门禁卡 浏览:85
win10文件夹属性里无法加密 浏览:34
比特币加密的条件 浏览:848
求购现成影视app源码 浏览:572
wdsecurity加密版 浏览:813
云服务器和云丰云 浏览:188
服务器如何设置独立ip 浏览:857
tar命令打包文件夹 浏览:1000
删除linux用户和组 浏览:548
小米的程序员都用什么笔记本 浏览:703
字节三面算法题 浏览:971
服务器保护有什么好处 浏览:894
全部下载完后进行统一解压 浏览:393
远嫁的程序员妈妈 浏览:555
1024程序员节安全攻防挑战赛 浏览:786
怎么解除txt加密 浏览:772
javahttp流 浏览:656