STM32GPIO

一、GPIO基础

相信聪明的你一定已经发现了GPIO只是几个单词的缩写,那么什么是GPIO呢------不妨我们来看看全称General Purpose Input/Output)通用目的输入输出。是微控制器中非常灵活的外设之一,它们可以被配置为多种不同的工作模式,以适应各种应用需求。

  • STM32微控制器的每个GPIO引脚可以配置为输入或输出。
  • 输入模式可以检测外部电平(高电平或低电平),输出模式可以控制外部电平(设为高电平或低电平)。
  • STM32芯片最多拥有GPIOA~GPIOG等7组端口,每组端口最多拥有Pin0~Pin15共16个引脚。STM32的每个I/O端口都可以自由编程,但I/O端口寄存器必须按32位字被访问,且每个I/O端口都由7个寄存器来控制。
  • 引脚编号如PA0、PB1等,表示引脚所属的端口及其在端口中的位置。
  • 上电复位后,GPIO默认为浮空状态,部分特殊功能引脚为特定状态。

二、GPIO的模式

 如图,GPIO具有两个功能--输入和输出。每种功能下共有四种工作模式。

   GPIO_Mode_AIN ---------------------- 模拟输入
   GPIO_Mode_IN_FLOATING -------- 输入浮空
   GPIO_Mode_IPD ---------------------- 输入下拉
   GPIO_Mode_IPU  ---------------------- 输入上拉
   GPIO_Mode_Out_OD ---------------- 开漏输出
   GPIO_Mode_Out_PP ---------------- 推挽式输出
   GPIO_Mode_AF_OD ---------------- 开漏复用功能
   GPIO_Mode_AF_PP ----------------- 推挽式复用功能

先来讲讲输入中的上拉和下拉。我们可以选择在输入模式下使用上拉或下拉电阻,这样可以确保在没有外部信号时引脚保持稳定状态。

接下来再讲讲输出中的推挽和开漏,通用和复用。

推挽:在推挽输出模式时,N-MOS 管和 P-MOS 管都工作。当控制输出为低电平(0)时,P-MOS 管关闭,N-MOS 管导通,使输出低电平,I/O 端口的电平就是低电平;当控制输出为高电平(1)时,P-MOS 管导通,N-MOS 管关闭,使输出高电平,I/O 端口的电平就是高电平。外部上拉和下拉的作用是控制在没有输出时 I/O 口电平。此模式可输出强高、低电平,适用于连接数字器件。

推挽模式下P-Mos和N-Mos交替导通。

开漏开漏输出模式时,只有 N-MOS 管工作。控制输出为低电平(0)时,P-MOS 管关闭,N-MOS 管导通,使输出低电平,I/O 端口的电平就是低电平;控制输出为高电平(1)时,P-MOS 管和 N-MOS 管都关闭,输出指令不起作用,此时 I/O 端口的电平由 I/O 端口外部的上拉或者下拉决定,如果没有上拉或者下拉,I/O 口就处于悬空状态。

开漏模式下P_Mos恒断开,只能控制N-Mos。

光听理论有点抽象,来个图片看看:

 其中Vdd是电源,Vss是地。图上我们把 P-MOS和N-MOS管当做开关使用。

通用:

这是 GPIO 引脚最基本的功能,即作为普通的输入或输出引脚使用。例如,可以将某个 GPIO 引脚配置为输出,直接控制其输出高电平或低电平来驱动 LED 灯;或者配置为输入,读取外部按键的状态。

在通用功能模式下,引脚的输入输出电平完全由用户程序直接控制,不涉及片上的其他外设模块。

复用:

当 GPIO 引脚被配置为复用功能时,该引脚不再单纯地作为普通的输入输出,而是与 STM32 内部的特定外设模块相关联。例如,某些 GPIO 引脚可以复用为 USART(通用同步异步收发器)的发送或接收引脚、SPI(串行外设接口)的数据引脚、I2C(集成电路互联总线)的 SCL(时钟线)或 SDA(数据线)等。

在复用功能模式下,引脚的输入输出电平由相应的外设模块控制,而不是由用户直接通过程序简单地设置。

小结:通用功能是 GPIO 引脚的基本用途,而复用功能则是将 GPIO 引脚与片上的特定外设模块相结合,以实现更丰富和复杂的功能。

IO端口位的基本结构

① 保护二极管(要在之前加限流电阻,否则有可能被击穿)
② 内部上拉、下拉电阻

为什么要有上下拉电阻呢?

答:在电路中设置上下拉电阻主要有以下几个原因:

1. 确定默认电平:当输入引脚悬空(未连接到任何信号源)时,上拉电阻可以将引脚的电平拉至高电平,下拉电阻则可以将其拉至低电平。这样可以确保在没有明确输入信号的情况下,引脚有一个确定的默认状态,避免出现不确定的电平状态导致电路逻辑错误。

2. 提高抗干扰能力上下拉电阻可以减小输入引脚受到外界噪声干扰的影响。例如,当有短暂的噪声脉冲出现时,由于电阻的存在,噪声可能无法改变引脚的电平状态,从而增强了电路的稳定性。

3. 增加驱动能力:在某些情况下,输出引脚连接的负载较重,通过添加上拉或下拉电阻,可以提高引脚的驱动能力,确保输出信号的强度和稳定性。

4. 实现线与逻辑在多个器件的输出连接在一起的情况下(如开漏输出模式),使用下拉电阻可以实现“线与”逻辑,即只有当所有输出都为低电平时,总线才为低电平。

5. 兼容不同电平标准在一些混合电平的电路中,上下拉电阻可以帮助引脚适应不同的电平要求。 例如,在一个基于 STM32 的电路中,对于一些用于检测外部设备状态的输入引脚,如果外部设备未连接或处于断开状态,上拉电阻可以确保引脚读取到的是高电平,从而避免误判。

 综上所述,上下拉电阻在电路设计中起着重要的作用,有助于提高电路的可靠性、稳定性和逻辑正确性。

③ 施密特触发器

  • 施密特触发器输入模式
    • 当一个GPIO引脚被配置为施密特触发器输入模式时,可以设置两个阈值:上升和下降的触发电压水平。
    • 对于输入信号来说,只有当信号超过上升触发电压时,输出从低变高;当信号下降到下降触发电压以下时,输出从高变低。
    • 这种特性使得施密特触发器能够在输入信号的幅度小于噪声的情况下,稳定地输出一个明确的高或低电平。

如果觉得抽象请看图:

④ P-MOS & N-MOS管

三、GPIO的配置 

GPIO(通用输入/输出)的配置包括以下几个主要方面:

  1. 工作模式选择

  • 输入模式:包括浮空输入、上拉输入、下拉输入和模拟输入。
    • 浮空输入:引脚电平由外部电路决定,可能处于不确定状态。
    • 上拉输入:内部有上拉电阻,无输入时默认高电平。
    • 下拉输入:内部有下拉电阻,无输入时默认低电平。
    • 模拟输入:用于连接 ADC 进行模拟信号采集。
  • 输出模式:包括推挽输出、复用推挽输出、开漏输出和复用开漏输出。
    • 推挽输出:可输出强高电平和强低电平。
    • 复用推挽输出:通过片上外设功能输出。
    • 开漏输出:需要外接上拉电阻实现高电平输出。
    • 复用开漏输出:通过片上外设功能实现开漏输出。

        2.输出速度配置

                可选择低速、中速和高速。不同的速度会影响输出信号的上升和下降时间,以及功耗和电磁兼容性。

        3.引脚复用功能选择

                当需要将 GPIO 引脚用于特定的外设功能(如 UART、SPI 等)时,需要配置为相应的复用功能。

        4.上下拉电阻配置

                决定是否启用内部的上拉或下拉电阻,以确定引脚在无输入时的默认电平。

例如,如果要将 PA0 配置为上拉输入模式,可以使用如下代码(假设使用 STM32 的标准库):

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  // 使能 GPIOA 端口时钟

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  // 选择 PA0 引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // 配置为上拉输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  // 配置速度(可根据需求调整)
GPIO_Init(GPIOA, &GPIO_InitStructure);  // 初始化 GPIOA

四、相关函数和寄存器

1.GPIO相关函数
         在STM32中,通常使用库函数来配置和操作GPIO引脚。这些函数位于不同的头文件中,主要包括stm32f1xx_gpio.h(以STM32F1系列为例)。

GPIO初始化函数

 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

这是用来初始化GPIO端口的函数,其中:

GPIOx:表示具体的GPIO端口,如GPIOA、GPIOB等。
GPIO_InitStruct:是一个结构体,用于配置GPIO的各种参数,如引脚编号、模式、输出类型、输出速度、上拉/下拉等。

GPIO设置函数:

  void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
  void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

这些函数分别用于设置GPIO引脚输出为高电平(Set)或低电平(Reset)。

读取输入状态:

  uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
  uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

这些函数用于读取指定GPIO引脚的输入状态,可以读取单个引脚状态或整个端口的状态。


2.GPIO配置结构体
在使用GPIO初始化函数时,需要填充一个结构体 GPIO_InitTypeDef,它定义在stm32f1xx_gpio.h中,主要包括以下字段:

typedef struct
{
  uint16_t GPIO_Pin;             /*!<指定要配置的GPIO引脚。

该参数可以是@ref GPIO_pins_define的任意值 */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< 指定所选引脚的速度。
该参数可以是@ref GPIOSpeed_TypeDef的值 */

  GPIOMode_TypeDef GPIO_Mode;    /*!< 指定所选引脚的工作模式。
该参数可以是@ref GPIOMode_TypeDef的值 */
}GPIO_InitTypeDef;

3. GPIO寄存器

STM32微控制器的GPIO(General Purpose Input/Output)模块包含了多个寄存器,用于配置和控制GPIO引脚的行为。以下是一些STM32 GPIO最常用的寄存器及其用途:

1. GPIOx_MODER (Mode Register)
   - 用于设置GPIO引脚的工作模式,如输入浮空、上拉/下拉输入、输出推挽或开漏、复用功能等。

2. GPIOx_OTYPER (Output Type Register)
   - 用于配置输出引脚的类型,推挽(Push-Pull)或开漏(Open Drain)。

3. GPIOx_OSPEEDR (Output Speed Register)
   - 控制输出引脚的驱动速度,低速、中速、高速或极高。

4. GPIOx_PUPDR (Pull-up/Pull-down Register)
   - 配置输入引脚的上拉或下拉电阻。

5. GPIOx_IDR (Input Data Register)
   - 此寄存器反映了GPIO引脚的当前输入状态。

6. GPIOx_ODR (Output Data Register)
   - 直接写入此寄存器可更改GPIO输出引脚的状态。

7. GPIOx_BSRR (Bit Set/Reset Register)**
   - 快速设置或复位GPIO输出引脚的状态,无需读取整个ODR寄存器。

8. GPIOx_BRR (Bit Reset Register)
   - 专门用于复位(清零)GPIO输出引脚的状态。

9. GPIOx_LCKR (Lock Register)
   - 用于锁定GPIO配置,防止配置被意外修改。

10. GPIOx_AFRx (Alternate Function Selection Register)
    - 当GPIO引脚被配置为复用功能时,用于选择具体的功能。

寄存器地址和字段说明补充:地址 = 基地址 + 偏移地址
以`GPIOA`为例,假设STM32的GPIOA基地址为`0x40020000`,那么寄存器的地址如下:

- `MODER`: `0x40020000 + 0x00`
- `OTYPER`: `0x40020000 + 0x04`
- `OSPEEDR`: `0x40020000 + 0x08`
- `PUPDR`: `0x40020000 + 0x0C`
- `IDR`: `0x40020000 + 0x10`
- `ODR`: `0x40020000 + 0x14`
- `BSRR`: `0x40020000 + 0x18`
- `BRR`: `0x40020000 + 0x1C`
- `LCKR`: `0x40020000 + 0x20`

- `AFR`: 分为`AFRL`和`AFRH`两个寄存器,`AFRL`位于`0x40020000 + 0x24`,`AFRH`位于`0x40020000 + 0x28`

 字段位操作
每个寄存器中的字段对应着不同的GPIO引脚。例如,在`MODER`寄存器中,第`n`位和`n+1`位组合控制着`GPIO_Pin_n`的模式。每个字段通常由几个比特位组成,用于表示不同的配置选项。

  • 18
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值