一句话定调
简单说,I2C和SPI就是单片机用来和外部设备“打电话”的两种不同方式——一个像打群架时轮流发言(I2C),一个像领导单独找每个人谈话(SPI)。
推荐一个学习网站,http://easelearningai.com 输入学习主题,会根据你的知识背景,帮你把学习内容讲得通俗易懂。
为什么会有这两种“电话线”?
想象一下:你只有一个单片机(大脑),但你想连接温度传感器、显示屏、存储卡、加速度计……一大堆外设。每个外设都需要和单片机交换数据。如果每个设备都单独拉一根线到单片机,那单片机上的引脚(就像人的手指头)根本不够用——新塘单片机一般只有几十个引脚,而你需要接十几个甚至几十个设备。
于是,工程师们发明了“总线”这个概念。总线就是一条共享的通信线路,所有设备都挂在这条线上,通过约定好的规则轮流说话,互不干扰。
但问题来了:不同的外设“性格”不同。有的需要高速传输(比如摄像头),有的只需要偶尔传几个数字(比如温度传感器),有的需要同时和多个设备对话……所以出现了两种主流的“电话系统”:I2C和SPI。
I2C:像班级里的“举手发言”
生活类比
想象一个班级:老师(单片机)要问全班同学问题。每个同学都有一个学号(地址)。老师喊:“学号5的同学,请回答!”只有学号5的同学站起来说话,其他同学安静听着。说完后,老师再叫下一个。这就是I2C的工作方式。
核心特点
- 只需要两根线:一根是时钟线(SCL,就像老师拍手的节奏),一根是数据线(SDA,就像同学说话的内容)
- 每个设备有唯一地址:就像每个同学有学号,I2C设备出厂时就固定了地址(比如0x50、0x68)
- 主从模式:单片机是“主设备”(老师),外设是“从设备”(学生),只有主设备能发起对话
真实场景:读取温度传感器
你买了一个LM75温度传感器模块。它只有4个引脚:VCC(电源)、GND(地)、SCL(时钟)、SDA(数据)。
你想读取当前温度,步骤是这样的:
- 单片机通过SCL线发出时钟脉冲(就像老师开始拍手)
- 单片机在SDA线上发送“0x48”(LM75的地址),后面跟一个“读”指令
- LM75听到自己的地址,回应“我在!”
- 单片机继续发送时钟,LM75开始把温度数据(比如25.3°C)一位一位传回来
- 传输结束,单片机停止时钟
整个过程就像:老师喊“学号48的同学,报一下你的温度!”——48号同学站起来回答“25.3度”——老师记录完毕。
为什么叫“I2C”?
全称是Inter-Integrated Circuit(集成电路间通信),读作“I方C”。因为只需要两根线,所以特别适合连接那些“不着急”的设备——温度传感器、实时时钟、EEPROM存储器等。速度一般在100kHz到400kHz之间(每秒传10万到40万位数据),够用但不算快。
新塘单片机怎么用I2C?
新塘的NuMicro系列单片机内置了I2C硬件模块。你只需要:
- 在代码中配置SCL和SDA引脚(比如PB0和PB1)
- 设置通信速度(标准模式100kHz或快速模式400kHz)
- 调用库函数发送设备地址和数据
比如读取LM75温度的伪代码:
I2C_Start(); // 发起通信 I2C_SendAddr(0x48); // 告诉LM75:我要找你 I2C_SendData(0x00); // 告诉LM75:我要读温度寄存器 I2C_Start(); // 重新发起(读操作需要) I2C_SendAddr(0x48 | 0x01); // 告诉LM75:现在我要读数据 temp = I2C_ReadData(); // 接收温度值 I2C_Stop(); // 结束通信SPI:像领导单独找每个人谈话
生活类比
现在换一个场景:你是公司领导(单片机),手下有4个部门经理(外设)。你要给每个经理单独布置任务。你不可能在全体大会上说“销售部,你们要……”,因为这样其他部门会听到机密。所以,你一个一个叫到办公室,关上门单独谈。每次只和一个经理对话,速度快,保密性好。
核心特点
- 需要四根线:
- MOSI(主输出从输入):领导说话的内容
- MISO(主输入从输出):经理回答的内容
- SCLK(时钟):领导拍手的节奏
- CS(片选):领导喊“某某经理,进来!”——每个经理有一根单独的CS线
- 全双工:可以同时发送和接收(就像领导说话的同时,经理也在回答)
- 速度极快:可达几十MHz(每秒几千万位),比I2C快几十倍
真实场景:驱动OLED显示屏
你买了一个0.96寸OLED显示屏,它使用SPI接口。它有7个引脚:VCC、GND、SCLK、MOSI、CS、DC(数据/命令选择)、RST(复位)。
你想在屏幕上显示“Hello”:
- 单片机把CS引脚拉低(就像喊“显示屏,进来!”)
- 通过SCLK发出时钟,同时通过MOSI发送命令(比如“清屏”)
- 再发送数据(比如每个像素的颜色值)
- 发送完毕,把CS拉高(“出去吧,叫下一个”)
整个过程就像:领导把显示屏经理叫进办公室,说“把黑板擦干净”,然后说“写上Hello这几个字”,说完后让他出去。
为什么叫“SPI”?
全称是Serial Peripheral Interface(串行外设接口)。因为每个设备都有单独的CS线,所以可以同时连接多个设备,而且互不干扰。特别适合需要高速传输的设备——SD卡、显示屏、ADC(模数转换器)、无线模块等。
新塘单片机怎么用SPI?
新塘单片机同样内置了SPI硬件模块。配置步骤:
- 设置SCLK、MOSI、MISO引脚(比如PA0-PA3)
- 为每个外设备分配一个CS引脚(可以用普通GPIO)
- 设置时钟极性和相位(和外设匹配)
- 调用库函数传输数据
比如向OLED发送一个字节:
CS_LOW(); // 选中显示屏 SPI_SendByte(0xAF); // 发送“显示开启”命令 CS_HIGH(); // 取消选中I2C vs SPI:怎么选?
| 特性 | I2C | SPI |
|---|---|---|
| 连线数量 | 2根(SCL+SDA) | 4根(SCLK+MOSI+MISO+CS),每多一个设备加一根CS |
| 速度 | 100kHz~400kHz(慢) | 最高几十MHz(快) |
| 通信方式 | 半双工(轮流说话) | 全双工(同时说和听) |
| 设备寻址 | 软件寻址(7位或10位地址) | 硬件片选(每设备一根CS线) |
| 典型应用 | 温度传感器、EEPROM、实时时钟 | 显示屏、SD卡、无线模块、ADC |
| 适合场景 | 设备多、速度要求不高、引脚有限 | 速度要求高、设备少、引脚够用 |
一句话决策:如果你要接5个以上的慢速传感器,选I2C(省引脚);如果你要驱动一个高分辨率显示屏,选SPI(要速度)。
在真实项目中如何选择?
假设你正在用新塘单片机做一个智能家居控制面板:
需要连接的设备:
- 温湿度传感器(DHT22)—— 慢速,I2C合适
- 实时时钟(DS3231)—— 慢速,I2C合适
- OLED显示屏(128x64)—— 需要刷新,SPI合适
- SD卡存储日志 —— 需要高速写入,SPI合适
- 4个按键 —— 直接接GPIO,不需要总线
方案:
- I2C总线挂载:温湿度传感器(地址0x40)+ 实时时钟(地址0x68)—— 只用2根线
- SPI总线挂载:OLED显示屏(CS接PA0)+ SD卡(CS接PA1)—— 共用SCLK、MOSI、MISO,各用一根CS
这样,你只用了6个引脚(2个I2C + 4个SPI),就连接了4个外设。如果每个设备单独接,需要至少8个引脚(每个设备至少2根数据线)。
最后一点提醒
初学者最容易犯的错误是忘记上拉电阻。I2C的两根线(SCL和SDA)是开漏输出(可以理解为“只能拉低,不能拉高”),所以必须接上拉电阻(通常4.7kΩ)到电源,否则信号传不出去。而SPI不需要上拉电阻,因为它是推挽输出(既能拉高也能拉低)。
新塘单片机开发板上通常已经集成了这些电阻,但如果你自己搭电路,一定要记得加上。
总结:I2C像班级里老师点名,省线但慢;SPI像领导单独谈话,快但费线。根据你的外设数量和速度需求,选对总线,就能用最少的引脚连接最多的设备。下次看到某个模块标注“I2C接口”或“SPI接口”,你就知道它用的是哪种“电话系统”了。