I2C总线
简介
I²C(Inter-Integrated Circuit)是内部集成电路的称呼,是一种串列通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。
协议
- 使用两条串行(数据线SDA&时钟线SCL),并利用电阻将电位上拉;
- 可在CPU与被控IC之间,IC与IC之前都可以进行双向传送;
- 支持多主控(multimastering),任何时间点只能有一个主控;
- 在主从通信中,可以有多个I2C总线器件同时接到I2C总线上,所有与I2C兼容的器件都具有标准的接口,通过地址来识别通信对象;
- 控制信号分为地址码和数据码两部分:地址那用来选址,即接通需要控制的电路;数据码是通信的内容。
应用
- 为了保存用户的设置而访问NVRAM芯片。
- 访问低速的数字模拟转换器(DAC)。
- 访问低速的模拟数字转换器(ADC)。
- 改变监视器的对比度、色调及色彩平衡设置(视频数据通道)。
- 改变音量大小。
- 获取硬件监视及诊断数据,例如中央处理器的温度及风扇转速。
- 读取实时时钟(Real-time clock)。
- 在系统设备中用来打开或关闭电源供应。
操作


初始化
将SDA和SCL都变成高电平
1 | void init() //初始化 |
开始信号

SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
1 | void start()//起始信号 |
地址
- 发送地址字(芯片的硬件地址),即使确定要对之进行操作的芯片。
- 在I2C总线协议中地址必须是起始条件后作为第一个字节发送。
- 使用I2C总线的芯片地址应包括固定部分和可编程部分。可编程部分必须根据地址引脚来确定。
- 地址字节的最后一位是用于设置以后传输方向的读/写位。
- 不同芯片地址字节的设置可能不同?
应答
- Master每发送完8bit(地址/命令字)数据后都要等待Slave的ACK,以确定数据传送是否被对方收到。
- 应答信号由接收设备产生。
- 在第9个clock,若从IC发ACK,SDA会被拉低,则说明数据传输正确;若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:
1 | void respons()//应答(相当于一个智能的延时函数 ) |
写数据
写寄存器的标准流程
- Master发起START
- Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
- Slave发送ACK
- Master发送reg addr(8bit),等待ACK
- Slave发送ACK
- Master发送data(8bit),即要写入寄存器中的数据,等待ACK
- Slave发送ACK
- 第6步和第7步可以重复多次,即顺序写多个寄存器
- Master发起STOP
写一个数据
写多个数据
写时序
- 先将SCL置0(只有它为0的时候SDA才允许变化)
- 改变SDA是数值(就是你当前要穿的一位是0还是1)
- 把SCL置1(此时芯片就会读取总线上的数据)
1 | #define uchar unsigned char |
读数据
读寄存器的标准流程
- Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
- Slave发送ACK
- Master发送reg addr(8bit),等待ACK
- Slave发送ACK
- Master发起START
- Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
- Slave发送ACK
- Slave发送data(8bit),即寄存器里的值
- Master发送ACK
- 第8步和第9步可以重复多次,即顺序读多个寄存器
读一个数据
读多个数据
1 | uchar read_byte() |
终止信号
SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
1 | void stop() //停止信号 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 琴韵居!