找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2751|回复: 0
收起左侧

C语言指针变量访问ROM中数组常量的方法

[复制链接]
ID:351097 发表于 2020-2-28 16:54 | 显示全部楼层 |阅读模式
    当使用到ASCII码字库点阵的时候,我们习惯定义一个大的数组来存放。如果没有指定存储区域,数组一般都是保存在RAM当中的,如果单片机的RAM空间比较紧张,就需要将数组保存在ROM当中。对于51单片机,如果只在数组前加const,只是声明这个数组的内容是只读的,但是,数组还是保存在RAM中的,可以通过查看代码空间大小进行验证。网上还有不少人认为只要声明const,就是只读的,就是放在ROM里面的,这个是错误的。这个只读只是你无法直接更改数组的内容,因为编译器会强制报错。但是,通过指针指向数组的方式,还是可以间接更改数组的内容的。要指定数组保存在ROM里,除了需要const关键字,还需要加上数据存储类型(区域修饰符)。对于keil,用code表明变量存放在ROM中;对于IAR for 8051,用__code表面变量存放在ROM中。由于我用的平台是IAR for 8051,单片机是STC8A8K64S4A12,测试也是基于这个平台。下面讲一下用指针访问ROM中数组的方法。 首先定义一个数组                                                                                                                                                                          __code const unsignde char array[] = {0x11,0x22,0x33,0x44};//声明数组保存在ROM里
再定义一个指针:                                                                                                                                                                                      
unsigned char __code const *p;//这是一个指针,指向code区域的unsigned char常量(const)
再获取数组的首地址                                                                                                                                                                                      
p = array;//指向数组首地址                                                                                                                                                                           
    这里指针p一定要用__code修饰,如果不用__code修饰,会报错。指针可以正常访问ROM中数组的内容。
不过可能有人可能会这样做:                                                                                                                                                                           
__code const unsignde char array[] = {0x11,0x22,0x33,0x44};//声明数组保存在ROM里                                                                                      
unsigned char *p;                                                                                                                                                                                       
p = (unsigned char*)array;//指向数组首地址   (类型强制转换)                                                                                                                  
    这样虽然编译不会报错,p指向的地址就是数组存放在ROM当中的地址值,这样看起来没问题,把地址值打印出来验证也正确,但是在使用的时候,会发现怎么也没法访问到正确的数组内容,而是其他内容,感觉像是指针跑飞了一样。其实原因很简单,定义指针p时没有加上__code,那么p指向的地址空间是在RAM里面的。也就是在RAM中访问和ROM相同地址值的内容,当然永远也无法访问到数组的内容的。                                                     
    如果硬要这样定义指针p,也不是没有办法访问ROM中的数组。比如先将ROM数组复制到RAM中,再进行访问,可以按照如下操作:                    
__code const unsignde char array[] = {0x11,0x22,0x33,0x44};//声明数组保存在ROM里                                                                                    
unsigned char *p;                                                                                                                                                                                       
unsigned char a[4];                                                                                                                                                                                      
for(unsigned char i = 0; i < 4; i++)                                                                                                                                                                  
{                                                                                                                                                                                                                  
    a[ i] = array[ i]; //直接访问ROM的数组,再复制到RAM中                                                                                                                                      
}
p = a;
    里面多了一个操作,再定义一个数组a,然后将数组array存放在ROM里面的内容复制到存放在RAM里面的a,再用p指向a的地址。虽然最终也可以正常获取数据,但是效率低下,这种操作是最不值得推荐的。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表