STM32学习-IIC

* IIC文件均已上传资源,可直接下载 *

* 无法直接下载,联系qpc6259@outlook.com *

IIC原理简述

IIC(Inter-Integrated Circuit)是一种由串行数据(SDA)线和串行时钟(SCL)线组成的串行通信总线,总线最大速度为400 kHz。一般来说,SDA和SCL信号线是开漏、双向的。实现流程概述为:在连接的设备中,主设备将某个从设备地址放在总线上发送,而匹配该地址的从设备会对主设备进行应答,不匹配的设备将不会进行应答。

IIC通信协议

IIC通信流程中,包括开始(S)、停止(P)、地址和读/写位(ADD+W / R)、应答(ACK / NACK)、数据(DATA),如图1所示。

图1 IIC数据传输时序图

延时函数

新建一个延时函数,主要是为了后面改操作之间时间间隔方便。

#define IIC_Delay()	delay_us(10)

开始(S)和停止(P)

起始条件(S):SDA线由高向低转换,同时SCL线为高电平(图2)。

停止条件(P):SDA线由低向高转换,同时SCL线为高电平(图2)。

图2 起始条件和停止条件时序图

下面是时序在程序上的体现(在起始条件中,最好先把SDA线置高,再将SCL线置高)。

起始条件:

/**	@brief	产生一个IIC通信开始信号
	*	@param	None
	*	@note		SDA	---             1
	*                       \
	*                        \
	*						   -----    0
	*					SCL	----------	1
	*	@retval	None
	*/
	
void IIC_Start()
{
	SDA(1);
	IIC_Delay();
	SCL(1);
	IIC_Delay();
	SDA(0);
	IIC_Delay();
	SCL(0);				//钳住SCL线,为后面的操作做准备
	IIC_Delay();
}

结束条件:

/**	@brief	产生一个IIC通信停止信号
	*	@param	None
	*	@note		SDA			   ---	1
	*							  /
	*							 /
	*					    -----		0
	*					SCL	----------	1
	*	@retval	None
	*/

void IIC_Stop()
{
	SDA(0);
	IIC_Delay();
	SCL(1);
	IIC_Delay();
	SDA(1);
	IIC_Delay();
}

应答 / 非应答信号(ACK / NACK)

在SDA线上传输的数据为1字节(8位)长,并且每次传输的数据字节数没有限制,但是每传输一个字节须跟一个确认信号(ACK)。确认信号的信号由主机产生:通过拉低(ACK)SDA线或者保持高(NACK)SDA线,同时保持一段时间(SCL线产生脉冲信号的高电平期间)从而生成应答信号。

图3 应答 / 非应答信号时序图

/**	@brief	发送一个应答 / 未应答信号
	*	@param	AckBit:1	未应答
	*					0	应答
	*	@note		SDA --------------	0 / 1
	*				SCL		 ----		1
	*					    /	 \
	*					   /      \
	*					---		   ---	0	
	*	@retval	None
	*/

void IIC_SendAck(uint8_t AckBit)
{
	SDA(AckBit);
	IIC_Delay();
	SCL(1);
	IIC_Delay();
	SCL(0);
	IIC_Delay();
}

等待应答信号(Wait ACK)

 因为每次发送数据后需要跟一个应答信号,所以在每次发送 / 接收完信号后需要等待一段时间,用来接收应答信号。此时主机进入等待状态,直到接收到来自从设备的应答信号。(文中没有在后面判断是否接收到ACK信号,有需要可以加一下)

/**	@brief	接收一个应答 / 未应答信号
	*	@param	None
	*	@note		SDA --------------	0 / 1
	*				SCL		 ----		1
	*						/	 \
	*					   /	  \
	*					---		   ---	0	
	*	@retval	AckBit:接收到的应答 / 未应答信号
	*/

uint8_t IIC_ReceiveAck()
{
	uint8_t AckBit;
	
	SDA(1);
	IIC_Delay();
	SCL(1);
	IIC_Delay();
	AckBit = SDA_READ;
	IIC_Delay();
	SCL(0);
	IIC_Delay();
	return AckBit;
}

地址和读/写位(ADD+W / R)

在起始条件出现开始通信后,主机需要在SDA线上发送一个8位的数据(由7位的从机地址和1位读/写位组成),其中读/写位是告诉主机应该是向从机写入数据还是从从机读取数据。

数据写入(W)

写1字节数据:

 /**	@brief	发送一个字节的数据
	*	@param	data:待发送的数据
	*	@note	SDA --------------	0 / 1
	*		    SCL		 ----		1
	*					/	 \
	*				   /	  \
	*				---		   ---	0	
	*	@retval	None
	*/

void IIC_Send_Byte(uint8_t data)
{
	uint8_t i;
	
	for(i = 0; i < 8; i++)
	{
		SDA(data & (0X80 >> i));	//一位一位发送数据
		IIC_Delay();
		SCL(1);
		IIC_Delay();
		SCL(0);
		IIC_Delay();
	}
}

数据读取(R)

读一个字节:

/**	@brief	读取一个字节的数据
  *	@param	None
  *	@note	SDA --------------	0 / 1
  *			SCL	     ----		1
  *					/	 \
  *				   /	  \
  *				---		   ---	0	
  *	@retval	Receive_Data:接收到的一字节的数据
  */

uint8_t IIC_Receive_Byte()
{
	uint8_t i, Receive_Data = 0x00;
	
	SDA(1);    //先拉高,等待从设备拉低
	IIC_Delay();
	
	for(i = 0; i < 8; i++)
	{
		SCL(1);
		IIC_Delay();
		
		if(SDA_READ)
			Receive_Data |= (0x80 >> i);	//一位一位接收数据
		
		SCL(0);
		IIC_Delay();
	}
	
	return Receive_Data;	//返回读取到的数据
}
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值