keil内存分配 您所在的位置:网站首页 idata汇编 keil内存分配

keil内存分配

2023-03-14 23:50| 来源: 网络整理| 查看: 265

本文目录一览:

1、malloc()函数在keil中使用应注意什么 2、C语言使用kile的高手来 3、您好请问您以前提问的keil arm c里面如何使用动态内存分配,怎么解决的呀。求指教 4、C语言 可以分配1bit的内存么..要怎么分配 5、Keil C51下如何让编译器优先使用片内RAM 6、keil arm c里面如何使用动态内存分配 malloc()函数在keil中使用应注意什么

在keil 中使用malloc()函数经常会遇到不正常的情况,通常表现为不能正确分配内存空间,或者只能分配很小的空间。

出现这个问题的原因大概有三个:

1、所用的ARM芯片本身内存已经被其代码占用,所余空间不够malloc分配。

解决办法:A、释放其他代码浪费的RAM空间;B、扩容。

2、未进行堆的初始化:在KEIL中使用malloc函数时,必需要对heap进行初始化,否则不能正常使用malloc。

解决办法:A、使用KEIL自带的启动代码,该汇编启动代码本身已经完成了对heap的初始化;(我们通常建立的工程都是使用KEIL自带的启动代码,或者在该基础上修改的代码,所以这个问题基本上不用考虑)

B、自己编写heap初始化汇编代码,该初始化代码必须放在调用C代码之前,最好放在启动代码中。

3、堆空间太小。

解决办法:在堆初始化代码中,将堆大小增加,一般0x400大小足够,如果不够的话,可根据实际调试情况进行增加。

C语言使用kile的高手来

一楼你是做计算机的吧,计算机的软件开发和单片机的不一样。

楼主要做单片机首先要学好电子技术。因为单片机和硬件电路密切相关,电路改动一点点,你的程序可能要完全改变了。

其次,你要先把你的单片机基础理论学好了,比如定时器、中断、串口通信等等必须要懂。

学单片机程序设计,要先记好单片机的汇编命令(各种单片机之间的汇编指令是不尽相同的,和计算机的汇编更加不一样)。看你说的应该不是kile C ,而是keil这个软件,它支持51系列单片机(也支持32位的ARM),可以编译51的汇编文件和C文件,可以软件仿真程序也可以连接仿真器仿真硬件电路板。还有一种是南京伟福公司的WAVE软件,也可以编译51的汇编和C文件。

你的串号我已经记下,采纳后我会帮你制作

您好请问您以前提问的keil arm c里面如何使用动态内存分配,怎么解决的呀。求指教

你的意思是要用 malloc()动态申请内存?如果是,我知道但是我不告诉你。最好不要用动态申请内存,因为加入这个玩意儿的支持代码量会变大。而且在嵌入式平台上开发是不建议这么做的,因为嵌入式平台的内存跟PC不是一个等级,很容易申请失败的,也就是说你的程序很容易跑死掉,建议还是全部用静态的数组吧,只要你能够静态申请下来,你使用的过程中绝对不会出错,内存绝对够是不是?

C语言 可以分配1bit的内存么..要怎么分配

内存分配最小单位是字节,一个字节8个bit。

你如果需要单独使用一个bit,那就申请1个字节,只用其中的1bit,其余7bit不用就是了。

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;i6;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;i7;i++)

{

id[i]=*point;

point++;

}

(此处只是对指针做一个小的介绍,达到访问内部任何空间的方式,后述有对指针使用的详细介绍)

2对SFR,RAM ,ROM的直接存取

C51提供了一组可以直接对其操作的扩展函数

若源程序中,用#include包含头文件,io51.h 后,就可以在扩展函数中使用特殊功能寄存器的地址名,以增强程序的可读性:

注 此方法对SFR,RAM,ROM的直接存取不建议使用.因为,淡io51.h这个头文件在KEIL中无法打开,可用指针,或是采用absacc.h头文件,

keil arm c里面如何使用动态内存分配

首先: SWI_Handler B SWI_Handler

代表的是 软中断 的入口

其次:他是一个死循环。

再次: 你调用的那个函数 是个 软中断 函数(肯定在某个地方 注册软中断过)。

最后:和你的那个动态分配内存 应该无关!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有