什么是GPIO?
General Purpose Input Output,即通用输入输出端口,简称GPIO
作用:负责采集外部器件的信息或者控制外部器件工作,即输入输出
GPIO简介
特点:
- 不同型号的芯片,GPIO的数量可能会不同
- 快速翻转,每次翻转最快只需要两个时钟周期
- 每个IO口都可以做中断
- 支持八种工作模式
- STM32工作电压: 2V < VDD < 3.6V
- 单个IO口,最大25mA
GPIO电压识别范围 :
CMOS端口: - 0.3V < VIL < 1.64V ;1.833V < VIH < 3.6V
TTL(FT/TC)端口:0V < VIL < 0.8V;2V< VIH < 5V
引脚分布
我们的NANO板子除去一些电源引脚、晶振引脚、复位引脚、
下载引脚、BOOT引脚,一共还剩下51个IO口,为:GPIOA ~ GPIOC、 PD0 ~ PD2
GPIO端口基本结构介绍
GPIO结构分析
施密特触发器
施密特触发器是一种整型电路,其作用是将非标准方波整型为方波。其本质为反向滞回比较器
作用:减少模拟信号的抖动(干扰),导致读取的电平不稳定
特点:
当输入电压高于正向阈值电压,输出为高;
当输入电压低于负向阈值电压,输出为低;
当输入在正负向阈值电压之间,输出不改变
MOS管
MOS管是压控型元件,通过控制栅源电压( Vgs )来实现导通或关闭
由于MOS管导通时电阻很小,因此输出的电流很大(可以到达25mA),具有较强的驱动能力,
上下拉电阻及保护二极管
设置上下拉电阻可以使IO口的初始电压为高/低电平。
保护二极管可以IO口,防止外界电压过高导致IO口被烧毁。
GPIO八种工作模式
上图是GPIO的八种工作模式,下面我们来一一分析:
浮空输入
特点:
- 上下拉电阻都不使用,输出回路关闭(MOS管不导通),施密特触发器开启。
- 空闲时IO口电平不稳定,由外部环境决定
- 初始电平不确定。
这一种输入模式的电平会完全取决于外部电路而与内部电路无关
上拉输入
特点:
- 上拉电阻开启,下拉电阻关闭,输出回路关闭(MOS管不导通),施密特触发器开启
- 空闲时IO口电平为高电平,初始电平为高电平
上拉输入的好处就是输入的电平不会上下浮动而导致输入信号不稳定,在没有信号输入的情况下可以稳定在高电平。
下拉输入
特点:
- 上拉电阻关闭,下拉电阻开启,输出回路关闭(MOS管不导通),施密特触发器开启
- 空闲时IO口电平为低电平,初始电平为低电平
下拉输入的好处就是输入的电平不会上下浮动而导致输入信号不稳定,在没有信号输入的情况下可以稳定在低电平。
模拟输入
特点:
- 上拉电阻关闭,下拉电阻关闭,输出回路关闭(MOS管不导通),施密特触发器关闭
- 专门用于模拟信号输入,读取对应引脚上的电压,用作电压采集,ADC/DAC
- 空闲时IO口电平不稳定,由外部环境决定 ,初始电平不确定。
可以让AD读取电压。还可以在低功耗模式下运行,实现省电的作用。
开漏输出
特点:
- 上拉电阻关闭,下拉电阻关闭,输出回路开启(P-MOS关闭,N-MOS打开或关闭),施密特触发器打开
- 当N-MOS管打开是,输出为低电平,关闭时,输出不确定
- 开漏输出只能输出低电平,当需要输出高电平时,需外额外接上拉电阻(也可以通过控制寄存器控制上拉电阻开启)。
注意:上图中有一个点需要纠正,开漏输出情况下,施密特触发器时开启的 ,关于为什么要开启,我也不太明白,不然我也不会画错了…………
开漏输出的优点:
- 开漏输出实质上是使用N-MOS管漏极输出,叫做OC门,它有一个重要的作用就是实现线与的功能,只要一个是低电平,那么所有连接到一起的OC门就是低电平,典型的应用就是IIC协议中的SDA和SCL线,当一个输出为低电平时,总线的电平就会被拉低。
- 开漏输出只能输出地点平,如果需要输出高低平。则需要外接一个上拉电阻,我们可以通过改变外接电阻的VDD,使得IO口上输出我们需要的电平(VDD可调)。
开漏式复用功能
特点:
- 上拉电阻和下拉电阻关闭,P-MOS管始终关闭,施密特触发器开启
- 不能输出高电平,需要外届上拉电阻才能输出高电平
- 由其他外设控制输出
推挽输出
特点
- 上拉电阻和下拉电阻关闭,施密特触发器开启,MOS管一个导通时另一个关闭
- P-MOS导通时输出高电平,N-MOS导通时输出低电平
- 可以输出高低电平,驱动能力强
推挽式复用功能
特点
- 上拉电阻和下拉电阻关闭,施密特触发器开启,MOS管一个导通时另一个关闭
- P-MOS导通时输出高电平,N-MOS导通时输出低电平
- 可以输出高低电平,驱动能力强
- 由其他外设控制输出
注意: F1在输出模式下,禁止使用内部上下拉电阻。而 F4/F7/H7在输出模式,可以使用内部上下拉
GPIO寄存器
概览
下面是STM32中GPIO的相关寄存器,由于我们使用的是F411的板子,所以我们重点讲下面一栏
端口模式寄存器(MODER)
GPIO-MODER用于控制IO方向(输入、输出、AF(复用)、模拟)。
端口输出类型寄存器(OTYPER)
端口输出速度寄存器(OSPEEDR)
注意:此寄存器只在输出模式下配置有效,输入模式下无效。
端口上拉/下拉寄存器(PUPDR)
端口输入数据寄存器(IDR)
注意:这个寄存器是只读寄存器
端口输出数据寄存器(ODR)
端口置位/复位寄存器(BSRR)
往高16位写1,ODR寄存器对应位置为0
往低16位写1,ODR寄存器对应位置为1
往BSRR寄存器写入0,ODR寄存器不改变
8种工作模式对应的配置– F4/F7/H7
建议通过BSRR寄存器来操作ODR寄存器,因为在直接对ODR寄存器进行操作,在读和访问之间产生中断,可能会产生风险,导致输出异常,使用BSRR则不会有此风险。
8种工作模式对应的配置– F1
通用外设驱动方法
GPIO配置步骤
其中:
HAL_GPIO_WritePin() 操作的是BSRR寄存器,
HAL_GPIO_TogglePin()操作的是ODR寄存器。
GPIO结构体
以上就是GPIO部分全部的理论知识,下面我们开始实战:点亮一个LED,实现一个简单的流水灯。
实战1——实现流水灯
原理图分析
在我们的NANO板子上一共有八个LED,分别对应IO口为PC0~PC7,因此我们要实现流水灯,只需要依次把LED0 ~ LED7写入低电平即可,设置GPIO为推挽输出。
CubeMX配置
因为我们需要写的是流水灯,同一时间只需要一个LED亮,其他七个为灭,所以选择初始电平为高电平,设置为上拉。
关于CubeMX的其他配置部分,大家可以参考之前的“ CubeMX入门系列 ” 这里不做赘述。
代码实现
关于流水灯的原理,我也是不做介绍,大家都知道的。