论坛元老
 
- 积分
- 8017
- 金钱
- 8017
- 注册时间
- 2014-8-13
- 在线时间
- 1594 小时
|
发表于 2018-4-4 00:53:44
|
显示全部楼层
本帖最后由 mack13013 于 2018-4-4 08:16 编辑
GPIOA_BASE实际上就是一串数字,该数字被当作地址的时候,地址总线会按照该数字映射。
比如假定GPIOA_BASE是0xD6(二进制的11010110),那么地址总线的A0到A7就会表现为(高高低高低高高低),此时再有WR之类的信号,那么对应地址的数据就会被搬运到数据总线上(参考一下SRAM芯片的管脚功能)。
再说结构体强制转换的问题。基本上大多地址都是连续的,拿上面的GPIOA_BASE来说,其地址为0xD6,后面还有很多内存空间0xD7、0xD8、0xD9....我们描述0xD7、0xD8、0xD9的时候是按照一个字节一个字节的描述,
但是我并不想这样使用,因为不方便,我本意是这样的,在0xD7开始的2个字节内放一个short类型的数字(可能是ADC转换后的数值之类),然后再放一个byte类型的数字(可能用来标记数据的来源,比如ADC通道1),
之后再放一个byte类型的数字(可能用来标记什么东西),最后放一个int类型的数字(可能是某种需要存储的数据),这样,0xD6 0xD7放了一个short类型数据,0xD8、0xD9分别放了一个byte类型数据,从0xDA开始的
0xDA、0xDB、0xDC、0xDD这4个字节合起来我存储一个int类型的数据。那我怎么访问这个怪了巴基的东西呢?总不能一个字节一个字节的读出,然后前面两个字节凑成short,最后4个字节凑成int吧?我们可以直接告
诉编译器,我要按照2、1、1、4的方式读取数据,那么我们就可以定义一个下面这样的结构体
[mw_shl_code=c,true]
typedef struct _ACTION_DESCRIPTOR
{
short wActType;
char cSrcValue;
char cSrcType;
int nDstValue;
} ACTION_DESCRIPTOR, *PACTION_DESCRIPTOR;[/mw_shl_code]
同时告诉编译器,我要从0xD6开始读取8个字节,并且按照2、1、1、4也就是ACTION_DESCRIPTOR这种结构体的"格式"来读取或者写入数据。语法上的写法就是 (ACTION_DESCRIPTOR*)0xD6,也就是强行将0xD6转化为
ACTION_DESCRIPTOR类型的指针(地址)。
至于int a=3; int * p; p=&a;这个问题,
执行int a = 3;时,系统会分配一个地址比如0xAA,从0xAA开始的0xAA、0xAB、0xAC、0xAD四个字节存放3这个整形数字,
执行int *p;时,系统分配一个地址比如0xE0,从0xE0开始的0xE0、0xE1、0xE2、0xE3四个字节(假定32位寻址)"准备"存放p的内容。
执行p=&a;时,我们知道&a的结果是0xAA(在执行int a = 3;时,由系统分配的),那么这句执行之后的结果就是从0xE0开始的0xE0、0xE1、0xE2、0xE3四个字节存储了0xAA。
|
|