Kinetis单片机——结构体相关

来源:互联网 发布:义乌淘宝美工培训学校 编辑:程序博客网 时间:2024/05/17 02:26
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寄存器,这就是头文件中寄存器定义的方法。

原创粉丝点击