尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

STM32 GPIO 标准库完全指南——从点亮LED到理解按键

STM32 GPIO 标准库完全指南——从点亮LED到理解按键 写在最前为什么从GPIO开始如果说学习一门编程语言的第一课是“Hello World”那么学习STM32的第一课就是点亮LED。而点亮LED就离不开GPIO——General Purpose Input Output通用输入输出端口。GPIO是STM32与外部世界对话的最基本方式。你可以通过它输出高/低电平去控制LED亮灭也可以通过它读取外部按键的电平变化。可以说几乎任何STM32项目都绕不开GPIO。本篇博客的目标是理解GPIO是什么、内部怎么工作的掌握标准库下GPIO的编程步骤能独立完成一个LED1.1 最朴素的理解想象你家里有一排电灯开关。每个开关只有两个状态开和关。你可以手动拨动开关改变灯的亮灭也可以看看某个开关现在是开还是关。GPIO引脚就是STM32芯片上的“电子开关”。每个引脚可以输出模式由芯片控制引脚输出高电平约3.3V或低电平0V相当于芯片替你“拨动开关”输入模式芯片读取引脚上当前的电压是高还是低相当于芯片“看一眼开关状态”1.2 STM32的GPIO有哪些特点相比51单片机简单的I/OSTM32的GPIO要复杂得多但也强大得多。第一数量多、分组管理。STM32最多可有7组GPIOGPIOA~GPIOG每组最多16个引脚总共可达112个。型号不同数量不同比如STM32F103ZET6就有7组×16个共112个GPIO引脚。第二8种工作模式可配置。每个引脚都可以通过软件独立配置为以下8种模式之一。模式分类具体模式通俗理解输入模式浮空输入引脚浮着电平由外部决定输入模式上拉输入内部有个电阻把电平“拉”到高电平输入模式下拉输入内部有个电阻把电平“拉”到低电平输入模式模拟输入用于ADC采集模拟信号输出模式推挽输出能直接输出高低电平驱动能力强输出模式开漏输出只能输出低电平或高阻态需外接上拉电阻复用模式推挽复用引脚交给片上外设如USART、SPI使用复用模式开漏复用同上但为开漏方式第三部分引脚支持5V容忍。标有“FT”的引脚可以承受5V电压与5V电平的外设连接时很方便。二、GPIO内部结构——从“框图”看本质只看文字很难理解为什么GPIO有这么多种模式我们来看看GPIO的内部结构图。2.1 GPIO的基本结构每个GPIO引脚内部大致是这样的结构┌─────────────┐ ──────┬─────────────┤ 保护二极管 ├─────► 到芯片内部 │ └─────────────┘ │ ▼ ┌──────────┐ │ 上拉电阻 │ (可配置) └──────────┘ │ ┌──────────┐ │ 下拉电阻 │ (可配置) └──────────┘ │ ├──────────────────────┐ │ │ ▼ ▼ ┌─────────┐ ┌─────────┐ │ P-MOS │ │ 输入 │ │ (上管) │ │ 数据 │ ├─────────┤ │ 寄存器 │ │ N-MOS │ └─────────┘ │ (下管) │ └─────────┘ │ ▼ GPIO引脚外部2.2 两个MOS管决定输出模式关键部件是P-MOS管和N-MOS管这对组合推挽输出模式两个MOS管都工作。输出1时P-MOS导通引脚输出高电平输出0时N-MOS导通引脚输出低电平。特点驱动能力强、速度高适合驱动LED等负载。开漏输出模式P-MOS管完全不工作。输出0时N-MOS导通引脚拉低输出1时两个MOS都关闭引脚呈高阻态必须外接上拉电阻才能得到高电平。特点可实现“线与”逻辑适合多设备共享总线如I2C。2.3 上拉/下拉电阻的作用在输入模式下上拉/下拉电阻用于给引脚一个“默认电平”。如果不接任何外部信号浮空输入的电平是不确定的容易受干扰。上拉电阻把它固定为高电平下拉电阻固定为低电平。三、标准库GPIO编程——三步走理解了原理我们来看实际怎么写代码。STM32标准外设库把寄存器操作封装成了函数我们主要用这些函数。3.1 编程三步骤使用GPIO的标准流程固定为三步1. 使能GPIO端口时钟 2. 初始化GPIO引脚配置模式、速度等 3. 在程序中控制或读取GPIO3.2 第一步使能时钟STM32的所有外设都有独立的时钟开关。使用GPIO前必须先开启对应端口的时钟。为什么要这样——省电。用不到的模块可以关闭时钟以降低功耗。#include stm32f10x_rcc.h // 使能GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);注意GPIO挂载在APB2总线上所以用RCC_APB2PeriphClockCmd函数。不同STM32系列可能略有差异F1系列如此。3.3 第二步初始化GPIO标准库用GPIO_InitTypeDef结构体来配置GPIO参数然后调用GPIO_Init函数写入寄存器。#include stm32f10x_gpio.h GPIO_InitTypeDef GPIO_InitStructure; // 配置PA0引脚推挽输出50MHz速度 GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; // 输出速度 GPIO_Init(GPIOA, GPIO_InitStructure);模式选择速查表使用场景GPIO_Mode驱动LED、蜂鸣器等GPIO_Mode_Out_PP推挽输出读取按键、开关状态GPIO_Mode_IPU上拉输入或GPIO_Mode_IPD下拉输入I2C的SCL/SDAGPIO_Mode_AF_OD复用开漏USART的TX/RXGPIO_Mode_AF_PP复用推挽ADC模拟采集GPIO_Mode_AIN模拟输入3.4 第三步控制或读取GPIO输出控制常用函数// 设置指定引脚为高电平 GPIO_SetBits(GPIOA, GPIO_Pin_0); // 设置指定引脚为低电平 GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 反转引脚电平 GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0)));读取输入常用函数// 读取指定引脚的电平输入模式 uint8_t status GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0); // 读取整个端口 uint16_t portData GPIO_ReadInputData(GPIOA);四、实战点亮一颗LED4.1 硬件连接假设你的开发板上LED连接的是GPIOB的Pin5引脚LED另一端正极接3.3V低电平点亮。4.2 完整代码c#include stm32f10x.h // 定义LED引脚方便以后修改 #define LED_PORT GPIOB #define LED_PIN GPIO_Pin_5 #define LED_PORT_CLK RCC_APB2Periph_GPIOB // 简单的延时函数不精准但初学者够用 void delay(uint32_t count) { while(count--); } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; // 1. 使能时钟 RCC_APB2PeriphClockCmd(LED_PORT_CLK, ENABLE); // 2. 初始化GPIO GPIO_InitStructure.GPIO_Pin LED_PIN; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(LED_PORT, GPIO_InitStructure); // 3. 主循环闪烁 while(1) { GPIO_SetBits(LED_PORT, LED_PIN); // LED熄灭高电平 delay(500000); GPIO_ResetBits(LED_PORT, LED_PIN); // LED点亮低电平 delay(500000); } }4.3 代码解读RCC_APB2PeriphClockCmd开启GPIOB时钟这是最容易忘记的一步GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz设置输出速度不是引脚电压变化速度的上限而是驱动电路的响应速度。常用的有10MHz、2MHz、50MHz一般设50MHz即可GPIO_SetBits/GPIO_ResetBits标准库提供的电平控制函数比直接操作寄存器更直观五、实战读取按键输入理解了输出再来看输入。按键是GPIO输入最典型的应用。5.1 硬件连接按键一端接GPIO引脚另一端接地。GPIO配置为上拉输入模式——按键未按下时引脚被内部上拉电阻拉到高电平按下时引脚被拉低。5.2 代码示例c#include stm32f10x.h #define KEY_PORT GPIOA #define KEY_PIN GPIO_Pin_0 int main(void) { GPIO_InitTypeDef GPIO_InitStructure; // 1. 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 2. 配置按键引脚为上拉输入 GPIO_InitStructure.GPIO_Pin KEY_PIN; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; // 上拉输入 GPIO_Init(KEY_PORT, GPIO_InitStructure); while(1) { // 读取按键状态 if(GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN) RESET) { // 按键被按下电平为低 // 这里可以执行按键响应操作 } } }5.3 小提示按键消抖机械按键在按下和释放的瞬间会产生几十毫秒的电平抖动。实际项目中通常需要做消抖处理软件延时或定时器检测初学者可以先加一个简单的延时来跳过抖动期。六、标准库常用GPIO函数速查以下是在标准库以STM32F10x系列为例中最常用的GPIO函数函数功能RCC_APB2PeriphClockCmd()使能/失能GPIO时钟GPIO_Init()初始化GPIO引脚GPIO_SetBits()将指定引脚设为高电平GPIO_ResetBits()将指定引脚设为低电平GPIO_WriteBit()写入指定引脚的电平GPIO_ReadInputDataBit()读取指定引脚输入电平GPIO_ReadInputData()读取整个端口的输入值GPIO_ReadOutputDataBit()读取指定引脚的输出电平读的是输出寄存器八、总结今天我们一起学习了GPIO的本质就是STM32芯片上的“电子开关”可以输入也可以输出8种工作模式重点是推挽输出驱动LED和上拉输入读取按键三个步骤使能时钟 → 初始化GPIO → 控制/读取两个完整代码LED闪烁和按键检测
返回列表