文章目录
- 一、使用HAL库配置GPIO思路
-
- [ 1、初始化配置:](# 1、初始化配置:)
- [ 2、输入输出操作:](# 2、输入输出操作:)
- [ 3、复用 / 中断:](# 3、复用 / 中断:)
- 二、HAL库GPIO相关函数
-
- [ 0、时钟使能](# 0、时钟使能)
- [ 1、初始化](# 1、初始化)
- [ 2、IO操作](# 2、IO操作)
- [ 3、宏定义](# 3、宏定义)
- [ 4、模式定义](# 4、模式定义)
- 三、示例代码
一、使用HAL库配置GPIO思路
1、初始化配置:
通过GPIO_InitTypeDef结构体定义引脚模式、速度、上下拉等参数,再调用HAL_GPIO_Init()完成初始化。
2、输入输出操作:
输出用HAL_GPIO_WritePin()/HAL_GPIO_TogglePin();输入用HAL_GPIO_ReadPin()。
3、复用 / 中断:
GPIO 作为外设复用(如串口、SPI)或外部中断时,需额外配置复用映射 / 中断优先级。
二、HAL库GPIO相关函数
0、时钟使能
c
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 使能GPIOB时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
// 关闭GPIOA时钟(极少用)
__HAL_RCC_GPIOA_CLK_DISABLE();
1、初始化
//初始化一个 / 多个 GPIO 引脚(配置模式、上下拉、速度)
HAL_GPIO_Init();
//恢复 GPIO 引脚为默认状态(模拟输入,无时钟)
HAL_GPIO_DeInit()
示例代码:
c
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 配置PA0为推挽输出,无上下拉,低速
GPIO_InitStruct.Pin = GPIO_PIN_0; // 指定引脚(可组合:GPIO_PIN_0|GPIO_PIN_1)
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;// 模式:推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;// 速度:低速
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 执行初始化
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);// 恢复为默认引脚
2、IO操作
//读取单个引脚电平,返回GPIO_PinState类型
HAL_GPIO_ReadPin();
//设置单个引脚电平(高 / 低)
HAL_GPIO_WritePin();
//翻转引脚电平(LED 闪烁常用)
HAL_GPIO_TogglePin();
//锁定GPIO引脚配置寄存器。
HAL_GPIO_LockPin();
//中断服务函数中调用,清除中断标志并触发回调
HAL_GPIO_EXTI_IRQHandler();
//中断回调函数(需重写,自定义中断逻辑)
HAL_GPIO_EXTI_Callback();
//配置中断优先级
HAL_NVIC_SetPriority();
//使能中断通道
HAL_NVIC_EnableIRQ();
3、宏定义
__HAL_GPIO_EXTI_GET_FLAG 检查指定的EXTI行标志是否设置。
__HAL_GPIO_EXTI_CLEAR_FLAG 清除EXTI的行挂起标志。
__HAL_GPIO_EXTI_GET_IT 检查指定的EXTI行是否被断言。
__HAL_GPIO_EXTI_CLEAR_IT 清除EXTI的行挂起位。
__HAL_GPIO_EXTI_GENERATE_SWIT 在选定的情况下生成软件中断。
4、模式定义
GPIO_MODE_INPUT 输入浮动模式
GPIO_MODE_OUTPUT_PP 输出推拉模式
GPIO_MODE_OUTPUT_OD 输出开漏模式
GPIO_MODE_AF_PP 备用功能推拉模式
GPIO_MODE_AF_OD 备用功能开漏模式
GPIO_MODE_AF_INPUT 备用功能输入模式
GPIO_MODE_ANALOG 模拟模式
GPIO_MODE_IT_RISING 具有上升沿触发检测的外部中断模式
GPIO_MODE_IT_FALLING 具有下降沿触发检测的外部中断模式
GPIO_MODE_IT_RISING_FALLING 具有上升下降沿触发检测的外部中断模式
GPIO_MODE_EVT_RISING 具有上升沿触发检测的外部事件模式
GPIO_MODE_EVT_FALLING 具有下降沿触发检测的外部事件模式
GPIO_MODE_EVT_RISING_FALLING 具有上升下降沿触发检测的外部事件模式
三、示例代码
c
//(GPIO 输出:控制 LED;GPIO 输入:读取按键)
#include "stm32f1xx_hal.h"
// 宏定义(简化代码,方便移植)
#define LED_PIN GPIO_PIN_0
#define LED_PORT GPIOA
#define KEY_PIN GPIO_PIN_1
#define KEY_PORT GPIOA
// GPIO初始化函数
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 1. 使能GPIO时钟(必须!否则引脚无响应)
__HAL_RCC_GPIOA_CLK_ENABLE();
// 2. 配置LED引脚(PA0,推挽输出)
GPIO_InitStruct.Pin = LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 低速
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
// 3. 配置按键引脚(PA1,上拉输入)
GPIO_InitStruct.Pin = KEY_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式
GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉(按键默认高电平,按下接地为低)
HAL_GPIO_Init(KEY_PORT, &GPIO_InitStruct);
}
int main(void)
{
// 1. HAL库初始化(必须!初始化系统时钟、SysTick等)
HAL_Init();
// 2. 配置系统时钟(根据自己的板子配置,如72MHz)
SystemClock_Config();
// 3. 初始化GPIO
GPIO_Config();
while (1)
{
// 4. 读取按键状态(低电平表示按下)
if (HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET)
{
HAL_Delay(20); // 消抖
if (HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET)
{
// 5. 翻转LED电平(亮/灭切换)
HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
// 等待按键释放(避免重复触发)
while (HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET);
}
}
}
}
// 系统时钟配置函数(STM32F103标准配置,可直接用)
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 配置外部晶振(8MHz)作为PLL源,PLL倍频到72MHz
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
// 配置系统时钟、AHB、APB总线时钟
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
// 错误处理函数(可自定义,如LED常亮)
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}