硬件协议之i2c
https://blog.csdn.net/ctyqy2015301200079/article/details/83830326 (此文章可能有误)
从目前来看,所有读写操作(包括ACK的读写)都是CLK=0,保持, 读取SDA后,CLK=1, 保持
起始信号和终止信号,都是先保持CLK=1, 然后前者SDA从1变为0, 后者SDA从0变1
其实CLK=0的作用代表要读写了, CLK=1的作用为恢复普通态, TODO。。。 占从设备角度看待是如何接受主设备的CLK命令的
起始信号
SDA,SCL设置为输出模式
SDA=1, SCL=1, 保持
SDA=0, 保持
终止信号
SCL=0, SDA=0, 保持
SCL=1, 保持
SDA=1, 保持
SDA, SCL设置为输入模式
// 有些人的描述为 SCL高电平时,SDA由低变高
单字节读
SDA设置为输入模式
循环8次:
SCL=1, 读SDA, 保持
SCL=0, 保持
从设备在SCL=0时可能已经准备好了SDA给主设备去读取
主控器发送ACK (读入一个字节后需要发送ACK)
SDA设置为输出模式
SCL=0, SDA=0, 保持
SCL=1, 保持
SCL=0, 保持
单字节写
SDA设置为输出模式
循环8次:
SCL=0,保持
写SDA, SCL=1, 保持
最后
SCL=0
此处,输出SDA后, 怀疑是保持了一段时间, 再设置SCL=1,
实际上输出SDA可能不需要保持一段时间再设置SCL=1,因为SCL=1在SDA之后设置的,SCL=1时,从设备才开始读入主设备设置的SDA
主控器读取ACK (写入一个字节后需要读ACK)
SDA设置为输入模式
SCL=1, 读SDA, 保持
SCL=0, 保持
(这里可能是SCL=0, 读SDA, 保持,然后再SCL=1保持)
此处写字节的最后一个位写完之后, 主设备SDA更换为读入模式, 而从设备马上就拉低了SDA代表收到了写入的字节
读数据流程:
1. 先发送开始信号S
2. 再发送从设备地址(7位,bit7~bit1), 再发送读标记1 (bit0为1代表读数据), 再读入ACK (用于判断从设备是否收到了地址)
3. 读入一个字节, 再发送ACK(告诉从设备已经读入了该字节)
4. 重复3去读取多个数据 (其实在3之前可能要写入一个寄存器地址或者寄存器的起始,之后才是读入多个数据)
5. 发送停止信号P
写数据流程
1. 先发送开始信号S
2. 再发送从设备地址(7位,bit7~bit1), 再发送读标记0 (bit0为0代表写数据), 再读入ACK (用于判断从设备是否收到了地址)
3. 写入一个字节, 再读入ACK(用于判断从设备是否收到了此字节)
4. 重复3去写入多个数据 (通常是写入两个数据, 一个寄存器地址和一个数据, 但是有些从设备定义的应用协议为寄存器起始地址 + 一大堆数据)
5. 发送停止信号P