长春营销型网站设计,汽车门户网站程序,增加网站访问量,神箭手 wordpressSTM32-GPIO
介绍
什么是GPIO#xff1f;
GPIO#xff08;通用输入/输出#xff09;是一种用于与外部设备进行数字通信的通用硬件接口。它允许微控制器或其他数字电路的引脚以灵活的方式配置为输入或输出#xff0c;并在运行时进行动态控制。GPIO可用于连接和控制各种外围…STM32-GPIO
介绍
什么是GPIO
GPIO通用输入/输出是一种用于与外部设备进行数字通信的通用硬件接口。它允许微控制器或其他数字电路的引脚以灵活的方式配置为输入或输出并在运行时进行动态控制。GPIO可用于连接和控制各种外围设备如LED、按钮、传感器、显示器、通信设备等。
GPIO模式
GPIO引脚的工作可以配置为输入还是输出以及其他相关的特性。STM32微控制器提供了多个寄存器来配置每个GPIO引脚的工作模式包括MODER模式寄存器、OTYPER输出类型寄存器、OSPEEDR输出速度寄存器、PUPDR上拉/下拉寄存器等。
以STM32F407为例它的5 V 容忍 I/O 端口位的基本结构如下
以下是STM32的GPIO引脚的几种基本模式 输入模式 (Input Mode): Analog Mode模拟模式: 用于连接模拟传感器。Floating Input浮空输入: 没有内部上拉或下拉电阻需要外部电路提供电平。Pull-up / Pull-down上拉/下拉输入: 配置内部上拉或下拉电阻用于消除浮空输入的不确定性。 输出模式 (Output Mode): Push-Pull Output推挽输出: 可以提供高电平和低电平输出。Open-Drain Output开漏输出: 用于连接多个设备需要外部上拉电阻来提供高电平。Push-Pull with Pull-up/Pull-down推挽输出带上拉/下拉: 输出高电平或低电平时同时配置上拉或下拉电阻。
常用API
在使用STM32的HAL库进行GPIO输入输出配置时主要使用的API包括HAL_GPIO_Init、HAL_GPIO_DeInit、HAL_GPIO_WritePin、HAL_GPIO_ReadPin等。 HAL_GPIO_Init函数 HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_Init);用于初始化指定的GPIO引脚。其中GPIOx是指定的GPIO端口如GPIOA、GPIOB等GPIO_Init是一个结构体包含了GPIO引脚的配置信息如模式、速度、上拉下拉等。 例如将PA5配置为推挽输出 GPIO_InitTypeDef GPIO_InitStruct {0};
GPIO_InitStruct.Pin GPIO_PIN_5;
GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_InitStruct.Speed GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOA, GPIO_InitStruct);HAL_GPIO_DeInit函数 void HAL_GPIO_DeInit(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin);用于反初始化指定的GPIO引脚。其中GPIOx是指定的GPIO端口GPIO_Pin是指定的GPIO引脚。 例如反初始化PA5引脚 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5);HAL_GPIO_WritePin函数 void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);用于设置指定的GPIO引脚的输出状态。其中GPIOx是指定的GPIO端口GPIO_Pin是指定的GPIO引脚PinState是要设置的状态GPIO_PIN_SET表示高电平GPIO_PIN_RESET表示低电平。 例如将PA5设置为高电平 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);HAL_GPIO_ReadPin函数 GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);用于读取指定GPIO引脚的输入状态。其中GPIOx是指定的GPIO端口GPIO_Pin是指定的GPIO引脚。 例如读取PA5引脚的状态 GPIO_PinState state HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5);项目实训
点亮一颗led
STM32F407芯片连接了一个LED到PA5引脚
#include stm32f4xx_hal.hvoid SystemClock_Config(void);
static void GPIO_Init(void);int main(void) {// 初始化HAL库HAL_Init();// 配置系统时钟SystemClock_Config();// 初始化GPIOGPIO_Init();while (1) {// 点亮LEDHAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);// 延时HAL_Delay(1000);// 关闭LEDHAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);// 延时HAL_Delay(1000);}
}// 系统时钟配置函数使用HAL库的CubeMX生成的代码
void SystemClock_Config(void) {RCC_OscInitTypeDef RCC_OscInitStruct {0};RCC_ClkInitTypeDef RCC_ClkInitStruct {0};__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState RCC_HSI_OFF;RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM 8;RCC_OscInitStruct.PLL.PLLN 336;RCC_OscInitStruct.PLL.PLLP RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ 4;if (HAL_RCC_OscConfig(RCC_OscInitStruct) ! HAL_OK) {Error_Handler();}RCC_ClkInitStruct.ClockType 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_DIV4;RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_5) ! HAL_OK) {Error_Handler();}
}// GPIO初始化函数
static void GPIO_Init(void) {// 启用GPIOA时钟__HAL_RCC_GPIOA_CLK_ENABLE();// 初始化PA5引脚为推挽输出GPIO_InitTypeDef GPIO_InitStruct {0};GPIO_InitStruct.Pin GPIO_PIN_5;GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Speed GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);// 初始化引脚状态为低电平HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
}
按键控制LED亮灭
假设按键连接到PA0引脚LED连接到PA5引脚
#include stm32f4xx_hal.hvoid SystemClock_Config(void);
static void GPIO_Init(void);int main(void) {// 初始化HAL库HAL_Init();// 配置系统时钟SystemClock_Config();// 初始化GPIOGPIO_Init();while (1) {// 读取按键状态if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) GPIO_PIN_SET) {// 按键按下点亮LEDHAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);} else {// 按键未按下关闭LEDHAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);}}
}// 系统时钟配置函数使用HAL库的CubeMX生成的代码
void SystemClock_Config(void) {RCC_OscInitTypeDef RCC_OscInitStruct {0};RCC_ClkInitTypeDef RCC_ClkInitStruct {0};__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState RCC_HSI_OFF;RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM 8;RCC_OscInitStruct.PLL.PLLN 336;RCC_OscInitStruct.PLL.PLLP RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ 4;if (HAL_RCC_OscConfig(RCC_OscInitStruct) ! HAL_OK) {Error_Handler();}RCC_ClkInitStruct.ClockType 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_DIV4;RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_5) ! HAL_OK) {Error_Handler();}
}// GPIO初始化函数
static void GPIO_Init(void) {// 启用GPIOA时钟__HAL_RCC_GPIOA_CLK_ENABLE();// 初始化PA0引脚为上拉输入按键连接到地按下时引脚电平为低GPIO_InitTypeDef GPIO_InitStruct {0};GPIO_InitStruct.Pin GPIO_PIN_0;GPIO_InitStruct.Mode GPIO_MODE_INPUT;GPIO_InitStruct.Pull GPIO_PULLUP;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);// 初始化PA5引脚为推挽输出GPIO_InitStruct.Pin GPIO_PIN_5;GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Speed GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);// 初始化引脚状态为低电平HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
}// 错误处理函数
void Error_Handler(void) {while (1) {// 程序错误时停在这里}
}