Pioneer 发表于 2017-10-20 13:53:16

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


#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;       /*!< 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)怎么理解,一般不是先定义一个结构体变量 再定义一个结构体指针变量来指向结构体变量的嘛?

闪电猫网络 发表于 2017-10-20 14:01:50

typedef struct
{
……
}GPIO_TypeDef;

上善若水··· 发表于 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的定义了。

Pioneer 发表于 2017-10-21 09:53:44

好的谢谢了哈

Pioneer 发表于 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 *不是用来定义结构体指针变量的嘛?
怎么把地址给强制转换有点没转过来。
有没有关于这方面的资料?

橙C 发表于 2017-10-21 10:20:38

能发生这种转换不出错的......
GPIOA_BASE 应该是 GPIO_TypeDef 基类

Pioneer 发表于 2017-10-21 11:41:28

GPIO_TypeDef *不是用来定义结构体指针变量的嘛?
再让这个这个结构体指针变量指向 GPIO_TypeDef类型的结构体变量的嘛?
GPIO_TypeDef *地址这个强制转换后发生了什么?

上善若水··· 发表于 2017-10-21 22:38:24

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

这个就是C/C++编译器的特性了,它可以允许结构体名或者类名直接强制转换指针,主要是为了实现子类与父类之间的直接访问吧!可以看看C++子类与父类指针转换那一章!

Pioneer 发表于 2017-10-25 21:26:41

好的!谢谢了哈!

远空w 发表于 2020-4-24 17:38:01

你好,我看了楼上的回答还是没全理解,为什么没有创建 结构体变量 就能访问 结构体变量的成员,难道说 ((GPIO_TypeDef *) GPIOA_BASE) 是 创建了一个首地址为 GPIOA_BASE 的结构体成员变量,通过 ((GPIO_TypeDef *) GPIOA_BASE)->MODER 来访问成员吗?

Cool_Breeze 发表于 2020-4-24 19:10:48

请问AHB2PERIPH_BASE是GPIO_TypeDef在堆中的地址吗?

空蓝 发表于 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

Pioneer 发表于 2023-7-27 11:09:43

空蓝 发表于 2022-12-6 20:33
这么久了,帖主估计早就搞明白了,今天我也遇到这个问题,自己想了好久算是理解了:
其实 ((GPIO_TypeDef...

GPIO_TypeDef的结构体指向0x00000000这个地址   
页: [1]
查看完整版本: 把地址强制转换成结构体指针的问题