鱼C论坛

 找回密码
 立即注册
查看: 8723|回复: 12

把地址强制转换成结构体指针的问题

[复制链接]
发表于 2017-10-20 13:53:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

#define GPIOA_BASE            (AHB2PERIPH_BASE + 0x00000000)  //地址
#define GPIOA                      ((GPIO_TypeDef *) GPIOA_BASE)
typedef struct
{
  __IO uint32_t MODER;        /*!< GPIO port mode register,                                  Address offset: 0x00 */
  __IO uint16_t OTYPER;       /*!< GPIO port output type register,                           Address offset: 0x04 */
  uint16_t RESERVED0;         /*!< Reserved,                                                                 0x06 */
  __IO uint32_t OSPEEDR;      /*!< GPIO port output speed register,                          Address offset: 0x08 */
  __IO uint32_t PUPDR;        /*!< GPIO port pull-up/pull-down register,                     Address offset: 0x0C */
  __IO uint16_t IDR;          /*!< GPIO port input data register,                            Address offset: 0x10 */
  uint16_t RESERVED1;         /*!< Reserved,                                                                 0x12 */
  __IO uint16_t ODR;          /*!< GPIO port output data register,                           Address offset: 0x14 */
  uint16_t RESERVED2;         /*!< Reserved,                                                                 0x16 */
  __IO uint32_t BSRR;         /*!< GPIO port bit set/reset registerBSRR,                     Address offset: 0x18 */
  __IO uint32_t LCKR;         /*!< GPIO port configuration lock register,                    Address offset: 0x1C */
  __IO uint32_t AFR[2];       /*!< GPIO alternate function low register,                Address offset: 0x20-0x24 */
  __IO uint16_t BRR;          /*!< GPIO bit reset register,                                  Address offset: 0x28 */
  uint16_t RESERVED3;         /*!< Reserved,                                                                 0x2A */
}GPIO_TypeDef;
请问 ((GPIO_TypeDef *) GPIOA_BASE)怎么理解,一般不是先定义一个结构体变量 再定义一个结构体指针变量来指向结构体变量的嘛?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-10-20 14:01:50 | 显示全部楼层
typedef struct
{
……
}GPIO_TypeDef;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-10-20 14:27:39 | 显示全部楼层
((GPIO_TypeDef *) GPIOA_BASE)的理解
GPIOA_BASE比如为0x0018F000,这个指针由程序创建的,是否为GPIO_TypeDef 结构体指针,这个不一定。
(GPIO_TypeDef *) GPIOA_BASE,这个指针被强制转化后,其地址并不会改变,还是为0x0018F000,但是在编写程序时,((GPIO_TypeDef *) GPIOA_BASE)->OTYPER 这样访问结构体编译器默认是可以的,其结果为0x0018F000+0x4 = 0x0018F004这个地址,那么这个地址是否意义,就取决于GPIOA_BASE的定义了。

评分

参与人数 1荣誉 +2 鱼币 +2 贡献 +3 收起 理由
Pioneer + 2 + 2 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-21 09:53:44 | 显示全部楼层
好的谢谢了哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-21 10:04:51 | 显示全部楼层
上善若水··· 发表于 2017-10-20 14:27
((GPIO_TypeDef *) GPIOA_BASE)的理解
GPIOA_BASE比如为0x0018F000,这个指针由程序创建的,是否为GPIO_Typ ...

(GPIO_TypeDef *) GPIOA_BASE
GPIO_TypeDef *不是用来定义结构体指针变量的嘛?
怎么把地址给强制转换有点没转过来。
有没有关于这方面的资料?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-10-21 10:20:38 | 显示全部楼层
能发生这种转换不出错的......
GPIOA_BASE 应该是 GPIO_TypeDef 基类
timg.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-21 11:41:28 | 显示全部楼层
GPIO_TypeDef *不是用来定义结构体指针变量的嘛?
再让这个这个结构体指针变量指向 GPIO_TypeDef类型的结构体变量的嘛?
GPIO_TypeDef *地址这个强制转换后发生了什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-10-21 22:38:24 | 显示全部楼层
Pioneer 发表于 2017-10-21 10:04
(GPIO_TypeDef *) GPIOA_BASE
GPIO_TypeDef *不是用来定义结构体指针变量的嘛?
怎么把地址给强制转换 ...

这个就是C/C++编译器的特性了,它可以允许结构体名或者类名直接强制转换指针,主要是为了实现子类与父类之间的直接访问吧!可以看看C++子类与父类指针转换那一章!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-25 21:26:41 | 显示全部楼层
好的!谢谢了哈!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-24 17:38:01 | 显示全部楼层
你好,我看了楼上的回答还是没全理解,为什么没有创建 结构体变量 就能访问 结构体变量的成员,难道说 ((GPIO_TypeDef *) GPIOA_BASE) 是 创建了一个首地址为 GPIOA_BASE 的结构体成员变量,通过 ((GPIO_TypeDef *) GPIOA_BASE)->MODER 来访问成员吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-24 19:10:48 | 显示全部楼层
请问AHB2PERIPH_BASE是GPIO_TypeDef在堆中的地址吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-6 20:33:10 | 显示全部楼层
这么久了,帖主估计早就搞明白了,今天我也遇到这个问题,自己想了好久算是理解了:
其实 ((GPIO_TypeDef *) GPIOA_BASE) 是强制把GPIOA_BASE(一个无符号32位整型数,假设是0x00000000)转换为指向 GPIO_TypeDef类型的指针。然后定义GPIO_TypeDef结构体类型。到此并没有创建任何实体,只是告知编译器0x00000000这个地址是指向了一个GPIO_TypeDef的结构体。
之后的代码会用到  GPIOA->MODER=1(任意一个满足条件的值); 这句话相当于往0x00000000地址写1,同理GPIOA-> OTYPER=1 是往0x00000004地址写1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-27 11:09:43 | 显示全部楼层
空蓝 发表于 2022-12-6 20:33
这么久了,帖主估计早就搞明白了,今天我也遇到这个问题,自己想了好久算是理解了:
其实 ((GPIO_TypeDef  ...

GPIO_TypeDef的结构体指向0x00000000这个地址   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-24 09:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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