Kinetis单片机——结构体相关

本文介绍了Kinetis单片机中UART0的寄存器结构体及其宏定义,讲解了如何使用结构体声明、定义及通过指针访问结构体成员。特别强调了在单片机头文件中,使用`typedef`和`volatile`关键字定义寄存器结构的重要性,并解析了如何通过基址转换为结构体指针,以便于访问和操作寄存器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

typedef struct UART0_MemMap {
  uint8_t BDH;            /**< UART Baud Rate Register High, offset: 0x0 */
  uint8_t BDL;            /**< UART Baud Rate Register Low, offset: 0x1 */
  uint8_t C1;             /**< UART Control Register 1, offset: 0x2 */
  uint8_t C2;             /**< UART Control Register 2, offset: 0x3 */
  uint8_t S1;             /**< UART Status Register 1, offset: 0x4 */
  uint8_t S2;             /**< UART Status Register 2, offset: 0x5 */
  uint8_t C3;             /**< UART Control Register 3, offset: 0x6 */
  uint8_t D;              /**< UART Data Register, offset: 0x7 */
  uint8_t MA1;            /**< UART Match Address Registers 1, offset: 0x8 */
  uint8_t MA2;            /**< UART Match Address Registers 2, offset: 0x9 */
  uint8_t C4;             /**< UART Control Register 4, offset: 0xA */
  uint8_t C5;             /**< UART Control Register 5, offset: 0xB */
} volatile *UART0_MemMapPtr;

/* UART0 - Peripheral instance base addresses */
/** Peripheral UART0 base pointer */
#define UART0_BASE_PTR                 ((UART0_MemMapPtr)0x4006A000u)

#define UART0_C2                       UART0_C2_REG(UART0_BASE_PTR)

#define UART0_C2_REG(base)             ((base)->C2)

以上代码段是KL05中UART0的寄存器结构体,以及一些用到的宏定义,这种定义方式在官方给的MKL05Z4.h文件中很常用,我在这里举出一个例子进行说明。

首先说明一下结构体:
结构体在定义之前,首先要建立结构声明,然后再定义结构变量,如下程序:

struct book{
    char titile[40];
    char author[20];
    float value;
};

struct book library, * ptbook;

首先建立了一个结构布局,标记名为book,然后定义了一个使用struct book结构布局的结构变量library,并且定义了一个 指向struct book结构类型的指针 ptbook。
&为地址运算符:后跟一个变量名时,&给出该变量的地址。
* 为地址运算符:后跟一个指针名或地址时,* 给出储存在指针指向地址上的值。

ptbook = &library;

和数组不同,结构名并不是结构体的地址,因此要在结构名前面加上&运算符。
当我想用指针访问结构体成员时,可以有两种方法:

第一种:使用->运算符。
->运算符叫做“指向结构体成员运算符”,一个指针当用来指向一个结构体时,称之为结构体指针。结构体指针中的值是所指向的结构体的首地址。通过结构体指针即可访问该结构体。
即如果ptbook == &library,那么ptbook->value即是library.value

第二种:采用如下方式进行替代

library.value == (*ptbook).value

本文开头所提到的结构体定义是利用typedef将UART0_MemMapPtr定义成一个指向UART0_MemMap结构类型的数据指针,在这里需要注意的是:UART0_MemMapPtr并不是一个变量,而是一个数据类型,类似于char,int的那种,所以之后可以利用UART0_MemMapPtr进行强制数据类型转换。

volatile * UART0_MemMapPtr;表示声明一个指向volatile型变量的指针,即该结构体中的寄存器都定义为volatile型的,这种用法常用于单片机头文件中定义寄存器使用。
我们可以看到头文件中一般还有如下定义:

/* UART0 - Peripheral instance base addresses */
/* Peripheral UART0 base pointer */
#define UART0_BASE_PTR                 ((UART0_MemMapPtr)0x4006A000u)

#define UART0_C2                       UART0_C2_REG(UART0_BASE_PTR)

#define UART0_C2_REG(base)             ((base)->C2)

((UART0_MemMapPtr)0x4006A000u)这句将0x4006A000这个数值强制装换为一个UART0_MemMap的一个指针。本质:从0x4006A000地址开始,为一个UART0_MemMap结构体!
0x4006A000u应该是系统UART0用的固定的基址,所以将其首先强转为指针,然后再定义成可读性强的base_pointer 宏。
而UART0_C2则表示:(UART0_BASE_PTR)->C2,即结构体中的C2寄存器,这就是头文件中寄存器定义的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值