IIC总线设计①——IIC通信协议

目录

一、IIC(Inter-Integrated Circuit)总线介绍

二、IIC协议

(一)IIC通信过程

(二)起始信号和停止信号

程序

(三)应答信号和非应答信号

 程序

(四)数据有效性

1.读一个字节程序

2.写一个字节程序


一、IIC(Inter-Integrated Circuit)总线介绍

IIC总线设计①——IIC通信协议_第1张图片

1.用于连接微控制器及其外围设备,多用与主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机。在CPU与被控IC之间,IC与IC之间进行双向传送,高速IIC总线可达400kbps以上。

2.IIC总线上的每个设备都有自己的一个唯一的地址,来确保不同设备之间访问的准确性。

3.IIC总线上一共只有两个总线,一条是双向的串行数据线SDA,一条是串行时钟线SCL

4.传输数据的设备间是简单的主/从关系(即数据传输是从主机发起,从机接收,从机不可能主动引起数据传输)

5.串行的8位双向数据传输。

6.IIC的高阻态:用于输入/输出,可独立输入/输出低电平和高阻状态,若需要产生高电平,则需使用外部上拉电阻。高阻状态是是三态门电路的一种状态。逻辑门的输出除了有高,低电平两种状态外,还有第三种状态—高阻状态的门电路,电路分析时可看做开路理解。为了避免总线信号的混乱,IIC的空闲状态有外部上拉,而此时空闲设备被拉到了高祖态,相当于断路,整个IIC总线只有开启了的设备才会正常进行通信,而不会干扰到其他设备。

二、IIC协议

IIC总线设计①——IIC通信协议_第2张图片

(一)IIC通信过程

        首先由主机产生一个起始信号(START),此时连接到IIC总线上的所有从机都会接收这个信号,所有从机开始等待主机接下来发送的第一个命令字节(共8位,高7位表示从机地址,最低位表示读、写),在总线上,每个设备的地址都是唯一的,当主机发送了命令字节后,所有从机会开始进行地址匹配,当某设备地址与主机发送的地址相同时,这个设备就被选中了,没有选中的设备会忽略之后的所有信息,继续保持高阻态连接。当从机匹配到地址后,从机会向主机发送一个应答信号(ACK),只有主机接收到应答信号之后,主机才能继续发送或接收信号。

        当读写位配置为0时,表示由主机向从机写数据。当主机接收到从机的应答信号之后,主机开始正式向从机发送数据,数据以字节为单位传输,主机每发送完一个字节数据,都要等待从机的应答信号(ACK),重复这个过程,主机可以向从机传输N个数据,传输字节数量没有限制。当数据传输结束时,主机向从机发送一个停止传输信息(STOP),表示不再传输数据。

        当读写位配置为1时,表示由主机向从机读数据。当主机接收到从机的应答信号之后,主机开始正式从从机读取数据,数据也是以字节为单位传输,从机每发送完一个字节数据,都会等待主机发送应答信号(ACK),重复这个过程,主机可以从从机读取N个数据,传输字节数量没有限制。当传输结束时,主机向从机发送一个非应答信号(NACK),则从机停止发送数据。

(二)起始信号和停止信号

当 SCL 线是高电平时 SDA 线从高电平向低电平切换,这个情况表示通讯的起始。当 SCL 是高电平时 SDA线由低电平向高电平切换,表示通讯的停止。起始和停止信号一般由主机产生。
IIC总线设计①——IIC通信协议_第3张图片

程序

/*
*********************************************************************************************************
*	函 数 名: IIC_Start
*	功能说明: CPU发起IIC总线启动信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
static void IIC_Start(void)
{
	/* 当SCL高电平时,SDA出现一个下跳沿表示IIC总线启动信号 */
	IIC_SDA_1();
	IIC_SCL_1();
	IIC_Delay();
	IIC_SDA_0();
	IIC_Delay();
	IIC_SCL_0();
	IIC_Delay();
}
/*
*********************************************************************************************************
*	函 数 名: IIC_Start
*	功能说明: CPU发起IIC总线停止信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
static void IIC_Stop(void)
{
	/* 当SCL高电平时,SDA出现一个上跳沿表示OLED_IIC总线停止信号 */
	IIC_SDA_0();
	IIC_SCL_1();
	IIC_Delay();
	IIC_SDA_1();
}

(三)应答信号和非应答信号

        若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号,发送方会继续发送下
一个数据;若接收端希望结束数据传输,则向对方发送“非应答(NACK)”信号,发送方接
收到该信号后会产生一个停止信号,结束信号传输,等待应答期间,SDA为高电平表示非应答信号,为低电平表示应答信号。

IIC总线设计①——IIC通信协议_第4张图片

 程序

/*
*********************************************************************************************************
*	函 数 名: IIC_Ack
*	功能说明: CPU产生一个ACK信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
static void IIC_Ack(void)
{
	IIC_SDA_0();	/* CPU驱动SDA = 0 */
	IIC_Delay();
	IIC_SCL_1();	/* CPU产生1个时钟 */
	IIC_Delay();
	IIC_SCL_0();
	IIC_Delay();
	IIC_SDA_1();	/* CPU释放SDA总线 */
}

/*
*********************************************************************************************************
*	函 数 名: IIC_NAck
*	功能说明: CPU产生1个NACK信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
static void IIC_NAck(void)
{
	IIC_SDA_1();	/* CPU驱动SDA = 1 */
	IIC_Delay();
	IIC_SCL_1();	/* CPU产生1个时钟 */
	IIC_Delay();
	IIC_SCL_0();
	IIC_Delay();	
}

(四)数据有效性

在时钟的高电平周期内,SDA线上的数据必须保持稳定,数据线仅可以在时钟SCL为低电平时改变,如下图。

IIC总线设计①——IIC通信协议_第5张图片

1.读一个字节程序

/*
*********************************************************************************************************
*	函 数 名: IIC_ReadByte
*	功能说明: CPU从IIC总线设备读取8bit数据
*	形    参:无
*	返 回 值: 读到的数据
*********************************************************************************************************
*/
static uint8_t IIC_ReadByte(void)
{
	uint8_t i;
	uint8_t value;

	/* 读到第1个bit为数据的bit7 */
	value = 0;
	for (i = 0; i < 8; i++)
	{
		value <<= 1;
		IIC_SCL_1();
		IIC_Delay();
		if (IIC_SDA_READ())
		{
			value++;
		}
		IIC_SCL_0();
		IIC_Delay();
	}
	return value;
}

2.写一个字节程序

/*
*********************************************************************************************************
*	函 数 名: IIC_SendByte
*	功能说明: CPU向IIC总线设备发送8bit数据
*	形    参:_ucByte : 等待发送的字节
*	返 回 值: 无
*********************************************************************************************************
*/
static void IIC_SendByte(uint8_t _ucByte)
{
	uint8_t i;

	/* 先发送字节的高位bit7 */
	for (i = 0; i < 8; i++)
	{		
		if (_ucByte & 0x80)
		{
			IIC_SDA_1();
		}
		else
		{
			IIC_SDA_0();
		}
		IIC_Delay();
		IIC_SCL_1();
		IIC_Delay();	
		IIC_SCL_0();
		if (i == 7)
		{
			 IIC_SDA_1(); // 释放总线
		}
		_ucByte <<= 1;	/* 左移一个bit */
		IIC_Delay();
	}
}

至此,相信读者已经对IIC总线有了初步认识,具体的IIC如何应用可能还是一脸懵逼的,但是不要慌,下一期我们使用IIC通信协议对24C32(EEPROM存储器)进行读写操作,安排!

你可能感兴趣的:(课程设计-IIC总线,stm32,单片机)