我遇到了这个宏定义
#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
。但是,我试图将这种数据结构(如指针定义)包括在内。
答案 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