马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一、IIC简介
I²C(Inter-Integrated Circuit)协议由飞利浦公司于1980年代开辟,是一种用于集成电路间短隔断通讯的串行协议。它计划用于毗连低速外围装备,特殊得当于必要简单数据交换的场景。I²C协议利用两根信号线:SCL(串行时钟线)和SDA(串行数据线)。这些线缆通过开漏(Open-Drain)输出布局与外接上拉电阻共同工作,以包管数据传输的稳固性和可靠性。I²C协议支持多主机和多从机的通讯模式,装备通过唯一的地点举行辨认。地点长度可以是7位或10位,使得I²C可以满意差别规模的体系需求。
二、时序分析
- 起始条件:SCL高电平期间,SDA从高电平切换到低电平。
- 停止条件:SCL高电平期间,SDA从低电平切换到高电平。
示例:- //产生IIC起始信号
- void IIC_Start(void)
- {
- SDA_OUT(); //sda线输出
- IIC_SDA=1;
- IIC_SCL=1;
- delay_us(4);
- IIC_SDA=0;//START:when CLK is high,DATA change form high to low
- delay_us(4);
- IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
- }
- //产生IIC停止信号
- void IIC_Stop(void)
- {
- SDA_OUT();//sda线输出
- IIC_SCL=0;
- IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
- delay_us(4);
- IIC_SCL=1;
- IIC_SDA=1;//发送I2C总线结束信号
- delay_us(4);
- }
复制代码
- 发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后开释SCL,从机将在SCL高电平期间读取数据位,以是SCL高电平期间SDA不答应有数据变革,依次循环上述过程8次,即可发送一个字节。
示例:- //IIC发送一个字节
- //返回从机有无应答
- //1,有应答
- //0,无应答
- void IIC_Send_Byte(u8 txd)
- {
- u8 t;
- SDA_OUT();
- IIC_SCL=0;//拉低时钟开始数据传输
- for(t=0;t<8;t++)
- {
- IIC_SDA=(txd&0x80)>>7;
- txd<<=1;
- delay_us(2);
- IIC_SCL=1;
- delay_us(2);
- IIC_SCL=0;
- delay_us(2);
- }
- }
复制代码
- 吸收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后开释SCL,主机将在SCL高电平期间读取数据位,以是SCL高电平期间SDA不答应有数据变革,依次循环上述过程8次,即可吸收一个字节(主机在吸收之前,必要开释SDA)。
示例:- //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
- u8 IIC_Read_Byte(unsigned char ack)
- {
- unsigned char i,receive=0;
- SDA_IN();//SDA设置为输入
- for(i=0;i<8;i++ )
- {
- IIC_SCL=0;
- delay_us(2);
- IIC_SCL=1;
- receive<<=1;
- if(READ_SDA)receive++;
- delay_us(1);
- }
- if (!ack)
- IIC_NAck();//发送nACK
- else
- IIC_Ack(); //发送ACK
- return receive;
- }
复制代码
- 发送应答:主机在吸收完一个字节之后,在下一个时钟发送一位数据,数据0体现应答,数据1体现非应答 吸收应答:主机在发送完一个字节之后,在下一个时钟吸收一位数据,判定从机是否应答,数据0体现应答,数据1体现非应答(主机在吸收之前,必要开释SDA)。
示例:- //等待应答信号到来
- //返回值:1,接收应答失败
- // 0,接收应答成功
- u8 IIC_Wait_Ack(void)
- {
- u8 ucErrTime=0;
- SDA_IN(); //SDA设置为输入
- IIC_SDA=1;delay_us(1);
- IIC_SCL=1;delay_us(1);
- while(READ_SDA)
- {
- ucErrTime++;
- if(ucErrTime>250)
- {
- IIC_Stop();
- return 1;
- }
- }
- IIC_SCL=0;//时钟输出0
- return 0;
- }
- //产生ACK应答
- void IIC_Ack(void)
- {
- IIC_SCL=0;
- SDA_OUT();
- IIC_SDA=0;
- delay_us(2);
- IIC_SCL=1;
- delay_us(2);
- IIC_SCL=0;
- }
- //不产生ACK应答
- void IIC_NAck(void)
- {
- IIC_SCL=0;
- SDA_OUT();
- IIC_SDA=1;
- delay_us(2);
- IIC_SCL=1;
- delay_us(2);
- IIC_SCL=0;
- }
复制代码
|