目的
GPIO口使用是单片机开发中最简单的一块,STM32的GPIO口无论是使用HAL库还是LL库开发起来都很简单,也没有什么坑。一般的对性能和内存等没有特殊要求的话用HAL库开发就行了,如果有要求的话可以使用LL库进行开发。
初始化设置
使用STM32CubeIDE或STM32CubeMX来初始化设置GPIO口是比较方便的,毕竟初始化代码都会自动生成,当然我们也可以自己编写初始化代码,参考下面软件生成的初始化代码:
//以下代码将PA2口初始化设置为推挽输出模式
static void MX_GPIO_Init(void)
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; //声明GPIO初始化数据结构
/* GPIO Ports Clock Enable */
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); //使能GPIOA口时钟
/*Reset GPIO pin Output Level */
LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_2); //重置初始输出低电平
/* Configure GPIO pin : PA2 */
GPIO_InitStruct.Pin = LL_GPIO_PIN_2; //设置2口
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; //设置为输出模式
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; //设置为低速
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; //设置为推挽输出模式
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; //没有上下拉电阻
LL_GPIO_Init(GPIOA, &GPIO_InitStruct); //应用初始化设置
}
上面代码中 LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
这句用来完成对指定GPIO口的初始化,程序中如果需要更改GPIO口配置也可以通过此方式更改。当然LL库中也提供了别的方法可以用来修改GPIO口的配置参数:
输出与控制
GPIO口输出通常指推挽输出 LL_GPIO_OUTPUT_PUSHPULL
和开漏输出 LL_GPIO_OUTPUT_OPENDRAIN
,开漏输出还可以设置内部上下拉电阻。在输出模式下通过下面三个方法可以控制输出值:
LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
将输出置为高;LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
将输出置为低;LL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
翻转GPIO输出值;
除了上面这几个方法外,LL库还提供了整组端口设置输出置的方法,可以在库中找到。
输入与端口值读取
输入分数字输入和模拟输入,这里主要讲下数字输入。数字输入的情况下可以设置内部上下拉电阻,如果不设置那就是浮空输入。数字输入时使用下面方法读取端口值:
uint32_t LL_GPIO_IsInputPinSet(GPIO_TypeDef *GPIOx, uint32_t PinMask)
外部中断
STM32每一个IO口都可以设置外部中断,但有点限制,比如PA2设置了外部中断那么PB2、PC2、PD2……等等这些都无法设置外部中断了。所以在IO口上的外部中断最多可以设置0~15号共16个。IO口上的外部中断可以被配置成电平上升沿、下降沿、上升下降沿触发。
下面使用按钮进行外部中断使用演示,按照下图将按钮接到PA1脚,图中电容用于消除按钮操作时的电平抖动:
按照下图进行初始化配置:
上图中设置了PA1脚外部中断,配置为上升下降沿均触发中断,并且将PA1设置为上拉模式,这样根据上面电路按钮未按下时端口为高电平,按钮按下时端口变为低电平。(为了方便测试这里我还启用了Debug引脚,下图就是实际调试效果)
PA1位于EXIT1,上图中在中断回调函数 EXTI1_IRQHandler
中添加了测试代码,测试代码为读取PA1当前输入端口值。当我按下或松开连接在PA1上的按钮的时候端口值会相应的变化。
总结
GPIO口的使用还是非常简单的,更多内容可以参考官方Datasheet、Reference manual、User Manual等。