文章目录
- 8.1 什么是固件库
- 8.2 什么时候使用
- 8.3 封装注意点
- 8.3.1 fsl
- 8.4 GPIO库函数定义
- 8.4.1 初始化结构体 gpio_pin_config_t
- 8.4.2 定义引脚模式的枚举类型
8.1 什么是固件库
固件库是指“RT1052 函数库”,是由 NXP 公司针对 RT1052 提供的函数接口,即
API (Application Program Interface)。
- 开发者可调用这些函数接口来配置 RT1052 的寄存器,使开发人员得以脱离最底层的寄存器操作
8.2 什么时候使用
绝大部分时候,我们愿意牺牲一点 CPU 资源,选择库开发
一般只有在对代码运行时间要求极苛刻的地方,才用直接配置寄存器的方式代替,如频繁调用的中断服务函数。
8.3 封装注意点
6 /* volatile 表示易变的变量,防止编译器优化, */
7 #define __IO volatile /* 可读写,一般用于定义有可读写权限的寄存器 */
8 #define __I volatile const /* 只读,一般用于定义只读权限的寄存器 *//* 使用更简短直观的方式来定义无符号 32 、 16 、 8 位变量 */
11 typedef unsigned int uint32_t;
12 typedef unsigned short uint16_t;
13 typedef unsigned char uint8_t;15 /* GPIO 寄存器结构体 */
16 typedef struct {
17 __IO uint32_t DR; /* DR 数据寄存器, 地址偏移 : 0x0 */
18 __IO uint32_t GDIR; /* GDIR 方向寄存器, 地址偏移 : 0x4 */
19 __I uint32_t PSR; /* PSR 状态寄存器, 地址偏移 : 0x8 */
20 __IO uint32_t ICR1; /* ICR1 中断配置寄存器 1, 地址偏移 : 0xC */
21 __IO uint32_t ICR2; /* ICR2 中断配置寄存器 2, 地址偏移 : 0x10 */
22 __IO uint32_t IMR; /* IMR 中断掩码寄存器 , 地址偏移 : 0x14 */
23 __IO uint32_t ISR; /* ISR 中断状态寄存器 , 地址偏移 : 0x18 */
24 __IO uint32_t EDGE_SEL; /* EDGE_SEL 边沿选择寄存器, 地址偏移 : 0x1C */
25 } GPIO_Type;
“__IO”代表了 C 语言中的关键字“volatile”,在 C 语言中该关键字用于修饰易变的变量,要求编译器不要优化
“__I”则代表“volatile const”在“__IO”的基础上增加不可修改的属性
寄存器很多时候是由外设或 RT1052 芯片状态修改的,也就是说即使 CPU 不执行代码修改这些变量,变量的值也有可能被外设修改、更新。
- 所以每次使用这些变量的时候,我们都要求 CPU 去该变量的地址重新访问。
- 若没有这个关键字修饰,在某些情况下,编译器认为没有代码修改该变量,就直接从 CPU 的某个缓存获取该变量值,这时可以加快执行速度,但该缓存中的是陈旧数据,与我们要求的寄存器最新状态可能会有出入。
8.3.1 fsl
文件名中的 fsl 大概是飞思卡尔半导体(freescale)的缩写,nxp 公司收购了 freescale,在固件库中它们使用 fsl 这个名字
8.4 GPIO库函数定义
8.4.1 初始化结构体 gpio_pin_config_t
1 /* GPIO 引脚配置结构体定义 */
2 typedef struct _gpio_pin_config {
3
4 /* 指定引脚的方向 */
5 uint8_t direction;
6
7 /* 设置一个默认的输出电平,在输入方向时本设置无效 */
8 uint8_t outputLogic;
9
10 /* 设置引脚的中断模式 */
11 uint8_t interruptMode;
12
13 } gpio_pin_config_t;
结构体中包含了初始化 GPIO 所需要的信息,包括引脚输入输出方向、默认输出电平以及中断模式。
然后把这个结构体作为“GPIO 初始化函数”的输入参数,该函数能根据这个变量值中的内容去配置寄存器,从而实现 GPIO 的初始化。
8.4.2 定义引脚模式的枚举类型
1 /* GPIO 方向枚举定义 */
2 typedef enum _gpio_pin_direction {
3 kGPIO_DigitalInput = 0U, /* 设置引脚为输入方向 */
4 kGPIO_DigitalOutput = 1U, /* 设置引脚为输出方向 */
5 } gpio_pin_direction_t;
6
7 /* GPIO 中断模式枚举定义 */
8 typedef enum _gpio_interrupt_mode {
9 kGPIO_NoIntmode = 0U, /* 设置引脚为通用 IO 功能(不使用中断) */
10 kGPIO_IntLowLevel = 1U, /* 设置引脚低电平引起中断 */
11 kGPIO_IntHighLevel = 2U, /* 设置引脚高电平引起中断 */
12 kGPIO_IntRisingEdge = 3U, /* 设置引脚上升沿引起中断 */
13 kGPIO_IntFallingEdge = 4U, /* 设置引脚下降沿引起中断 */
14 kGPIO_IntRisingOrFallingEdge = 5U, /* 设置引脚上升沿和下降沿都引脚中断 */
15 } gpio_interrupt_mode_t
“U”表示该数字是无符号类型,在这里其实不写也可以,是一种编程习惯。