当前位置: 首页 > news >正文

STM32F1 GPIO介绍及应用

第一章 GPIO介绍及应用

1. GPIO简介

GPIO 是通用输入输出端口的简称,简单来说就是 STM32 可控制的引脚, STM32 芯片的 GPIO 引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。 STM32 芯片的 GPIO被分成很多组,每组有 16 个引脚,如型号为 STM32F103VET6 型号的芯片有 GPIOA、 GPIOB、GPIOC 至 GPIOE 共 5 组 GPIO,芯片一共 100 个引脚,其中 GPIO 就占了一大部分,所有的 GPIO引脚都有基本的输入输出功能。

最基本的输出功能是由 STM32 控制引脚输出高、低电平,实现开关控制,如把 GPIO 引脚接入到 LED 灯,那就可以控制 LED 灯的亮灭,引脚接入到继电器或三极管,那就可以通过继电器或三极管控制外部大功率电路的通断。

最基本的输入功能是检测外部输入电平,如把 GPIO 引脚连接到按键,通过电平高低区分按键是否被按下。

2. GPIO工作模式

总结一下,由 GPIO 的结构决定了 GPIO 可以配置成以下模式:

typedef enum
{GPIO_Mode_AIN = 0x0, // 模拟输入GPIO_Mode_IN_FLOATING = 0x04, // 浮空输入GPIO_Mode_IPD = 0x28, // 下拉输入GPIO_Mode_IPU = 0x48, // 上拉输入GPIO_Mode_Out_OD = 0x14, // 开漏输出    GPIO_Mode_Out_PP = 0x10, // 推挽输出GPIO_Mode_AF_OD = 0x1C, // 复用开漏输出GPIO_Mode_AF_PP = 0x18 // 复用推挽输出
} GPIOMode_TypeDef;

在标准库中, GPIO 总共有 8 种细分的工作模式,稍加整理可以大致归类为以下三类:

2.2.1 输入模式(模拟/浮空/上拉/下拉)

在输入模式时,施密特触发器打开,输出被禁止,可通过输入数据寄存器 GPIOx_IDR 读取 I/O 状态。其中输入模式,可设置为上拉、下拉、浮空和模拟输入四种。上拉和下拉输入很好理解,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候用的是这个模式。模拟输入则用于 ADC 采集。

2.2.2 输出模式(推挽/开漏)

在输出模式中,推挽模式时双 MOS 管以轮流方式工作,输出数据寄存器 GPIOx_ODR 可控制 I/O输出高低电平。开漏模式时,只有 N-MOS 管工作,输出数据寄存器可控制 I/O 输出高阻态或低电平。输出速度可配置,有 2MHz10MHz50MHz 的选项。此处的输出速度即 I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求不严格,把速度设置成最大即可

在输出模式时施密特触发器是打开的,即输入可用,通过输入数据寄存器 GPIOx_IDR 可读取 I/O的实际状态。

2.2.3 复用功能(推挽/开漏)

复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式,但是输出信号源于其它外设,输出数据寄存器 GPIOx_ODR 无效;输入可用,通过输入数据寄存器可获取 I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。

3. GPIO使用示例

3.1 GPIO输出-点亮LED

在这里插入图片描述

3.1.1 led相关参数宏定义
#ifndef __LED_H__
#define __LED_H__#include "stm32f10x.h"#define LED_GPIO_Port GPIOB
#define LED_GPIO_CLK RCC_APB2Periph_GPIOB
#define RED_LED_Pin GPIO_Pin_5
#define GREEN_LED_Pin GPIO_Pin_0
#define BLUE_LED_Pin GPIO_Pin_1#define LED_ON(x)    GPIO_SetBits(LED_GPIO_Port, (x))
#define LED_OFF(x)   GPIO_ResetBits(LED_GPIO_Port, (x))#endif /* __LED_H__ */
3.1.2 GPIO初始化
#include "led.h"void BSP_LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE); // 打开GPIO时钟// 初始化红色 LED 引脚GPIO_InitStructure.GPIO_Pin = RED_LED_Pin; // 选择引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出速度GPIO_Init(LED_GPIO_Port, &GPIO_InitStructure);// 初始化绿色 LED 引脚GPIO_InitStructure.GPIO_Pin = GREEN_LED_Pin;GPIO_Init(LED_GPIO_Port, &GPIO_InitStructure);// 初始化蓝色 LED 引脚GPIO_InitStructure.GPIO_Pin = BLUE_LED_Pin;GPIO_Init(LED_GPIO_Port, &GPIO_InitStructure);// 初始LED全灭LED_OFF(RED_LED_Pin);LED_OFF(GREEN_LED_Pin);LED_OFF(BLUE_LED_Pin);
}
3.1.3 主函数测试
#include "stm32f10x.h"
#include "led.h"#define led_delay delay(0x0FFFFF);void delay(__IO uint32_t nCount)
{for(; nCount != 0; nCount--);
}int main()
{BSP_LED_Init();while(1){LED_ON(RED_LED_Pin);led_delay;LED_OFF(RED_LED_Pin);led_delay;LED_ON(GREEN_LED_Pin);led_delay;LED_OFF(GREEN_LED_Pin);led_delay;LED_ON(BLUE_LED_Pin);led_delay;LED_OFF(BLUE_LED_Pin);led_delay;}
}

3.2 GPIO输出-控制蜂鸣器

在这里插入图片描述

3.2.1 蜂鸣器相关参数宏定义
#ifndef __BEEP_H__
#define __BEEP_H__ #include "stm32f10x.h"#define Beep_GPIO_Port GPIOA
#define Beep_GPIO_CLK RCC_APB2Periph_GPIOA
#define Beep_GPIO_Pin GPIO_Pin_8#define BEEP_ON() GPIO_SetBits(Beep_GPIO_Port, Beep_GPIO_Pin)
#define BEEP_OFF() GPIO_ResetBits(Beep_GPIO_Port, Beep_GPIO_Pin)void BSP_Beep_Init(void);#endif /* __BEEP_H__ */
3.2.2 GPIO初始化
#include "beep.h"void BSP_Beep_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(Beep_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = Beep_GPIO_Pin;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(Beep_GPIO_Port, &GPIO_InitStructure);BEEP_OFF();
}
3.2.3 主函数测试
#include "stm32f10x.h"
#include "beep.h"#define beep_delay delay(0x0FFFFF);void delay(__IO uint32_t nCount)
{for(; nCount != 0; nCount--);
}int main()
{BSP_Beep_Init();while(1){BEEP_ON();beep_delay;BEEP_OFF();beep_delay;}
}

3.3 GPIO输入-按键控制LED

在这里插入图片描述

3.3.1 按键相关参数宏定义
#ifndef __KEY_H__
#define __KEY_H__#include "stm32f10x.h"#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA
#define KEY1_GPIO_Port GPIOA
#define KEY1_GPIO_Pin GPIO_Pin_0
#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC
#define KEY2_GPIO_Port GPIOC
#define KEY2_GPIO_Pin GPIO_Pin_13#define KEY_OFF 0
#define KEY_ON 1void BSP_KEY_Init(void);
uint8_t KEY_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);#endif /* __KEY_H__ */
3.3.2 GPIO初始化
void BSP_KEY_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_Pin;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_Pin;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY2_GPIO_Port, &GPIO_InitStructure);
}
3.3.3 按键扫描函数
uint8_t KEY_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON) // 读取按键电平{while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON); // 判断按键是否长时间按下return KEY_ON;}else{return KEY_OFF;}
}
3.3.4 主函数测试
#include "stm32f10x.h"
#include "led.h"
#include "key.h"int main()
{BSP_LED_Init();BSP_KEY_Init();while(1){if(KEY_Scan(KEY1_GPIO_Port, KEY1_GPIO_Pin) == KEY_ON){LED_ON(RED_LED_Pin);}if(KEY_Scan(KEY2_GPIO_Port, KEY2_GPIO_Pin) == KEY_ON){LED_OFF(RED_LED_Pin);}}
}

4. GPIO常见函数(STD库)

4.1 初始化与配置

  • 使能GPIO时钟
    使用RCC_APB2PeriphClockCmd()开启对应GPIO端口的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟
  • GPIO初始化
    通过GPIO_Init()配置引脚模式、速度等参数:
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;          // 配置PA0
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;   // 推挽输出模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  // 速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStruct);             // 应用配置

4.2 输出操作

  • 设置引脚为高电平
    GPIO_SetBits()将指定引脚置高:
GPIO_SetBits(GPIOA, GPIO_Pin_0); // PA0输出高电平
  • 设置引脚为低电平
    GPIO_ResetBits()将指定引脚置低:
GPIO_ResetBits(GPIOA, GPIO_Pin_0); // PA0输出低电平
  • 按位写入引脚状态
    GPIO_WriteBit()灵活设置单个引脚状态(Bit_SETBit_RESET):
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); // PA0输出高
  • 写入整个端口
    GPIO_Write()一次性设置所有引脚状态:
GPIO_Write(GPIOA, 0x01); // PA0置高,其余置低

4.3 输入操作

  • 读取单个引脚输入状态
    GPIO_ReadInputDataBit()获取输入引脚的电平:
uint8_t value = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0); // 读取PA0输入值
  • 读取整个端口输入值
    GPIO_ReadInputData()返回端口的16位输入数据:
uint16_t port_value = GPIO_ReadInputData(GPIOA); // 读取GPIOA所有输入引脚

4.4 输出状态读取

  • 读取输出寄存器状态
    GPIO_ReadOutputDataBit()GPIO_ReadOutputData()用于读取输出寄存器的值(可能与实际引脚状态不同):
uint8_t output_bit = GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0); // 读取PA0输出寄存器状态
uint16_t output_port = GPIO_ReadOutputData(GPIOA);              // 读取GPIOA输出寄存器全部状态

4.5 其他函数

  • 引脚配置锁定
    GPIO_PinLockConfig()锁定引脚配置,防止意外修改:
GPIO_PinLockConfig(GPIOA, GPIO_Pin_0); // 锁定PA0配置

文中工程下载:https://github.com/hazy1k/STM32F1-Quick-Start-Guide-STD/tree/master/2.code

http://www.dtcms.com/a/344914.html

相关文章:

  • Vue2.x核心技术与实战(三)
  • 掌握DRF的serializer_class:高效API开发
  • [激光原理与应用-318]:光学设计 - Solidworks - 草图中常见的操作
  • PCIe 5.0 SSD的发热量到底有多大?如何避免?
  • ubuntu - 终端工具 KConsole安装
  • DL00433-基于深度学习的无人机红外成像系统可视化含数据集
  • 【数据结构】选择排序:直接选择与堆排序详解
  • 【小白笔记】 MNN 移动端大模型部署
  • Java试题-选择题(14)
  • 新能源知识库(83)新能源行业的标准制定机构介绍
  • 期权买沽是什么意思?
  • python3GUI--Joy音乐播放器 在线播放器 播放器 By:PyQt5(附下载地址)
  • DAY01:【DL 第一弹】深度学习的概述
  • 什么是哈希值(hash value)???
  • FFmpeg03:多媒体文件处理基础
  • ffmpeg 中 crc32 源码分析及调试
  • vagrant怎么在宿主机操作虚拟机里面的系统管理和软件安装
  • xilinx的oddr原语是否可以直接使用verilog实现?
  • ingress和service区别
  • 20250822解决荣品RD-RK3588-MID核心板出现插USB开机-长按RESET开机的问题
  • 基于LangChain + Milvus 实现RAG
  • 升级 Docker Compose 到最新版本:从安装到验证全指南
  • SOLIDWORKS 2025智能工具优化设计流程
  • 数据结构: 2-3 树的删除操作 (Deletion)
  • Maven的概念与Maven项目的创建
  • 线程异步操作
  • LoRA内部原理代码解析(52)
  • 【笔记】动手学Ollama 第七章 应用案例 Agent应用
  • SpringBoot项目创建的五种方式
  • 线性回归:机器学习中的基石