
接口线少只有两根线,控制方式简单,通信速率较高;
I2C 是飞利浦公司开发的两线式串行总线;
硬件比较复杂,稳定性不太好,程序移植有点麻烦,用软件模拟I2C比较方便
(1)支持多设备的总线
(2)一个总线只使用两根线,数据线SDA,时钟线SCL
(3)每个连接总线都设备都有一个独立的地址,查询设备都是靠这个地址
(4)总线通过上拉电阻,空闲的时候就输出高阻态,所有设备空间的时候,会拉成高电平
(5)多个主机同时使用总线的时候,就会使用仲裁
(6)总线传输模式,标准100kbits/s,快速模式400kbit.s
I2C 里面定义了通信的 6 个方面
1、起始和停止信号
2、数据有效性、
3、响应
4、仲裁
5、时钟同步
6、地址广播

I2C传输数据,SCL时钟要为高电平期间,SDA传输数据的线必须稳定;
时钟为低电平的期间,数据线上的高电平或者低电平数据允许发生变化;
传输数据以字节为单位,每次传输的字节数不受限制;

时钟SCL为高电平期间,SDA数据线由高电平向低电平变化表示起始信号;
时钟SCL为高电平期间,SDA数据线由低电平向高电平变化表示停止信号;
起始和停止信号都是由主机发出,发送起始信号后,总线就处于被占用的状态,主机发送停止信号后,总线就处于空闲状态;

发送端传输完一个字节的数据后,后面必须要跟一个校验位,这个校验位是 从机 通过控制SDA(数据线)来实现的,主机可以继续发送数据,这个校验位就是数据或地址传输过程中的响应。
响应分为(应答ACK)和(非应答NACK)
作为从机 当 主机接收到I2C传输的一个字节数据或地址后,若让主机继续发送需要向对方发送应答ACk信号低电平脉冲,主机就会继续发送下一个数据;
若从机希望结束数据传输,则会向主机发送 非应答NACK信号高电平脉冲,主机收到非应答信号,就会产生停止信号,结束信号传输;
每个字节必须保证8位,先传送高位MSB ,在传输地位LSB,传送的字节要跟一位应答位 (一帧 9 位 )

分为两种,7位和10位的
D7~D1 是 从机的地址,D0位是数据传送方向位;
为0表示主机向从机写数据,为1 主机向 从机读数据;
主机发送一个地址,总线上每个器件都将头7位于自己的地址比较,一样,就会被主机选址
四位是固定的,3个可编程

主机发送起始信号,发送从机地址+使能位写数据,从机发送应答,主机发送数据,从机应答主机发送数据,非应答,主机 发送结束信号;

- #include "iic.h"
-
-
- // at 芯片读写操作的
- // 起始信号
- void iic_start(void)
- {
- IIC_SCL = 1;
- IIC_SDA = 1;
- delay_10us(1);
- IIC_SDA = 0;
- delay_10us(1);
- IIC_SCL = 0;
- // 处于占用
-
- }
-
-
- // 停止信号
-
- void iic_stop(void)
- {
- IIC_SCL = 1;
- IIC_SDA = 0;
- delay_10us(1);
- IIC_SDA = 1;
- delay_10us(1);
- }
-
-
- // 应答信号
-
- void iic_ack(void)
- {
- IIC_SCL = 0;
- IIC_SDA = 0;
- delay_10us(1);
- IIC_SCL = 1;
- delay_10us(1);
- IIC_SCL = 0;
- }
-
- // 非应答信号
-
- void iic_nack(void)
- {
- IIC_SCL = 0;
- IIC_SDA = 1;
- delay_10us(1);
- IIC_SCL = 1;
- delay_10us(1);
- IIC_SCL = 0;
-
- }
-
-
- u8 iic_wait_ack(void)
- {
- u8 time_temp =0;
-
- IIC_SDA = 1;
- delay_10us(1);
- while(IIC_SDA)
- {
- time_temp++;
- if(time_temp>100)
- {
- iic_stop();
- return 1; // 返回1 停止应答
- }
- }
- IIC_SDA = 0;
- return 0;
-
- }
-
- // IIC写字节的操作
- void iic_write_byte( u8 dat) // 入参 传入字节
- {
- //
- u8 i =0;
- IIC_SCL=0;
- for(i=0;i<8;i++) //从高位 在地位 写入
- {
- if( (dat&0x80) > 1) // 0x80 1000 0000 从最高位 判断最高位为1 如果大于0
- IIC_SDA = 1;
- else
- IIC_SDA = 0;
- dat <<= 1; // 左移一位
- IIC_SDA = 0;
- delay_10us(1);
- IIC_SCL=0;
- delay_10us(1);
- }
- }
-
- // IIC 读字节操作
- u8 iic_read_byte(u8 ack)
- {
- u8 i =0;
- u8 receive =0;
-
- for(i=0;i<8;i++)
- {
- IIC_SCL = 0;
- delay_10us(1);
- IIC_SCL=1;
- delay_10us(1);
- receive<<=1;
- if(IIC_SDA)receive++;
-
- }
-
- if(!ack)iic_nack();
- else iic_ack();
-
- return receive;
-
- }