📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨
📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】
📢:文章若有幸对你有帮助,可点赞 👍 收藏 ⭐不迷路🙉
📢:内容若有错误,敬请留言 📝指正!原创文,转载注明出处
最近一段时间使用单片机外设比较频繁,尤其是GPIO使用更为常见,今天就从GPIO的原理和实战这两个方面进行介绍。
1.GPIO参数
GPIO的使用会先配置它的参数,有4个,即端口、模式、速率和PIN脚,在STM32的头文件中定义了GPIO结构体,来配置后面三个参数。
1.1 端口和引脚
GPIO 端口是一组 GPIO 引脚的集合,在硬件层面,它是芯片上的一个物理单元,将多个相关的 GPIO 引脚组合在一起进行管理。每个端口通常由多个连续编号的引脚组成,不同的微控制器或开发板上,端口的数量和每个端口包含的引脚数会有所不同。例如,在 STM32 系列微控制器中,常见的有 GPIOA、GPIOB、GPIOC 等多个端口,每个端口一般包含 16 个 GPIO 引脚。
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */
#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */
#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */
#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */
#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */
#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */
GPIO 引脚是 GPIO 端口中的具体连接点,是芯片与外部电路进行信号交互的物理接口。每个引脚可以独立地配置为输入或输出模式,以实现不同的功能。例如,一个引脚可以连接到一个按键,用于检测按键的按下或释放状态(输入模式);也可以连接到一个 LED 灯,用于控制 LED 的亮灭(输出模式)。
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */
#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */
#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */
#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */
#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */
1.2 模式
模式类型 | 模式名称 | 原理 | 特点 | 应用场景 |
---|---|---|---|---|
输入模式 | 浮空输入 | 引脚不接上拉或下拉电阻,直接与外部信号相连,电平完全取决于外部信号 | 易受干扰,电平不稳定 | 外部信号源已处理好上拉或下拉的情况,如特定传感器 |
上拉输入 | 内部通过上拉电阻连接电源,无外部信号时引脚为高电平,外部低电平可拉低引脚 | 抗干扰能力较强 | 按键检测,按键按下拉低电平 | |
下拉输入 | 内部通过下拉电阻连接地,无外部信号时引脚为低电平,外部高电平可拉高引脚 | 抗干扰能力较强 | 按键检测,按键按下拉高电平 | |
模拟输入 | 引脚绕过数字输入缓冲器,直接连接片上 ADC 模块以采集模拟信号 | 可精准采集模拟量 | 温度、压力等传感器的模拟信号采集 | |
输出模式 | 推挽输出 | 由 P 沟道和 N 沟道 MOS 管组成推挽结构,分别控制高低电平输出 | 能提供较大驱动电流 | 直接驱动小功率负载,如 LED 灯 |
开漏输出 | 仅用 N 沟道 MOS 管,低电平导通接地,高电平为高阻态,需外接上拉电阻 | 可实现线与功能 | I2C 总线通信 | |
复用推挽输出 | GPIO 配置为复用功能,采用推挽输出,信号由片上其他外设控制 | 信号由外设决定 | 定时器的 PWM 信号输出 | |
复用开漏输出 | GPIO 配置为复用功能,采用开漏输出,信号由片上其他外设控制,需外接上拉电阻 | 可实现线与功能且信号由外设控制 | I2C 接口的 SDA 和 SCL 线 |
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;
1.3 速度
GPIO引脚的速度。在微控制器中,GPIO 引脚的速度设置会影响其输出信号的切换速度,注意是输出速度,输入模式下,配置了这个速度也是无效的。
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
2. GPIO寄存器
主要对某个端口的某个pin脚进行拉高拉低的操作。
寄存器名称 | 英文全称 | 功能 | 寄存器位分布 | 使用示例 |
---|---|---|---|---|
CRL | Port Configuration Register Low | 配置 GPIO 端口低 8 位引脚(Pin0 - Pin7)的工作模式和输出速度 | 每个引脚用 4 位配置,如 Pin0 由第 0 - 3 位控制,Pin1 由第 4 - 7 位控制 | 将 Pin2 配置为推挽输出且速度为 10MHz,设置对应 4 位为 0x01 |
CRH | Port Configuration Register High | 配置 GPIO 端口高 8 位引脚(Pin8 - Pin15)的工作模式和输出速度 | 每个引脚对应 4 位确定模式和速度 | 将 Pin10 配置成浮空输入模式,设置对应 4 位为 0x04 |
IDR | Port Input Data Register | 在引脚为输入模式时,读取引脚电平状态(高或低) | 32 位寄存器,每位对应一个 GPIO 引脚,第 0 位对应 Pin0,第 1 位对应 Pin1 | 读取 Pin3 输入状态,检查第 3 位,1 为高电平,0 为低电平 |
ODR | Port Output Data Register | 在引脚为输出模式时,设置引脚输出高或低电平 | 32 位寄存器,每位对应一个 GPIO 引脚 | 让 Pin5 输出高电平,将第 5 位置 1 |
BSRR | Port Bit Set/Reset Register | 单独设置或清除 GPIO 端口的某一位 | 低 16 位(第 0 - 15 位)用于设置引脚,高 16 位(第 16 - 31 位)用于清除引脚 | 将 Pin7 设置为高电平,向第 7 位写 1;清除为低电平,向第 23 位写 1 |
BRR | Port Bit Reset Register | 专门清除 GPIO 端口的某一位 | 低 16 位,每位对应一个 GPIO 引脚 | 将 Pin9 清除为低电平,向第 9 位写 1 |
LCKR | Port Configuration Lock Register | 锁定 GPIO 端口的配置,锁定后下次复位前无法修改 | 第 0 - 15 位对应 Pin0 - Pin15 的锁定状态,第 16 位是锁定键 | 锁定 Pin4 配置,按特定锁定序列操作 |
tyedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
3. 项目实战
3.1 基本步骤
第一步:开启GPIO时钟
第二步:配置GPIO参数
第三步:GPIO初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
3.2 应用实例
按键控制LED