以下文章来源于:公_众_号开源电子网 读取更多技术文章,请扫码关注
IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器以及其外围设备,IIC也被成为I2C,其实两者是完全相同的,只是名词不一样而已。它是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。 IIC特点: ①数据线SDA:数据线用来传输数据;时钟线SCL:时钟线用来同步数据收发 ②总线上每一个器件都有一个唯一的地址识别,所以我们只需要知道器件的地址,根据时序就可以实现微控制器与器件之间的通信。 ③数据线SDA和时钟线SCL都是双向线路,都通过一个电流源或上拉电阻连接到正的电压,所以当总线空闲的时候,这两条线路都是高电平。 ④总线上数据的传输速率在标准模式下可达100kbit/s在快速模式下可达400kbit/s在高速模式下可达3.4Mbit/s。 ⑤总线支持设备连接个数:同时支持多个主机和多个从机,连接到总线的接口数量只由总线电容是400pF的限制决定,如以下图所示:
1.有效数据:在时钟的高电平周期内,SDA线上的数据必须保持稳定,数据线仅可以在时钟SCL为低电平时改变。
2.起始和结束条件: 起始条件:当SCL为高电平的时候,SDA线上由高到低的跳变被定义为起始条件,如以下图所示:
结束条件:当SCL为高电平的时候,SDA线上由低到高的跳变被定义为停止条件,如下图所示:
注意:注意起始和终止信号都是由主机发出的,总线在起始条件之后,视为忙状态,在停止条件之后被视为空闲状态。 3.应答:每当主机向从机发送完一个字节的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到了数据。 注意:从机应答主机所需要的时钟仍是主机提供的,应答出现在每一次主机完成8个数据位传输后紧跟着的时钟周期,低电平0表示应答,1表示非应答
4.数据帧格式:I2C总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。
写操作:S为起始信号,SLAVE ADDRESS从机地址(7bit)+W(0)一共8位,有阴影的部分是主机发送的,而没有阴影部分是从机发送到主机的,A/A非(0/1),P代表停止信号。
读操作:S为起始信号,SLAVE ADDRESS从机地址(7bit)+R(1)一共8位,有阴影的部分是主机发送的,而没有阴影部分是从机发送到主机的,A(应答)/A非(0/1),P代表停止信号,注意:假如主机一直返回应答信号,那么从机可以一直发送数据,也就是图中的(n byte + 应答信号)情况,直到主机发出非应答信号,从机才会停止发送数据。
如何编写IIC驱动代码:1.起始信号代码编写:
/* 产生IIC起始信号 */
void IIC_Start(void)
{
SDA_OUT(); /* sda线输出 */
IIC_SDA=1; /* ① */
IIC_SCL=1; /* ② */
delay_us(5); /* ③ */
IIC_SDA=0; /* ④ */
delay_us(5); /* ⑤ */
IIC_SCL=0; /* ⑥ */
}
上述起始信号函数①代表上图的①,而函数②代表上图②,其他类似。 2.停止信号代码编写:
/* 产生IIC停止信号 */
void IIC_Stop(void)
{
SDA_OUT(); /* sda线输出 */
IIC_SCL=0; /* ① */
IIC_SDA=0; /* ② */
delay_us(5); /* ③ */
IIC_SCL=1; /* ④ */
IIC_SDA=1; /* ⑤ */
delay_us(5); /* ⑥ */
}
上述起始信号函数①代表上图的①,而函数②代表上图②,其他类似。 3.主机产生应答代码编写:
/* 产生ACK应答 */
void IIC_Ack(void)
{
IIC_SCL=0; /* ① */
SDA_OUT(); /* sda线输出 */
IIC_SDA=0; /* ② */
delay_us(5);
IIC_SCL=1; /* ③ */
delay_us(5); /* ④ */
IIC_SCL=0; /* ⑤ */
}
上述起始信号函数①代表上图的①,而函数②代表上图②,其他类似。
4.主机产生非应答代码编写: /* 不产生ACK应答 / void IIC_NAck(void) { IIC_SCL=0; / ① / SDA_OUT(); / sda线输出 / IIC_SDA=1; / ② / delay_us(2); IIC_SCL=1; / ③ / delay_us(4); / ④ / IIC_SCL=0; / ⑤ */ }
述起始信号函数①代表上图的①,而函数②代表上图②,其他类似。 5.等待从机发送应答信号代码编写: 思路:先让SDA=1,再判断在一定时间内SDA是否变为0,从而识别出外设有没有发送应答信号。
/* 等待应答信号到来*/
/* 返回值: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) /* 获取SDA电平*/
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0; /* 时钟输出0 */
return 0;
}
第一步.设置SDA为输入 第二步.拉高SDA:主要判断从机应答就是把SDA拉低。 第三步.拉高SCL:数据稳定就是有效数据。 第四步.等待接收器返回应答信号,如果数据线SDA一直为高,就一直等待ucErrTime大于250,并返回1(无效应答),如果数据线SDA为低,返回0(有效应答)。 6.IIC发送一个字节发送一个字节的代码编写: 思路:数据传输过程中,数据传输保持稳定(在SCL高电平期间,SDA一直保持稳定,没有跳变),只有当SCL被拉低后,SDA才能被改变在SCL为高电平期间(有效数据时间段),发送数据,发送8次数据,如果数据为1,显然SDA是被拉高;如果数据为0,那么SDA被拉低。 /* IIC发送一个字节*/ /* 返回从机有无应答*/ /* 1,有应答*/ /* 0,无应答 */
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0; /* ① */
for(t=0;t>7; /* ② */
txd
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?