STM32外设-GPIO输出(不含复用)
GPIO(通用输入/输出口)是微控制器上可以由用户自定义控制的引脚
一,GPIO模式简介
1,输入模式
将引脚配置为输入模式,用于读取外部信号。
适用场景:读取按钮状态、传感器信号等
2,输出模式
将引脚配置为输出模式,用于驱动外部设备或信号。
适用场景:LED控制、电机驱动等
3,模拟模式
将引脚配置为模拟模式,用于模拟信号输入或输出。
适用场景:ADC读取、DAC输出等
4,复用模式
将引脚配置给某个外设的使用,如UART、SPI或I2C等。
适用场景:通信接口、定时器输出等
二,输出模式详解
1, 输出类型
共有两种输出类型:推挽输出模式和开漏输出模式,先讲一下电路原理
1,推挽输出:
下图是STM32引脚电路原理图,右边两个二极管只起 保护作用,暂时省略
我们通过HAL库的API接口函数对寄存器写入0/1,从而控制P-MOS和N-MOS的截止,达到输出高低电平的目的:
当P-MOS导通,N-MOS截止时,N-MOS处是断路,上面VDD和P-MOS处是短路,测出引脚电压为VDD(将电流推出去)
(其实VDD和P-MOS有阻抗,但是直接测引脚电压就相当于测的是内阻的电压,没有其他电阻分压测出来就是VDD)
如果此时在引脚处接一个LED,LED会被点亮
当P-MOS截止,N-MOS导通时,P-MOS处是断路,上面N-MOS处是短路,此时引脚输出低电平(将电流挽进来)
2,开漏输出
开漏输出可以输出低电平和高阻态,开漏输出时P-MOS永远截止,输出哪个状态取决于N-MOS的截止和导通(为什么叫开漏?N-MOS管的漏极的开与关决定了开漏模式的输出)
当N-MOS导通时,开漏输出与推挽输出一致,输出低电平
而当N-MOS截止时,输出的是高阻态,为什么输出的是高阻态?
了解高阻态的定义:引脚与电源和地之间呈现高电阻状态,即高阻态。此时输出引脚不对外提供确定电平信号,其电平由外部电路决定。
那高阻态有什么作用呢?
作用1:改变芯片输出的电平。如下图,STM32引脚输出3.3V,但我想让其输出5V,可以在引脚外接一个上拉电阻1(假设为10K),根据分压原理,N-MOS阻值无穷大,绿点处是5V
作用2:利用高阻态的线与特性
线与:即只有当所有连接在一起的输出端口都输出高电平时,总的输出才为高电平;只要有一个输出端口为低电平,总的输出就是低电平 。
线或:只要连接的输出端口中有一个输出高电平,总的输出就为高电平;只有当所有输出端口都为低电平时,总的输出才是低电平 。
如下图,两个芯片外接一个上拉电阻,只有当两个引脚同时为高阻态时,才能输出高电平,有一个引脚输出低电平就输出低电平
若 GPIO 配置为开漏输出模式,默认就是高阻态状。开漏输出下,N-MOS 管用于控制输出,无外部上拉电阻时,N-MOS 管截止就会呈现高阻态 。 此外,当复用功能输出信号未有效驱动、相关寄存器配置错误,或芯片处于特定低功耗模式影响 GPIO 驱动电路时,也可能使输出进入高阻态。
-
推挽输出模式 (Push-Pull)
功能:可以驱动高电平(逻辑1)和低电平(逻辑0)
工作原理:有两个晶体管配置,一个用于拉高电平,一个用于拉低电平
优点:驱动能力强,适用于大多数数字输出应用
缺点:高频切换时可能导致较大功耗和信号干扰
应用示例:LED控制、开关控制、信号输出 -
开漏输出模式 (Open-Drain)
功能:只能拉低电平(逻辑0),高电平由外部上拉电阻提供
工作原理:只有一个下拉晶体管,高电平依赖外部上拉电阻
优点:支持多路信号线"线与"逻辑,适合共享总线
缺点:无法直接驱动高电平,需要外部电阻
应用示例:I2C总线、外部信号线共享 -
推挽输出 vs 开漏输出
特性 | 推挽输出 | 开漏输出 |
---|---|---|
高电平驱动 | ✓ 内部提供 | ✗ 需要外部上拉 |
低电平驱动 | ✓ 内部提供 | ✓ 内部提供 |
多设备共享总线如iic总线 | ✗ 不适合 | ✓ 适合 |
电流驱动能力 | ✓ 较强 | ⚠ 取决于上拉电阻 |
LED控制适用性 | ✓ 非常适合 | ⚠ 需要外部上拉 |
相对于51单片机只有输出0和1两种情况,STM32输出变复杂有什么好处?
2,输出速度
先来解释一下什么是输出驱动电路带宽和不失真信号:
输出驱动电路带宽:指输出驱动电路能够不失真地传输信号的频率范围,单位通常是赫兹(Hz) 即范围。也就是说,带宽越大,电路能够承受的信号频率越大,能传输的信号频率越高,信号的变化速度就可以越快。
不失真信号:信号传输时,不发生变化的信号。
举个例子:cpu执行程序先输出高电平,在输出低电平,最后输出高电平,如果信号变化很快,超出了IO的带宽,IO在输出高低高时,可能会发生:先输出高,本该变成低时没有反应过来,此时CPU又让IO输出高,整体来看,IO是一直输出高电平,发生了信号失真
GPIO 输出驱动电路主要由晶体管(通常是 MOS 管)构成,通过控制这些晶体管的导通和截止来实现信号的输出
那么STM32是如何控制输出高速信号和低速信号的呢?
有一个思路是更改高速晶体管和低速晶体管,但实际上是:改变晶体管导通和截止的速度。
-
低速 (Low Speed) 对应2-10MHz
特性:输出驱动电路带宽低,能通过的不失真信号最大频率低 。信号电平转换相对慢,功耗小、噪声低,产生的电磁干扰(EMI)2也较小
适用场景:按键、LED控制等低频应用 -
中速 (Medium Speed) 对应10-50MHz
特性:输出驱动电路带宽适中,信号电平转换速度适中。
适用场景:一般通信接口、显示驱动等 -
高速 (High Speed) 对应50-100MHz
特性:输出驱动电路带宽高,能通过高频信号,信号电平转换速度快。
适用场景:高速总线、快速数据传输等 -
超高速 (Very High Speed) 对应100MHz+
特性:输出驱动电路带宽更高,信号电平转换迅速。
适用场景:高速存储器接口、高速数据采集等
注意
更高的速度会导致:
更多的功耗
更大的电磁干扰(EMI)
更快的信号上升和下降时间
对于LED控制这类应用,通常选择低速即可,这能降低功耗并减少EMI。
因此,在实际应用中,需要根据具体的需求来合理选择 GPIO 的输出速度,在速度、功耗和 EMI 之间找到一个平衡点。
三,GPIO配置选项
再用STM32CubeMX配置GPIO引脚时,需要对下图红框的配置选项进行配置,下面我将将所有的配置选择都介绍一下
- GPIO Mode (GPIO模式)
决定引脚的基本工作方式,是STM32CubeMX中最基础的配置项。
Input Mode (输入模式) | Output Mode (输出模式) | Analog Mode (模拟模式) | Alternate Function (复用功能) |
---|---|---|---|
配置引脚为输入,用于读取外部信号 | 配置引脚为输出,用于控制外部设备 | 配置引脚为模拟模式,用于ADC/DAC | 连接内部外设如UART/SPI/I2C等 |
配置提示: 对于LED控制,通常选择Output Mode。如果需要通过PWM控制LED亮度,则选择Alternate Function并连接到定时器。
- GPIO Output Type (输出类型)
当GPIO配置为输出模式时,可以选择不同的输出类型。
Push-Pull (推挽输出) | Open-Drain (开漏输出) |
---|---|
可以主动输出高电平和低电平,驱动能力强。 | 只能主动输出低电平,高电平需要外部上拉电阻。 |
高电平:主动拉高 低电平:主动拉低 | 高电平:依靠外部上拉 低电平:主动拉低 |
LED控制 数字信号输出 | I2C总线 多设备共享总线 |
配置提示: 对于一般的LED控制,选择Push-Pull输出类型。对于需要共享总线的场景(如I2C),选择Open-Drain输出类型。
- GPIO Speed (输出速度)
决定GPIO引脚状态切换的速率和驱动能力。更高的速度设置意味着更快的电平切换速率和更强的电流驱动能力。
速度设置 | 最大频率 | 适用场景 |
---|---|---|
Low (低速) | ~2MHz | 低功耗应用、LED指示灯 |
Medium (中速) | ~10MHz | 一般数字接口、按键控制 |
High (高速) | ~50MHz | SPI通信、快速信号处理 |
Very High (超高速) | ~100MHz+ | 高速通信接口、时钟信号 |
配置提示: 对于普通LED控制,选择Low速度即可。更高的速度会增加功耗和电磁干扰,除非应用需要,否则不要选择过高的速度设置。
- GPIO Pull-up/Pull-down (内部的上拉/下拉电阻)
决定GPIO引脚在未被驱动时的默认状态。
No Pull-up/Pull-down | Pull-up (上拉) | Pull-down (下拉) |
---|---|---|
不启用内部上拉/下拉电阻,引脚浮空。 | 启用内部上拉电阻,引脚默认为高电平。 | 启用内部下拉电阻,引脚默认为低电平。 |
模拟输入 外部已有定义电平 | 按键检测 I2C总线 | 上拉型开关检测 默认低电平信号 |
- GPIO Label (引脚标签)
为GPIO引脚指定一个有意义的名称,方便在代码中引用。
命名规范:
使用有描述性的名称,如 LED_GREEN、BUTTON_USER
避免使用特殊字符,使用下划线分隔单词
保持命名一致性,便于代码维护
命名示例:
功能 | 推荐标签名 |
---|---|
LED指示灯 | LED_RED, LED_GREEN, LED1, LED2 |
按键输入 | BUTTON_USER, KEY1, KEY2 |
传感器控制 | SENSOR_ENABLE, TEMP_ALERT |
配置提示: 合理命名GPIO引脚可以大大提高代码的可读性和可维护性。CubeMX会根据标签名自动生成相应的宏定义,方便在代码中使用。
- GPIO Signal (引脚信号)
STM32的每个GPIO引脚通常可以复用为多个不同的外设信号。例如,一个引脚可能既可以作为USART1的TX,也可以作为TIM2的通道3,还可以作为SPI3的MOSI。那么如何在CubeMX中实现GPIO引脚复用呢?
首先将GPIO配置为复用功能(Alternate Function)模式,“Signal” 选项用于指定该引脚连接到STM32内部的哪个外设的哪个具体信号。
然后通过在CubeMX的"Signal"下拉列表中选择,或者直接在代码中配置GPIO的 Alternate 字段(使用HAL库时),可以决定该引脚当前连接到哪个外设信号。
最后提供一些常见的复用功能信号类型:
TIM1_CH1 (定时器通道)
USART1_TX (串口发送)
USART1_RX (串口接收)
SPI1_SCK (SPI时钟)
SPI1_MISO (SPI主入从出)
SPI1_MOSI (SPI主出从入)
I2C1_SCL (I2C时钟线)
I2C1_SDA (I2C数据线)
ADC1_IN0 (ADC输入通道)
DAC1_OUT1 (DAC输出通道)
TIMx_CHx (定时器通道)
TIMx_ETR (外部触发)
TIMx_BKIN (刹车输入)
USARTx_TX (串口发送)
USARTx_RX (串口接收)
USARTx_CK (同步时钟)
USARTx_CTS (流控)
USARTx_RTS (流控)
I2Cx_SCL (I2C时钟)
I2Cx_SDA (I2C数据)
SPIx_SCK (SPI时钟)
SPIx_MISO (主入从出)
SPIx_MOSI (主出从入)
SPIx_NSS (片选)
I2Sx_CK (I2S时钟)
I2Sx_WS (字选)
I2Sx_SD (串行数据)
CANx_TX (CAN发送)
CANx_RX (CAN接收)
USB_OTG_FS/HS_…
ETH_… (以太网)
SDMMCx_… (SD卡)
QUADSPI_… (QSPI)
SYS_… (系统功能, 如SWD, JTAG)
RCC_… (时钟输出, 如MCO)
EVENTOUT (事件输出)
LED控制相关的信号类型:
TIMx_CHx - 定时器PWM输出通道,用于控制LED亮度
GPIO_Output - 普通GPIO输出,用于简单的LED开关控制
配置示例:通过PWM实现LED亮度控制或呼吸灯效果:
将目标GPIO引脚的模式设置为 Alternate Function Push-Pull (通常推挽输出效果更好)。
在 “Signal” 下拉列表中,选择一个可用的 TIMx_CHx (定时器通道) 信号。
转到对应的 TIMx 外设配置界面。
配置定时器的时钟源和预分频器(Prescaler)、自动重载寄存器(ARR)以设定PWM频率。
启用所选的 Channel x,并将其模式设置为 PWM Generation CHx。
配置比较寄存器(CCR / Pulse)的值来控制PWM占空比,从而控制LED亮度。
重要提示:务必查阅STM32芯片的数据手册(查找 “Alternate function mapping” 相关表格),确认所选引脚支持你想要连接的定时器通道。并非所有引脚都支持所有定时器的所有通道。
四,STM32 HAL库GPIO配置
STM32 HAL(Hardware Abstraction Layer,硬件抽象层)库提供了一套完整的API来配置和控制GPIO引脚。相比直接操作寄存器,HAL库更易用且可移植性更好。
1,GPIO初始化结构体
HAL库使用GPIO_InitTypeDef结构体来配置GPIO引脚:
Pin: 要配置的引脚,如GPIO_PIN_0, GPIO_PIN_1等
Mode: 引脚模式,如GPIO_MODE_OUTPUT_PP(推挽输出)
Pull: 上拉/下拉设置,如GPIO_NOPULL, GPIO_PULLUP等
Speed: 输出速度,如GPIO_SPEED_FREQ_LOW
Alternate: 复用功能选择(仅在复用模式下使用)
2,引脚复用机制
STM32微控制器的GPIO引脚可以分配给不同的外设功能,这称为引脚复用(Alternate Function):
每个引脚可以有多达16个不同的复用功能(AF0-AF15)
例如,同一个引脚可以配置为UART发送、SPI时钟或I2C数据线
复用功能在芯片手册中有详细说明,不同系列和型号的STM32有所不同
使用GPIO_MODE_AF_PP或GPIO_MODE_AF_OD模式并设置相应的AF值
3,GPIO时钟使能
在STM32中,使用任何外设前都必须使能其时钟:
使用__HAL_RCC_GPIOx_CLK_ENABLE()宏来使能GPIO端口时钟
这一步骤在配置GPIO前必须完成,否则配置无效
不同的GPIO端口(GPIOA, GPIOB等)需要单独使能
4,GPIO操作函数
HAL库提供了多种操作GPIO的函数:
HAL_GPIO_WritePin(): 设置引脚输出高/低电平
HAL_GPIO_ReadPin(): 读取引脚输入状态
HAL_GPIO_TogglePin(): 翻转引脚状态
HAL_GPIO_LockPin(): 锁定引脚配置
HAL_GPIO_EXTI_IRQHandler(): 中断处理
这些函数屏蔽了底层寄存器操作的复杂性,使得代码更清晰易读。
什么是上拉电阻?什么是下拉电阻
一,上拉电阻和下拉电阻的概念
下图中,单片机引脚输出5V高电平,什么都不接的情况下,测试为5V
但接了一个下拉电阻后,输出3.8V:原因是单片机内部P-MOS含有阻抗,对5V进行了分压
在此基础上,再接一个上拉电阻,输出变成了4.2V:原因是外部电阻和P-MOS的阻抗并联,总阻抗减小,输出有升高了0.4V
二,上拉电阻的作用:将高阻态钳位在高电平
开漏输出高阻态时,单片机内部两个MOS截止,阻抗无穷大,此时在外部接一个上拉电阻(10K),它与P-MOS并联后总阻值约为10K,和N-MOS相比几乎不分电压,最终输出5V
↩︎
电磁兼容性(EMC)和电磁干扰(EMI)
电磁兼容性(EMC)
定义:设备或系统在其电磁环境中能正常工作,且不对该环境中其他设备产生难以承受的电磁干扰的能力 。
原理:通过合理的电路设计(如滤波、屏蔽 )、接地处理等措施,减少自身产生的电磁干扰,同时增强对外部电磁干扰的抵抗能力。
作用:保证多个电子设备在同一环境中能互不干扰、稳定运行,提高整个系统的可靠性。
电磁干扰(EMI)
定义:由电磁场引起的对电子设备、电气设备或电磁设备的有害影响 。可分为传导干扰(通过导电介质传播 )和辐射干扰(通过空间以电磁波形式传播 )。
原理:电子设备工作时,内部的电流变化、信号传输等会产生电磁波,若不加以抑制,就会干扰其他设备。
作用:会造成信号失真、设备误动作等问题,影响设备正常工作,所以在电子产品设计中要采取措施抑制 EMI。 ↩︎