介绍
教程:
-
两根通信线:SCL(时钟),SDA(数据)
-
一主多从,一条总线挂载多个设备,SCL连在一起,SDA连在一起
-
支持指定设备的指定寄存器的读写
-
支持以下操作:指定地址写
-
只有主设备呼叫后,从设备才可以向SDA发送数据
通信电平
- SCL和SDA配置为开漏模式,由外置上拉电阻来上拉
- 只要有一个设备发送低电平,总线就为低电平
- 空闲:SCL和SDA都为高电平
- 开始一轮通信:在SCL高电平的前提下拉低SDA
- 发送数据:发送方在SCL低电平期间调整SDA电平,接收方在SCL高电平期间读取SDA电平,一次发送一个字节
- 应答:每收发完一个字节,后面紧跟一位应答位,SDA为低电平表示应答有效
- 应答完毕紧接着可以发送第二个字节
- 结束一轮通信:在SCL高电平的前提下拉高SDA
通信协议
对于大部分的I2C设备来说:
- 每个从设备有7bit的地址;在一轮通信中,主设备通过地址选择一个从设备进行通信
- 每个从设备在一系列地址上有寄存器,每个寄存器负责不同的功能,具体参考技术手册
- 支持对从指定从设备的指定寄存器读/写操作
- 从设备有个寄存器作为指针指向“当前处理的寄存器的地址”,每次读/写了一个byte就+1
- 在发送数据部分如果读/写完一个byte,没有收到应答,则会继续发送。由于“当前处理的寄存器”指针自增,实际发送的是下一个字节。即:发送数据部分读/写完一个byte,发送方没有收到应答,则会发送下一个byte
指定寄存器写:
- 第1个byte:主设备发送;前7位表示从设备地址,第8位为0表示主设备写从设备;从设备拉低SDA进行ACK
- 第2个byte:主设备发送寄存器地址;从设备拉低SDA进行ACK
- 第3+byte:主设备发送数据,写入从设备寄存器;从设备拉低SDA进行ACK
指定寄存器读:
- 第1个byte:主设备发送;前7位表示从设备地址,第8位为0表示主设备写从设备;从设备拉低SDA进行ACK
- 第2个byte:主设备发送寄存器地址;从设备拉低SDA进行ACK
- 第3个byte:主设备发送;前7位表示从设备地址;第8位为1表示主设备读从设备;从设备拉低SDA进行ACK
- 第4+byte:主设备输出时钟,从设备发送数据,主设备读取;主设备进行NACK表示将会继续读取;主设备拉低SDA进行ACK表示读取结束
设备地址的两种书写方式:
- 7bit长度:不包括读写位,使用时实际传参
ADDR<<1 | RW- 8bit长度:分为读地址和写地址,使用时实际传参
ADDR- 比如128x64的OLED屏幕,只有写操作,其默认写地址为:
0x78/0b0111000(8bit) =0x3c/0b011100(7bit)
I2C外设
- 一个数据寄存器DR
- 发送数据时:将数据从DR转移到移位寄存器中,然后高位先行移出至SDA
- 接收数据时:移位寄存器从SDA读入最低位,读入8位后将数据转移到DR
HAL库
函数命名是这样的:
- 是否阻塞
- Blocking
- Interrupt
- DMA
- 收发方式
- 不带Mem的:通常为直接与另一个MCU通信时使用
- Master/Slave
- Seq模式:连续读写一系列数组(大量数据)时使用
- 带Mem的:对芯片的指定寄存器地址读写
(区分于寄存器地址与设备地址)
|
|
实践:24C02的读写
24C02芯片
datasheet:
AT24C02B: https://ww1.microchip.com/downloads/en/DeviceDoc/doc0180.pdf
24C02C: http://ww1.microchip.com/downloads/en/DeviceDoc/21202j.pdf
请阅读其中有关 Write 和 Read 有关的内容!
- I2C协议的EEPROM,可以断电保存数据,具有2kB的空间,以8或者16字节为一页
- 使用上述读写寄存器的方法直接读写数据
- 读取
- 支持读取单个字节,或者连续读取多个字节
- 读取多个字节时可以跨页读取
- 写入
- 支持写入单个字节,或者连续写入多个字节
- 连续写入多个字节时不能跨页。如果数据长度超过页边界,将会从页起始开始覆盖写入
- 从I2C写入的内容将会保存到缓存中,在连续写入结束时写回非易失性存储中
- 在写回的过程中不会响应任何I2C指令,需要等待写回完成后、判断其有响应后,再进行其它操作