在"FreeRTOS 从入门到精通"这个专题系列完结后,我觉得是时候应该再介绍和推广一些大神写的优秀的第三方库。通过调用这些第三方库的函数可以避免重复造轮子,同时缩短项目开发时间和提高程序的健壮性。研究和学习这些第三方库的代码也可以提高我们的代码能力。
作为本专题的开篇,我将介绍Tilen Majerle大神写的基于STM32的HAL第三方库之通用输入输出口GPIO库。本GPIO库的源文件在下面这个下载链接中。
tm_stm32_gpio.zip089u.com(本人使用的开发板是STM32F429IDISCOVERY,使用的IDE是STM32CubeIDE,程序编译顺利并运行正常)
为什么要使用TM的GPIO库
- 使用官方的HAL库对通用输入输出口引脚(GPIO Pins)初始化时,首先要开启对应GPIO口的时钟,然后对此引脚进行配置。TM的GPIO库在初始化GPIO时会自动使能对应GPIO口的时钟,用一个函数就可以对引脚进行配置和初始化
- 方便的读取GPIO口的值,快速设置上拉电阻
- 提供更多的功能
如何配置TM的GPIO库
TM的GPIO库依赖于HAL的GPIO库。首先把头文件和代码文件根据项目需求放到对应位置。
然后在tm_stm32_gpio.h头文件中,根据stm32芯片的型号引用相对应的stm32fxxx_hal.h
在主程序的头文件main.h中引用tm_stm32_gpio.h头文件并编译程序,如果编译没有报错则配置成功。
TM的GPIO库的枚举类型
本库的一些枚举类型参数,在调用库函数时会用到
//引脚的功能的枚举
typedef enum {
TM_GPIO_Mode_IN = 0x00, /*!< 引脚功能为通用输入口 */
TM_GPIO_Mode_OUT = 0x01, /*!< 引脚功能为通用输出口 */
TM_GPIO_Mode_AF = 0x02, /*!< 引脚功能为复用功能 */
TM_GPIO_Mode_AN = 0x03, /*!< 引脚功能为模拟输入输出口 */
} TM_GPIO_Mode_t;
//引脚的输出类型的枚举
typedef enum {
TM_GPIO_OType_PP = 0x00, /*!< 引脚输出类型为推挽输出 */
TM_GPIO_OType_OD = 0x01 /*!< 引脚输出类型为开漏输出 */
} TM_GPIO_OType_t;
//引脚的速率的枚举
typedef enum {
TM_GPIO_Speed_Low = 0x00, /*!< 引脚速率为低速模式 */
TM_GPIO_Speed_Medium = 0x01, /*!< 引脚速率为中速模式 */
TM_GPIO_Speed_Fast = 0x02, /*!< 引脚速率为快速模式,F0系列没有此选项*/
TM_GPIO_Speed_High = 0x03 /*!< 引脚速率为高速模式 */
} TM_GPIO_Speed_t;
//引脚的电阻设置的枚举
typedef enum {
TM_GPIO_PuPd_NOPULL = 0x00, /*!< 引脚无电阻设置 */
TM_GPIO_PuPd_UP = 0x01, /*!< 引脚使能上拉电阻 */
TM_GPIO_PuPd_DOWN = 0x02 /*!< 引脚使能下拉电阻 */
} TM_GPIO_PuPd_t;
TM的GPIO库的函数和宏
简要介绍一下GPIO库的库函数和宏,在tm_stm32_gpio.h头文件有详细的功能介绍
//函数功能:初始化GPIO引脚的功能,此函数会自动使能该GPIO口的时钟
void TM_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,
TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd,
TM_GPIO_Speed_t GPIO_Speed);
//函数功能:初始化GPIO引脚的复用功能,此函数会自动使能该GPIO口的时钟
void TM_GPIO_InitAlternate(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,
TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed,
uint8_t Alternate);
//函数功能:取消GPIO引脚的功能,该引脚会被设为模拟模式以降低功耗
void TM_GPIO_DeInit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//函数功能:把GPIO引脚设为输入模式,使用此函数需该引脚先调用TM_GPIO_Init函数或
// TM_GPIO_InitAlternate()函数被初始化
void TM_GPIO_SetPinAsInput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//函数功能:把GPIO引脚设为输出模式,使用此函数需该引脚先调用TM_GPIO_Init函数或
// TM_GPIO_InitAlternate()函数被初始化
void TM_GPIO_SetPinAsOutput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//函数功能:把GPIO引脚设为模拟模式,使用此函数需该引脚先调用TM_GPIO_Init函数或
// TM_GPIO_InitAlternate()函数被初始化
void TM_GPIO_SetPinAsAnalog(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//函数功能:把GPIO引脚设为复用功能模式,使用此函数需该引脚先调用TM_GPIO_Init函数或
// TM_GPIO_InitAlternate()函数被初始化
void TM_GPIO_SetPinAsAlternate(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//函数功能:配置GPIO引脚的电阻,使用此函数需该引脚先调用TM_GPIO_Init函数或
// TM_GPIO_InitAlternate()函数被初始化
void TM_GPIO_SetPullResistor(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,
TM_GPIO_PuPd_t GPIO_PuPd);
//宏的功能:GPIO引脚设为低电平
#define TM_GPIO_SetPinLow(GPIOx, GPIO_Pin)
//宏的功能:GPIO引脚设为高电平
#define TM_GPIO_SetPinHigh(GPIOx, GPIO_Pin)
//宏的功能:设置GPIO引脚电平,val为0时设置为低电平,val为其余值时为高电平
#define TM_GPIO_SetPinValue(GPIOx, GPIO_Pin, val)
//宏的功能:切换GPIO引脚电平
#define TM_GPIO_TogglePinValue(GPIOx, GPIO_Pin)
//宏的功能:设置GPIO口的引脚的电平
#define TM_GPIO_SetPortValue(GPIOx, value)
//宏的功能:获取GPIO输入引脚的电平
#define TM_GPIO_GetInputPinValue(GPIOx, GPIO_Pin)
//宏的功能:获取GPIO输出引脚的电平
#define TM_GPIO_GetOutputPinValue(GPIOx, GPIO_Pin)
//宏的功能:获取GPIO输入数据寄存器的电平
#define TM_GPIO_GetPortInputValue(GPIOx)
//宏的功能:获取GPIO输出数据寄存器的电平
#define TM_GPIO_GetPortOutputValue(GPIOx)
示例程序
开发板STM32F429IDISCOVERY的Pin13和Pin14分别连接了个Led灯
//初始化变量pinStatus
uint8_t pinStatus=0;
//配置GPIOG的Pin13为推挽输出模式,开启上拉电阻,引脚速率为高速
TM_GPIO_Init(GPIOG,GPIO_Pin_13,TM_GPIO_Mode_OUT,TM_GPIO_OType_PP,
TM_GPIO_PuPd_UP,TM_GPIO_Speed_High);
//配置GPIOG的Pin14为推挽输出模式,开启上拉电阻,引脚速率为高速
TM_GPIO_Init(GPIOG,GPIO_Pin_14,TM_GPIO_Mode_OUT,TM_GPIO_OType_PP,
TM_GPIO_PuPd_UP,TM_GPIO_Speed_High);
for(;;)
{
//切换GPIOG的Pin13的电平
TM_GPIO_TogglePinValue(GPIOG,GPIO_Pin_13);
//pinStatus变量储存GPIOG的Pin13的电平状态
pinStatus = TM_GPIO_GetOutputPinValue(GPIOG, GPIO_Pin_13);
//GPIOG的Pin14的电平设为pinStatus
TM_GPIO_SetPinValue(GPIOG, GPIO_Pin_14, pinStatus);
osDelay(1000);//延时1秒
}
运行效果为两个Led灯每隔1秒同时闪烁