Arm CMSIS寄存器值

Arm CMSIS寄存器值,arm,embedded,cpu-registers,cmsis,Arm,Embedded,Cpu Registers,Cmsis,我刚刚开始探索ARM控制器的CMSIS。使用它似乎相当方便,但是我想知道实际的寄存器值是在哪里定义的。让我们以GPIO为例 有一个结构GPIOA_AHB_类型,由不同的成员定义。然后,对于GPIOB,定义了一个内存(或寄存器?)地址,比如GPIOB_AHB_BASE。之后,将指针设置为GPIOB_AHB_BASE,如下所示: #define GPIOB_AHB ((GPIOA_AHB_Type*) GPIOB_AHB_BASE) 例如,GPIOB_AHB的成员变量为GPIOB_A

我刚刚开始探索ARM控制器的CMSIS。使用它似乎相当方便,但是我想知道实际的寄存器值是在哪里定义的。让我们以GPIO为例

有一个结构GPIOA_AHB_类型,由不同的成员定义。然后,对于GPIOB,定义了一个内存(或寄存器?)地址,比如GPIOB_AHB_BASE。之后,将指针设置为GPIOB_AHB_BASE,如下所示:

#define GPIOB_AHB        ((GPIOA_AHB_Type*) GPIOB_AHB_BASE)

例如,GPIOB_AHB的成员变量为GPIOB_AHB->DIR,用于设置其输入或输出。我的问题是,这些成员变量在哪里初始化?我猜寄存器的实际地址是特定于设备的,所以我试图在特定于设备的头中找到它们,但我只找到了GPIOB_AHB_BASE define和成员变量的声明。编译器如何知道,当我键入GPIOB_AHB->DIR时,我想写入设置该端口I/O方向的寄存器?

如果查看CMSIS头,您将看到所有结构定义。以下是我当前项目的一个示例:

typedef struct
{
  __IO uint32_t DATA;              /*!< Port A Data Register                         */
  __IO uint32_t CR;                /*!< Port A Output Control Register               */
  __IO uint32_t FR1;               /*!< Port A Function Register 1                   */
  __IO uint32_t FR2;               /*!< Port A Function Register 2                   */
       uint32_t RESERVED0[6];
  __IO uint32_t OD;                /*!< Port A Open Drain Control Register           */
  __IO uint32_t PUP;               /*!< Port A Pull-up Control Register              */
       uint32_t RESERVED1[2];
  __IO uint32_t IE;                /*!< Port A Input Control Register                */
} TSB_PA_TypeDef;
这样您就可以像这样使用它:

TSB_PA->CR |= (1U << 2);          // make Port A, bit 2 an output
value = TSB_PA->DATA & (1U << 5); // read Port A, bit 5.

TSB|U PA->CR|=(1U数据和(1U谢谢!我看到指针TSB_PA指向位于TSB_PA_BASE位置的TSB_PA_TypeDef类型的结构。但是,在该结构中,编译器如何知道数据、CR等的单独位置?这是一个结构。它们都被适当的字段大小所抵消-这就是为什么其中有
保留的
字段-这些是内存映射中没有任何寄存器的漏洞。这很有意义:)在这种情况下,我想你声明成员变量的顺序也很重要,对吗?它们不是变量,而是结构中的字段。是的,顺序很重要。@Botond:与Carl的评论相反,结构的成员在C中通常被称为“成员”,而不是字段。术语“字段”在Pascal的上下文中使用“记录”或多或少类似于C的<代码>结构>代码>。在C++中,类和结构也可以有成员函数,数据成员通常被称为“成员变量”,所以我不认为你们离得太远,但是成员是关键的——它们不是独立的,不存在于结构的实例之外。
TSB_PA->CR |= (1U << 2);          // make Port A, bit 2 an output
value = TSB_PA->DATA & (1U << 5); // read Port A, bit 5.