我正在对 Atmel 的 AT91SAM7X256 进行编程,我对定义寄存器的宏以及如何使用它们感到有些困惑。
我使用如下行在寄存器中设置一个位:
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PWMC;
现在,当我在宏扩展之后查看它时,它看起来像这样:
((AT91PS_PMC) 0xFFFFFC00)->PMC_PCER = 1 << (10);
我可以在文件 AT91SAM7X256.h 中找到的定义
在文件的顶部:
#ifndef __ASSEMBLY__
typedef volatile unsigned int AT91_REG;// Hardware register definition
#define AT91_CAST(a) (a)
#else
#define AT91_CAST(a)
#endif
然后我在下面找到 AT91C_BASE_PMC 的定义
...
#define AT91C_BASE_CKGR (AT91_CAST(AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address
#define AT91C_BASE_PMC (AT91_CAST(AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address
#define AT91C_BASE_RSTC (AT91_CAST(AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address
...
所以看起来这变得非常简单。类似地,宏 AT91C_ID_PWMC 定义为
...
#define AT91C_ID_TWI ( 9) // Two-Wire Interface
#define AT91C_ID_PWMC (10) // PWM Controller
#define AT91C_ID_UDP (11) // USB Device Port
...
但是解引用 ((AT91PS_PMC) 0xFFFFFC00)->PMC_PCER 是如何工作的?我可以找到 PMC_PCER 的一些定义。
#ifndef __ASSEMBLY__
typedef struct _AT91S_SYS {
...
AT91_REG Reserved20[1]; //
AT91_REG PMC_PCER; // Peripheral Clock Enable Register
AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
...
} AT91S_SYS, *AT91PS_SYS;
#else
#endif
并再次下降。
#ifndef __ASSEMBLY__
typedef struct _AT91S_PMC {
...
AT91_REG Reserved0[1]; //
AT91_REG PMC_PCER; // Peripheral Clock Enable Register
AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
...
} AT91S_PMC, *AT91PS_PMC;
#else
...
#define PMC_SCSR (AT91_CAST(AT91_REG *) 0x00000008) // (PMC_SCSR) System Clock Status Register
#define PMC_PCER (AT91_CAST(AT91_REG *) 0x00000010) // (PMC_PCER) Peripheral Clock Enable Register
#define PMC_PCDR (AT91_CAST(AT91_REG *) 0x00000014) // (PMC_PCDR) Peripheral Clock Disable Register
...
#endif
所以我的问题是
- 这些宏是如何工作的?
- 我的印象是,我可以使用表达式 AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PWMC; 设置一个位;? 这是真的?
- 我将如何取消该位?
- 为什么它做得这么复杂,而不是简单地直接设置值?