2、硬件接口入门:I2C、SPI、UART通信协议基础及在美容仪中的应用

各位同学,咱们今天聊聊硬件接口。说实话,很多初学者一听到「I2C、SPI、UART」这几个词就头大。我当年也一样,觉得这玩意儿太抽象了。

但你想啊,美容仪里那么多传感器——温度、湿度、皮肤阻抗、超声波探头——它们怎么跟主控芯片「说话」?靠的就是这些协议。说白了,就是给数据铺一条路,让芯片和传感器能互相听懂。

2.1 为什么美容仪需要通信协议?

我举个例子。你手里有个温度传感器,它测到皮肤表面是36.5℃。这个数据怎么告诉主控芯片?总不能靠喊吧?

通信协议就是一套「约定」。它规定了:

  • 什么时候开始说话(起始信号)
  • 一次说多少位(数据长度)
  • 说完怎么结束(停止信号)
  • 说错了怎么办(校验机制)

没有这些约定,传感器和芯片就是鸡同鸭讲。我在项目里见过有人把I2C的SDA和SCL接反了,结果读出来的温度值忽高忽低,排查了整整两天……嗯,这种坑咱们得避开。

2.2 I2C协议:两根线搞定多个传感器

I2C,全称是Inter-Integrated Circuit。你记住两个关键词就行:两根线、多设备

哪两根线?SDA(数据线)和SCL(时钟线)。所有设备都挂在这两根线上,每个设备有一个唯一的地址。主控芯片想跟谁说话,就喊谁的地址。

I2C在美容仪中的典型应用:

  • 皮肤温度传感器(如MAX30205)
  • 皮肤阻抗测量芯片(如AD5933)
  • 环境光传感器(用于检测是否贴合皮肤)

我个人习惯用I2C来连接那些「数据量不大、但设备多」的场景。比如美容仪里同时挂3个温度传感器,用I2C只需要两根线,省GPIO口。

避坑指南:我曾经在项目里把I2C的上拉电阻忘了焊。结果数据死活读不出来,示波器一看,波形全是毛刺。记住:I2C的SDA和SCL必须接上拉电阻(一般是4.7kΩ),否则信号不稳定。

2.3 SPI协议:速度快,适合大数据量

SPI,Serial Peripheral Interface。它比I2C多两根线:MOSI(主出从入)、MISO(主入从出)、SCLK(时钟)、CS(片选)。

说白了,SPI是「全双工」的——主控发数据的同时也能收数据。速度可以跑到几十MHz,比I2C快得多。

美容仪里什么场景用SPI?我告诉你:

  • 超声波探头驱动芯片:需要高速传输波形数据
  • 高分辨率ADC:比如24位的模数转换器,数据量大
  • 显示屏驱动:如果美容仪带个小屏幕,SPI是首选

注意:SPI的片选信号(CS)很容易被忽略。每个从设备需要一个独立的CS引脚。我曾经犯过一个错:两个SPI设备共用了同一个CS,结果数据互相串扰,读出来的全是乱码。后来老老实实各接各的CS,问题解决。

2.4 UART协议:最简单,但只能一对一

UART,Universal Asynchronous Receiver/Transmitter。它只有两根线:TX(发送)和RX(接收)。

为什么叫「异步」?因为没有时钟线。收发双方得提前约定好波特率——比如9600、115200。说白了,就是双方说好「每秒传多少位」,然后各自按这个节奏来。

UART在美容仪里用得不多,但有一个场景很常见:

  • 蓝牙模块通信:很多美容仪通过蓝牙连手机App,蓝牙模块和主控之间就是用UART通信的
  • 调试输出:我习惯在开发阶段用UART打印日志,方便看传感器数据对不对

小技巧:UART的TX和RX要交叉连接——主控的TX接从设备的RX,主控的RX接从设备的TX。我第一次焊板子时接反了,数据发出去对方收不到,还以为是代码写错了……

2.5 三种协议对比:怎么选?

我整理了一张表,你一看就明白:

协议 线数 速度 多设备 全双工 美容仪典型用途
I2C 2 慢(100kHz-400kHz) 是(地址区分) 半双工 温度、阻抗传感器
SPI 4+ 快(可达几十MHz) 是(片选区分) 全双工 超声波、ADC、屏幕
UART 2 中等(最高几Mbps) 否(一对一) 全双工 蓝牙、调试

怎么选?我个人的经验是:

  • 如果传感器多、数据量小、GPIO口紧张 → 选I2C
  • 如果数据量大、要求速度快 → 选SPI
  • 如果只是跟蓝牙模块通信或调试 → 选UART

2.6 实战:用I2C读取温度传感器

咱们来点实际的。假设美容仪里有个温度传感器(比如常见的LM75),地址是0x48。你想读温度值,代码怎么写?

# 伪代码示例,实际用MicroPython或C实现
import machine

i2c = machine.I2C(0, scl=machine.Pin(22), sda=machine.Pin(21), freq=100000)

# 读取温度寄存器(0x00)
data = i2c.readfrom_mem(0x48, 0x00, 2)
temp_raw = (data[0] << 8) | data[1]

# 转换为摄氏度(LM75精度0.125℃)
if temp_raw & 0x8000:  # 负数处理
    temp_c = ((temp_raw - 65536) * 0.125)
else:
    temp_c = (temp_raw * 0.125)

print("皮肤温度:", temp_c, "℃")

你看,就这么几行代码。但实际项目中,我建议你加个重试机制——传感器偶尔会「卡住」,读不到数据。我曾经遇到过:美容仪开机时温度传感器还没准备好,第一次读取返回0xFF,差点以为传感器坏了。后来加了延时和重试,稳得很。

2.7 总结一下

三种协议,说白了就是三种不同的「说话方式」:

  • I2C像开大会,主持人点名,谁被点到谁发言
  • SPI像一对一私聊,速度快但占线多
  • UART像对讲机,简单直接,但一次只能两个人聊

在美容仪项目里,你大概率三种都会用到。别怕,多焊几次板子、多调几次代码,自然就熟了。我刚开始做嵌入式时,I2C的时序图看了三遍才看懂……现在闭着眼都能写驱动。

下一章咱们聊聊具体的传感器选型,到时候拿实际芯片来练手。