我如何理解此宏定义

时间:2020-03-27 11:04:52

标签: c

我遇到了这个宏定义

#define CAN1      ((CAN_TypeDef *) CAN1_BASE)

我想了解背后的概念。 CAN_TypeDef是一种数据结构,其定义如下

typedef struct
{
  __IO uint32_t              MCR;                 /*!< CAN master control register,         Address offset: 0x00          */
  __IO uint32_t              MSR;                 /*!< CAN master status register,          Address offset: 0x04          */
  __IO uint32_t              TSR;                 /*!< CAN transmit status register,        Address offset: 0x08          */
  __IO uint32_t              RF0R;                /*!< CAN receive FIFO 0 register,         Address offset: 0x0C          */
  __IO uint32_t              RF1R;                /*!< CAN receive FIFO 1 register,         Address offset: 0x10          */
  __IO uint32_t              IER;                 /*!< CAN interrupt enable register,       Address offset: 0x14          */
  __IO uint32_t              ESR;                 /*!< CAN error status register,           Address offset: 0x18          */
  __IO uint32_t              BTR;                 /*!< CAN bit timing register,             Address offset: 0x1C          */
  uint32_t                   RESERVED0[88];       /*!< Reserved, 0x020 - 0x17F                                            */
  CAN_TxMailBox_TypeDef      sTxMailBox[3];       /*!< CAN Tx MailBox,                      Address offset: 0x180 - 0x1AC */
  CAN_FIFOMailBox_TypeDef    sFIFOMailBox[2];     /*!< CAN FIFO MailBox,                    Address offset: 0x1B0 - 0x1CC */
  uint32_t                   RESERVED1[12];       /*!< Reserved, 0x1D0 - 0x1FF                                            */
  __IO uint32_t              FMR;                 /*!< CAN filter master register,          Address offset: 0x200         */
  __IO uint32_t              FM1R;                /*!< CAN filter mode register,            Address offset: 0x204         */
  uint32_t                   RESERVED2;           /*!< Reserved, 0x208                                                    */
  __IO uint32_t              FS1R;                /*!< CAN filter scale register,           Address offset: 0x20C         */
  uint32_t                   RESERVED3;           /*!< Reserved, 0x210                                                    */
  __IO uint32_t              FFA1R;               /*!< CAN filter FIFO assignment register, Address offset: 0x214         */
  uint32_t                   RESERVED4;           /*!< Reserved, 0x218                                                    */
  __IO uint32_t              FA1R;                /*!< CAN filter activation register,      Address offset: 0x21C         */
  uint32_t                   RESERVED5[8];        /*!< Reserved, 0x220-0x23F                                              */ 
  CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register,                 Address offset: 0x240-0x31C   */
} CAN_TypeDef;

CAN1_BASE的定义如下。

/*!< Peripheral memory map */
#define APB1PERIPH_BASE        0x40000000UL
#define CAN1_BASE             (APB1PERIPH_BASE + 0x6400UL)

问题:宏定义CAN1是将起始地址分配给数据结构CAN_TypeDef还是其他含义。我知道宏将(0x40000000UL+ 0x6400UL的十六进制值赋予CAN1。但是,我试图将这种数据结构(如指针定义)包括在内。

1 个答案:

答案 0 :(得分:2)

这很简单。

让它变得更简单。

#define PERIPHADDR  0x12345678

typedef struct
{
    volatile uint32_t REG1;
    volatile uint32_t REG2;
    volatile uint32_t REG3;
    volatile uint32_t REG4;
    volatile uint32_t REG5;
}PERIPH_t;

#define PERIPH  ((PERIPH_t *)(PERIPHADDR))


void foo()
{
    PERIPH -> REG1 = 0x45678;
}

并扩展为

void foo()
{
    ((PERIPH_t *)(0x12345678)) -> REG3 = 0x45678;
}

宏定义CAN1是否为数据分配起始地址 结构CAN_TypeDef还是其他意思

否,它不分配任何地址。它只是计算它必须存储值的位置。没有任何中间指针。

您可能会问为什么不定义“普通”指针。答案很简单。它将浪费内存并生成效率较低的代码:

示例:

#define PERIPH  ((PERIPH_t *)(PERIPHADDR))

PERIPH_t *PERIPH1 = (PERIPH_t *)PERIPHADDR;


void foo()
{
    PERIPH -> REG3 = 0x45678;
}

void bar()
{
    PERIPH1 -> REG3 = 0x45678;
}

及其结果代码:

foo:
        ldr     r3, .L3
        ldr     r2, .L3+4
        str     r2, [r3, #128]
        bx      lr
.L3:
        .word   305419776
        .word   284280
bar:
        ldr     r3, .L6
        ldr     r2, .L6+4
        ldr     r3, [r3]
        str     r2, [r3, #8]
        bx      lr
相关问题