IIC与SPI通信协议对比

本人是初学者,非常希望与大家交流。

想象一下你是个芯片老大,要指挥手下的小弟(其他芯片)干活。怎么给小弟们发命令、收情报呢?这时就需要通信协议—— IIC 和 SPI。

1. IIC(也叫 I²C):两线制的“电话会议系统”

  • 核心特点: 只用两根线!

    • SDA (数据线): 像电话听筒,既能说又能听,但不能同时(半双工)。

    • SCL (时钟线): 像电话铃声/节拍器,老大负责摇铃铛📢,告诉大家“注意!现在开始传消息了!1,2,1,2...”

  • 怎么工作?

    • 老大点名: 老大(主设备)先摇铃铛(SCL),然后在SDA线上喊:“喂喂喂!地址是0x68的小弟(从设备)在吗?我要跟你说话啦!”(广播一个唯一的设备地址)。

    • 小弟应答: 地址匹配的小弟会回一声:“在呢老大!”(发送一个应答信号)。

    • 传纸条/听汇报: 然后老大就可以通过这根SDA线,按照SCL的节奏,要么给小弟发命令(写数据),要么听小弟汇报情况(读数据)。一次只能一个人说话。

    • 多个小弟: 所有小弟都挂在同一对 SDA 和 SCL 线上。老大靠点名(设备地址)找到特定小弟。就像开电话会议,大家都能听到铃响和点名,但只有被点到名的才能说话。

  • 优点:

    • 省线省钱! 接再多的设备也只需要两根线,电路板走线清爽。

    • 有地址,好管理。 理论上可以挂很多设备(地址不冲突就行)。

  • 缺点:

    • 速度慢点。 因为要等点名、应答,而且一根线来回传数据。

    • 容易“串线”。 一根线上挂太多设备或者线路太长,信号可能变差。

    • 老大累。 时钟SCL必须由老大(主设备)产生,小弟不能主动摇铃铛。

  • 适合场景: 速度要求不高,设备不太多,成本敏感的地方。比如:读取温度传感器、光照传感器、EEPROM(小存储器)的数据。

 形象比喻:IIC 就像一个“电话会议群聊”

  • 只有一个人(主设备)能主持(发起通话、控制时钟)。

  • 主持人点名(发地址)呼叫特定参会者(从设备)。

  • 大家共用一条语音线路(SDA),同一时间只能一个人说话或听(半双工)。

  • 主持人用另一个铃声(SCL)统一节奏。

2. SPI:四线制的“点对点高速专线”

  • 核心特点: 一般用四根线!(有时三根)

    • MOSI (Master Out Slave In): 老大说,小弟听 的专属通道。

    • MISO (Master In Slave Out): 小弟说,老大听 的专属通道。

    • SCLK (时钟 Clock): 老大负责摇铃铛📢,统一数据节奏(和IIC的SCL作用一样)。

    • CS/SS (片选 Chip Select / Slave Select): 点名专用线! 老大想和哪个小弟说话,就单独拉一下(通常是拉低)连到那个小弟的这根线,意思是:“喂!你!就你!注意听/说!”

  • 怎么工作?

    • 老大指人: 老大决定要和哪个小弟A说话,就拉低小弟A的CS线(其他小弟的CS保持高电平,让它们“睡觉”别听)。

    • 同时开聊! 老大一边在MOSI线上给小弟A发命令(说),一边在MISO线上听小弟A的回复(听),两边同时进行(全双工)! SCLK线一直在摇,同步两边数据的收发节奏。

    • 换人: 老大说完A,把A的CS线拉高(“好了你歇着吧”),再拉低小弟B的CS线,开始和小弟B说话。

  • 优点:

    • 速度飞快! 有独立通道,能同时收发,时钟频率通常比IIC高很多。

    • 连接简单直接。 点对点连接,信号干扰小,更稳定。

    • 全双工,效率高。 能一边下命令一边收结果。

  • 缺点:

    • 费线! 每增加一个设备,老大就需要多一根CS线来控制它!挂4个设备就需要4根CS线 + 3根公共线(MOSI, MISO, SCLK)= 7根线!布线可能变复杂。

    • 没地址。 全靠CS线物理点名。

    • 标准稍松散。 具体怎么传数据(比如数据位顺序、时钟极性等)细节上可能略有不同,需要看芯片手册配置。

  • 适合场景: 对速度要求高,数据量大,设备相对较少的地方。比如:驱动显示屏、读写SD卡、连接高速ADC/DAC(模数/数模转换器)、连接无线模块(WIFI, 蓝牙芯片)。

 形象比喻:SPI 就像“老大和小弟开私聊小灶”

  • 老大(主设备)是中心。

  • 每个小弟(从设备)都有自己专属的“收命令通道”(MOSI)、“汇报通道”(MISO)和“点名铃”(CS)。

  • 老大想和谁私聊,就按谁的专属点名铃(拉低CS)。

  • 私聊时,老大可以对着小弟的耳朵(MOSI)快速下命令,同时小弟也能对着老大的耳朵(MISO)快速汇报,两边同时说同时听(全双工)! 老大还用另一个铃铛(SCLK)指挥两人说话的节奏。

  • 老大一次只和一个小弟私聊(通过CS选择)。

总结:关键区别一目了然

特点IIC (电话会议)SPI (私聊小灶)
线数少 (2根:SDA, SCL)多 (通常4根:MOSI, MISO, SCLK, CS/SS)
点名方式喊地址 (广播+应答)拉专线 (CS/SS 物理选择)
数据通道1根线来回用 (半双工)2根独立线 (全双工,可同时收/发)
速度较慢很快
设备扩展容易 (地址区分),但总线负载有限费线 (每加一设备多一根CS线)
复杂度协议稍复杂 (地址、应答)硬件连线稍多,协议相对直接
典型应用传感器、小存储器、低速控制显示屏、存储器卡、高速ADC、无线模块

再浓缩成一句话:

IIC 是“省线省钱开大会,点名叫号慢慢聊”;
SPI 是“多线高速开小灶,指谁跟谁同时唠”!

现在是不是感觉它们就像两个性格迥异的通信小能手啦?下次在电路图上看到它们,想想谁是开大会的,谁是开小灶的,就明白啦!

示例1:IIC通信 - 控制OLED显示屏

#include <Wire.h>       // IIC通信必备库(电话会议系统)
#include <Adafruit_SSD1306.h> // OLED显示屏库

// 设置OLED参数(128x64分辨率)
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C // OLED地址(相当于电话号码)

// 创建OLED对象(初始化电话会议系统)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(9600);
  
  // 尝试启动IIC通信(拨打电话)
  if(!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
    Serial.println("IIC连接失败!检查接线");
    while(1); // 卡死在这里
  }
  
  Serial.println("IIC连接成功!开始电话会议...");
  
  // 清屏(挂断之前的通话)
  display.clearDisplay();
  
  // 设置字体(选择说话语气)
  display.setTextSize(2);         // 字体大小
  display.setTextColor(WHITE);    // 字体颜色
  
  // 设置光标位置(指定说话位置)
  display.setCursor(10, 20);
  
  // 发送数据(开始说话)
  display.println("Hello IIC!");  // 说"Hello IIC!"
  
  // 显示内容(挂上听筒结束通话)
  display.display();
}

void loop() {
  // 这里不需要重复操作
}
 代码解释(IIC版):
  1. 包含库Wire.h是Arduino的IIC库(电话会议系统)

  2. 地址设置0x3C是OLED的固定地址(相当于电话号码)

  3. 初始化display.begin()启动IIC通信(拨打电话)

  4. 数据传输

    • setCursor():设置文本位置(指定说话位置)

    • println():发送数据(说话内容)

    • display():结束传输(挂断电话)

  5. 特点体现

    • 只用了SDA(A4)和SCL(A5)两根线

    • 通过地址0x3C选择设备

    • 每次只能发送或接收(半双工)

Esp32         ->   OLED
GND           ->   GND
5V            ->   VCC
A4            ->   SDA (数据线)
A5            ->   SCL (时钟线)

 示例2:SPI通信 - 控制MAX7219 LED点阵

#include <SPI.h> // SPI通信必备库(私聊系统)

// 定义SPI引脚(Esp32 固定引脚)
#define DATA_PIN 11  // MOSI(老大发令通道)
#define CLK_PIN 13   // SCK (摇铃铛节奏线)
#define CS_PIN 10    // CS  (点名专线)

// LED点阵命令(MAX7219专用指令)
const byte DECODE_MODE = 0x09;  // 解码模式
const byte INTENSITY = 0x0A;    // 亮度设置
const byte SCAN_LIMIT = 0x0B;   // 扫描限制
const byte SHUTDOWN = 0x0C;     // 关机模式
const byte DISPLAY_TEST = 0x0F; // 测试模式

void setup() {
  // 设置CS引脚为输出(点名专线控制权)
  pinMode(CS_PIN, OUTPUT);
  
  // 启动SPI通信(开启私聊系统)
  SPI.begin();
  
  // 初始化LED点阵(唤醒小弟)
  sendCommand(SHUTDOWN, 1);      // 退出关机模式
  sendCommand(DISPLAY_TEST, 0);  // 关闭测试模式
  sendCommand(DECODE_MODE, 0);   // 禁用BCD解码
  sendCommand(SCAN_LIMIT, 7);    // 扫描所有8位数码管
  sendCommand(INTENSITY, 8);     // 设置中等亮度
}

void loop() {
  // 显示"SPI"字母动画
  showS(); delay(500);
  showP(); delay(500);
  showI(); delay(500);
  clearDisplay(); delay(300);
}

// ======== 核心函数:发送SPI命令 ========
void sendCommand(byte command, byte data) {
  digitalWrite(CS_PIN, LOW);  // 拉低CS(点名:小弟注意!)
  
  SPI.transfer(command); // 发送命令(说:要做什么)
  SPI.transfer(data);    // 发送数据(说:具体怎么做)
  
  digitalWrite(CS_PIN, HIGH); // 拉高CS(结束通话)
}

// ======== 显示字母S ========
void showS() {
  // 点亮构成"S"的LED(同时发送行列数据)
  for(int col=1; col<=8; col++) {
    byte pattern = 0;
    if(col==1) pattern = B00111100;
    if(col==2) pattern = B01000010;
    // ...其他行类似
    sendCommand(col, pattern);
  }
}

// ======== 清屏函数 ========
void clearDisplay() {
  for(int i=1; i<=8; i++) {
    sendCommand(i, 0x00); // 所有LED关闭
  }
}
代码解释(SPI版):
  1. SPI引脚:Esp32的固定SPI引脚(MOSI-11, MISO-12, SCK-13)

  2. CS引脚:自定义的片选引脚(这里是D10,点名专线)

  3. 通信流程

    • digitalWrite(CS_PIN, LOW):选中设备(点名叫小弟)

    • SPI.transfer():发送数据(同时收/发)

    • digitalWrite(CS_PIN, HIGH):释放设备(结束通话)

  4. 全双工体现:发送命令同时可接收点阵状态

  5. MAX7219控制

    • 通过寄存器命令控制(如SHUTDOWN/INTENSITY)

    • 每列单独控制(8x8点阵)

Esp32         ->   MAX7219模块
GND           ->   GND
5V            ->   VCC
D11 (MOSI)    ->   DIN (数据输入)
D13 (SCK)     ->   CLK (时钟)
D10 (自定义CS) ->   CS  (片选)

对比总结:

特性IIC示例 (OLED)SPI示例 (LED点阵)
线数2根 (SDA+SCL)3根 (MOSI+SCK+CS)
库文件Wire.hSPI.h
设备选择通过地址(0x3C)通过CS引脚(物理拉低)
数据传输display.print() (单向发送)SPI.transfer() (双向传输)
速度较慢(100kHz-400kHz)快速(默认4MHz)
典型应用传感器/小屏幕高速外设(LED/存储器卡)

建议:

  1. 先尝试IIC示例(接线简单)

  2. 用串口监视器观察调试信息

  3. 成功后尝试SPI示例(注意CS引脚接线)

  4. 修改显示内容(IIC改文本,SPI改图案)

  5. 进阶:同时使用IIC和SPI(体验多协议协作)

这两个示例展示了:

  • IIC像「电话会议」:两根线搞定,靠地址呼叫

  • SPI像「私聊专线」:多线高速,CS点名指谁跟谁聊

实际接线时,记得给OLED和MAX7219模块都供电哦!遇到问题先检查地址和CS引脚设置~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FightingFreedom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值