C 外围定义
有人能给初学者解释一下以下结构吗C 外围定义,c,C,有人能给初学者解释一下以下结构吗 typedef struct { __IO uint32_t CTRL; /**< Control Register */ __IO uint32_t CNT; /**< Counter Value Register */ __IO uint32_t COMP0; /**< Compare Value Register 0 */ __IO uint3
typedef struct
{
__IO uint32_t CTRL; /**< Control Register */
__IO uint32_t CNT; /**< Counter Value Register */
__IO uint32_t COMP0; /**< Compare Value Register 0 */
__IO uint32_t COMP1; /**< Compare Value Register 1 */
__I uint32_t IF; /**< Interrupt Flag Register */
__IO uint32_t IFS; /**< Interrupt Flag Set Register */
__IO uint32_t IFC; /**< Interrupt Flag Clear Register */
__IO uint32_t IEN; /**< Interrupt Enable Register */
__IO uint32_t FREEZE; /**< Freeze Register */
__I uint32_t SYNCBUSY; /**< Synchronization Busy Register */
} RTC_TypeDef;
#define RTC_BASE (0x40080000UL)
#define RTC ((RTC_TypeDef *) RTC_BASE)
typedef结构
{
__IO uint32\u t CTRL;/**<控制寄存器*/
__IO uint32\u t CNT;/**<计数器值寄存器*/
__IO uint32_t COMP0;/**<比较值寄存器0*/
__IO uint32_t COMP1;/**<比较值寄存器1*/
__I uint32\u t IF;/**<中断标志寄存器*/
__IO uint32_t IFS;/**<中断标志设置寄存器*/
__IO uint32\u t IFC;/**<中断标志清除寄存器*/
__IO uint32\u t IEN;/**<中断启用寄存器*/
__IO uint32\u t冻结;/**<冻结寄存器*/
__I uint32\u t SYNCBUSY;/**<同步忙寄存器*/
}RTC_TypeDef;
#定义RTC_基(0x400800000UL)
#定义RTC((RTC_TypeDef*)RTC_BASE)
尤其是最后一行
为什么括号如此不寻常?这个*是什么意思?指针还是乘法运算符
谢谢
为什么括号如此不寻常?这个*是什么意思?指针或
乘法运算符
*
这里是一个指针,不是乘法运算符
宏在这里没有什么不寻常的地方。它只是将地址类型转换为
struct RTC_TypeDef
结构定义非常简单,变量封装在结构中。然后可以将该结构引用为RTC_TypeDef
,因为您使用TypeDef
typedef struct
{
__IO uint32_t CTRL; /**< Control Register */
__IO uint32_t CNT; /**< Counter Value Register */
__IO uint32_t COMP0; /**< Compare Value Register 0 */
__IO uint32_t COMP1; /**< Compare Value Register 1 */
__I uint32_t IF; /**< Interrupt Flag Register */
__IO uint32_t IFS; /**< Interrupt Flag Set Register */
__IO uint32_t IFC; /**< Interrupt Flag Clear Register */
__IO uint32_t IEN; /**< Interrupt Enable Register */
__IO uint32_t FREEZE; /**< Freeze Register */
__I uint32_t SYNCBUSY; /**< Synchronization Busy Register */
} RTC_TypeDef; /** @} */
最后,以下行可以分为两部分:
(RTB_TypeDef *)RTC_BASE
这意味着(RTB_TypeDef*)(0x400800000ul)
-基本上告诉编译器将内存地址0x400800000ul
视为指向RTB_TypeDef
额外的括号表示单个变量作为计算表达式RTC。
从那时起,每当编译器看到
RTC
,它就会用(RTB_TypeDef*)(0x400800000ul)
替换它,这基本上是一种在内存中标记此结构开头的方便方法每当您在数据类型(甚至是用户定义的数据类型)之后遇到一个或多个*
,它就是一个指针
你所说的建筑:
typedef struct
{
__IO uint32_t CTRL; /**< Control Register */
__IO uint32_t CNT; /**< Counter Value Register */
__IO uint32_t COMP0; /**< Compare Value Register 0 */
__IO uint32_t COMP1; /**< Compare Value Register 1 */
__I uint32_t IF; /**< Interrupt Flag Register */
__IO uint32_t IFS; /**< Interrupt Flag Set Register */
__IO uint32_t IFC; /**< Interrupt Flag Clear Register */
__IO uint32_t IEN; /**< Interrupt Enable Register */
__IO uint32_t FREEZE; /**< Freeze Register */
__I uint32_t SYNCBUSY; /**< Synchronization Busy Register */
} RTC_TypeDef;
也是一个宏定义的。它只是一个RTC_Typedef
类型的指针,指向地址(0x400800000UL)
因此,在编译之前,预处理器将用((RTC_TypeDef*)0x400800000UL)
替换RTC
的所有实例。
如果您增加
RTC
指针,它将增加sizeof(RTC_Typedef)
指针。这里都是关于指针的。:-)那个结构有问题。由于这显然是一个寄存器映射(对于RTC),因此需要将其固定到((volatile RTC_TypeDef*)RTC_BASE)
,否则使用它的所有代码都可能包含随机错误。此外,在这里使用指针算法也是相当混乱的,因为没有理由这样做。最好使用(*(volatile RTC_TypeDef*)RTC_BASE)
,这样使用该结构的代码就不会那么混乱了。什么“指针算法”@Lundin?RTC被定义为指向struct的指针,因此可以在RTC->CTRL=1这样的代码中取消对它的引用;RTC->IFS=2代码>等对我来说是有意义的。@GrahamS我的评论并不是很清楚,但我想通过不把RTC当作指针来防止像RTC[3]=…
这样丑陋的事情。是的,有人在编写硬件外围驱动程序时使用“神奇数字”编写这样的代码。(我目前正在维护这样一个程序。)无论如何,这里最重要的事情是易变的:没有它,代码可能会崩溃和烧坏。。。。下一行表示每次编写RTC_BASE时,编译器都会将该行替换为(0x400800000UL)。错误,不是整行,只是RTC\u BASE
。
typedef struct
{
__IO uint32_t CTRL; /**< Control Register */
__IO uint32_t CNT; /**< Counter Value Register */
__IO uint32_t COMP0; /**< Compare Value Register 0 */
__IO uint32_t COMP1; /**< Compare Value Register 1 */
__I uint32_t IF; /**< Interrupt Flag Register */
__IO uint32_t IFS; /**< Interrupt Flag Set Register */
__IO uint32_t IFC; /**< Interrupt Flag Clear Register */
__IO uint32_t IEN; /**< Interrupt Enable Register */
__IO uint32_t FREEZE; /**< Freeze Register */
__I uint32_t SYNCBUSY; /**< Synchronization Busy Register */
} RTC_TypeDef;
#define RTC ((RTC_TypeDef *) RTC_BASE)