2. 硬件接口基础:GPIO、UART、I2C、SPI的电气特性与协议基础
做嵌入式控制算法调试,说白了就是跟芯片的“手脚”打交道。GPIO、UART、I2C、SPI 这四个接口,我几乎每天都在用。它们就像工程师的“五官”——看状态、听数据、摸传感器、说指令,全靠它们。
很多新手一上来就写代码,结果板子不工作,查半天发现是电平没对上,或者时序差了几个微秒。嗯,这里咱们先把底层的电气特性和协议基础捋清楚。
2.1 GPIO:最基础的“开关”与“眼睛”
GPIO(通用输入输出)是嵌入式系统里最简单的接口,但也是最容易出坑的地方。我个人习惯,拿到一块新板子,第一件事就是点个灯——确认 GPIO 能正常拉高拉低。
2.1.1 电气特性
- 输出模式:推挽输出(Push-Pull)和开漏输出(Open-Drain)。推挽输出能主动拉高拉低,驱动能力强;开漏输出只能拉低,高电平要靠外部上拉电阻。
- 输入模式:浮空输入、上拉输入、下拉输入。浮空输入电平不确定,我建议除非有外部驱动,否则别用。
- 电压阈值:TTL 电平(5V)和 CMOS 电平(3.3V/1.8V)的阈值不同。比如 3.3V 的 CMOS,高电平阈值是 0.7×VDD ≈ 2.31V,低电平是 0.3×VDD ≈ 0.99V。
2.1.2 常见应用场景
| 场景 | 模式 | 注意事项 |
|---|---|---|
| LED 控制 | 推挽输出 | 限流电阻不能省 |
| 按键检测 | 上拉输入 | 软件去抖,硬件加电容更好 |
| I2C 总线 | 开漏输出 | 必须配上拉电阻 |
| 中断触发 | 输入+中断 | 边沿触发还是电平触发?看信号质量 |
2.2 UART:最经典的“串口对话”
UART(通用异步收发器)是我调试时最依赖的接口。没有它,很多问题根本不知道从哪里下手。你想想看,一个 printf 就能把变量值打出来,多方便。
2.2.1 电气特性
- 电平标准:TTL 电平(0~3.3V/5V)和 RS-232 电平(-12V~+12V)。两者不能直连,需要 MAX232 之类的芯片转换。
- 波特率:常见的有 9600、115200、921600。波特率误差超过 ±2% 就会丢数据。我遇到过因为晶振不准导致通信失败的案例,后来改用内部 RC 振荡器时都会先测实际频率。
- 数据格式:起始位(1位)+ 数据位(5~8位)+ 校验位(可选)+ 停止位(1~2位)。
2.2.2 协议基础
UART 是异步通信,没有时钟线。收发双方靠约定的波特率来同步。发送时,数据从 LSB(最低有效位)开始,依次发送。接收端在起始位下降沿后,按波特率采样。
// 典型的 UART 初始化代码(STM32 HAL 库)
UART_HandleTypeDef huart2;
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
HAL_UART_Init(&huart2);
2.3 I2C:多设备共享的“两线总线”
I2C(Inter-Integrated Circuit)只有两根线:SCL(时钟)和 SDA(数据)。它支持多主多从,但实际项目中我很少用多主,太容易冲突了。
2.3.1 电气特性
- 开漏输出:SCL 和 SDA 都是开漏结构,必须外接上拉电阻(通常 4.7kΩ~10kΩ)。
- 速率模式:标准模式(100kHz)、快速模式(400kHz)、高速模式(3.4MHz)。总线电容会影响速率,线太长或设备太多时,要降低频率。
- 地址冲突:每个设备有 7 位或 10 位地址。我遇到过两个传感器地址一样,结果总线一直报错。后来我用了地址转换芯片才解决。
2.3.2 协议基础
I2C 的通信流程很清晰:起始条件(SCL 高时 SDA 下降沿)→ 发送从机地址 + 读写位 → 从机应答(ACK)→ 数据字节(每字节后跟 ACK)→ 停止条件(SCL 高时 SDA 上升沿)。
2.4 SPI:高速全双工的“四线通信”
SPI(串行外设接口)比 I2C 快得多,而且支持全双工。它需要四根线:SCLK(时钟)、MOSI(主出从入)、MISO(主入从出)、CS(片选)。
2.4.1 电气特性
- 推挽输出:SCLK、MOSI、CS 都是推挽结构,驱动能力强,速率可以跑到几十 MHz。
- 电平匹配:主设备和从设备的电平必须一致。我试过 3.3V 的主机接 5V 的从机,结果 MISO 引脚被烧了。后来加了电平转换芯片。
- 时钟极性(CPOL)和相位(CPHA):有四种模式(Mode 0~3)。主从必须匹配,否则数据会错位。
2.4.2 协议基础
SPI 的通信由主机控制。主机拉低 CS 选中从机,然后产生时钟信号。每个时钟周期,主机通过 MOSI 发送一位,同时从机通过 MISO 返回一位。传输完成后,主机拉高 CS。
| SPI 模式 | CPOL | CPHA | 数据采样边沿 |
|---|---|---|---|
| Mode 0 | 0 | 0 | 上升沿采样 |
| Mode 1 | 0 | 1 | 下降沿采样 |
| Mode 2 | 1 | 0 | 下降沿采样 |
| Mode 3 | 1 | 1 | 上升沿采样 |
2.5 四种接口对比与选型建议
在实际项目中,选哪个接口不是拍脑袋决定的。我一般会从这几个维度考虑:
- 速度需求:SPI > UART > I2C > GPIO(模拟)。
- 引脚数量:GPIO(1 根)< UART(2 根)< I2C(2 根)< SPI(4 根)。
- 设备数量:I2C(多设备,地址区分)> SPI(多设备,片选区分)> UART(点对点)。
- 抗干扰能力:差分信号(如 RS-485)> 单端信号(如 UART TTL)。
2.6 知识体系总览
下面这张图把四种接口的核心要素串起来了。你可以把它当作调试时的“速查地图”。
好了,这一章的内容就到这里。记住,硬件接口是嵌入式系统的“骨架”,协议是“血液”。只有把这两样搞清楚了,后面的控制算法调试才能有的放矢。