一. GPIO概述
GPIO全称General Purpose Input Output,是微控制数字输入/输出的基本模块,可以实现微控制器与外部环境的数字进行交换。借助GPIO微控制器可以实现对外围设备(像控制led亮灭,按键控制,软件模拟IIC等)直观又简单的控制。
在STM32中,GPIO的资源相当的丰富,旗下的微控制器片上最多有7组I/O端口:GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG,每组端口有16个外部引脚,每组端口的引脚都具有通用I/O(输入/输出),单独位清除/位清除,I/O唤醒/中断,复用(AF),软件重新映射I/O复用,GPIO锁定机制功能。
STM32的每个GPIO端口都由7个寄存器:
·2个32位 配置寄存器(GPIOx_CRL,GPIOx_CRH);
·2个32位 数据寄存器(GPIOx_IDR,GPIOx_ODR);
·1个32位 位/复位寄存器(GPIOx_BSRR);
·1个16位 复位寄存器(GPIOx_BRR);
·1个32位 锁定寄存器(GPIOx_LCKR);
STM32中的GPIO口可以由软件配置成8种模式:
浮空输入模式,上拉输入模式,下拉输入模式,模拟输入模式
推挽输出模式,开漏输出模式,复用推挽输出模式,复用开漏输出模式
二. GPIO的主要特征
- 提供最多112个多功能双向的I/O引脚,80%的引脚利用率。
- 几乎每一个引脚(除了ADC)都兼容5V,每一个I/O具有20mA的驱动能力。
- 每个I/O引脚最高18MHz的翻转速度和50MHz的输出速度。
- 每个I/O引脚有8种工作模式,在复位和刚复位后,复位功能未开启,I/O引脚被设置为浮空输入模式。
- 所有的I/O引脚都具有复用功能,包括JTAG/SWD,Timer,USART,I2C,SPI等。
- 某些复用功能引脚(除了F和G端口)都可以用作事件输入。
- PA0可以用作从机待机模式唤醒的引脚,PC13可以用作入侵检测的引脚。
三. 使用STM32CubeMX配置GPIO基础开发-输出模式
我们打开STM32CubeMX软件
点击file->new project新建一个工程
点开system core->RCC->HSE中选择crystal/ceramic resonator配置RCC使用外部高速时钟源,再点开system core->SYS->Debug中选择serial wire,再到Clock Configuration配置时钟源
我的开发板上的LED灯是在接在了PB4管脚口上,且该管脚口需要输出低电平才能点亮LED1 灯,配置如下
至此我们就已经配置好了一个GPIO管脚口的输出模式,现在我们学习保存工程,操作如下
关于STM32CubeMX软件创建一个GPIO输出工程到此就创建好了,接下来我们来聊聊看看GPIO电平输出有关的HAL库函数
四. GPIO输出有关的HAL库函数
GPIO电平输出HAL库函数
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
/**
* @概要 设置或清除所选数据端口位。
* @参数 GPIOx: 端口号,其中x可以是A…G(取决于你所使用的设备)来选择GPIO外设。如:GPIOA
* @参数 GPIO_Pin: 引脚号,指定要写入的端口位。该参数可以是GPIO_PIN_x中的一个,其中x可以是(0..15)。如GPIO_PIN_1
* @参数 PinState: 引脚输出状态,高电平--GPIO_PIN_SET,低电平--GPIO_PIN_RESET
* @返回值 空
*/
GPIO电平翻转HAL库函数
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
/**
* @概要 切换指定的GPIO引脚
* @参数 GPIOx: 端口号,其中x可以是A…G(取决于你所使用的设备)来选择GPIO外设。如:GPIOA
* @参数 GPIO_Pin: 引脚号,指定要写入的端口位。该参数可以是GPIO_PIN_x中的一个,其中x可以是(0..15)。如GPIO_PIN_1
* @返回值 空
*/
GPIO锁定模式函数
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
/**
* @概要 锁定GPIO引脚配置寄存器。
* @批注 锁定机制允许IO配置被冻结。当锁序列被应用于端口位时,在下一次重置之前,不可能再修改端口位的值。
* @参数 GPIOx: 端口号,其中x可以是A…G(取决于你所使用的设备)来选择GPIO外设。如:GPIOA
* @参数 GPIO_Pin: 引脚号,指定要写入的端口位。该参数可以是GPIO_PIN_x中的一个,其中x可以是(0..15)。如GPIO_PIN_1
* @返回值 空
*/
GPIO初始化函数源码剖析
void MX_GPIO_Init(void){
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO端口时钟使能 */
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*GPIO初始化函数源码剖析 */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
/*配置GPIO引脚:PB4 */
GPIO_InitStruct.Pin = GPIO_PIN_4; //GPIO端口的引脚号是:4
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //GPIO的模式是:推挽输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL; //没有上拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; //GPIO的输出速度是:非常低速
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); //将参数结构设置到GPIOB端口
}
五. 实现点亮开发板上的LED小灯
在main.c的while(1) { } 中添加如下代码
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
实现的效果是LED1小灯灯亮,1s过一会,LED1灯灭,1s过一会,LED1灯电平翻转,1s过一会…如此循环。