c - 访问微 Controller 上寄存器的结构指针?

标签 c arm cortex-m cmsis

我正在尝试理解 STM-32 Cortex-M4 微 Controller 附带的 cmsis 头文件。 他们有一个结构是

typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  __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 uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
  __IO uint16_t BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
  __IO uint16_t BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef;

例如,这样写是否有意义:

((GPIO_TypeDef *) 0x08000) -> MODER = 0x12;

我不明白这条线在做什么。 如果你这样做对我来说会更有意义

GPIO_TypeDef * td = 0x08000;
td -> MODER = 0x12;

这些是一样的吗?为什么?

最佳答案

GPIO_TypeDef struct 是一种巧妙的地址偏移编码机制。因此,如果我们获得一个指向 GPIOD 基地址的指针,我们将该指针转换为 GPIO_TypeDef struct 指针,我们可以使用标准 C 解引用运算符 (->) 来访问距 GPIOD 基地址一定偏移量的地址。

所以在你的例子中,GPIOD_BASE计算结果为 (AHB1PERIPH_BASE + 0x0C00)MODERGPIO_TypeDef 的地址偏移量为 0x0结构体指针。这意味着GPIOD_BASE->MODER计算结果为 (AHB1PERIPH_BASE + 0x0C00) + 0x00 。这只是 GPIOD 的端口模式寄存器的地址。

这适用于 GPIO_TypeDef 中定义的所有字段结构。例如,GPIOD_BASE->PUPDR计算结果为 (AHB1PERIPH_BASE + 0x0C00) + 0x0C 。这只是 GPIOD 上拉/下拉寄存器的地址。

关于c - 访问微 Controller 上寄存器的结构指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40121633/

相关文章:

c - 将数组传递给函数——出了什么问题?

c - C 程序中的错误小于预期

macos - 如何在 OS X 上轻松安装 arm-elf-gcc?

assembly - ARM编程中有翻译表XLAT指令吗?

c - 为什么在结构中不可能有静态成员?

c - Valgrind for C 程序报告令人难以置信的无效写入

linux - 读取NAND闪存并将其写入另一个系统

c++ - 从堆栈转储和 .elf 文件中提取 FreeRTOS/ARM/C++ 堆栈跟踪的工具?

linux - i.MX6SX 从 DDR 运行 M4 固件

c - 在 arm cortex m4 nrf52 的本地闪存中重写变量的初始化值