stm32软件模拟I2C

一  概述

  很多人都知道stm32的硬件I2C存在BUG,现在我们通过软件模拟时序的办法来实现I2C。


  使用软件模拟I2C主要是方便程序的移植,只需要更改一下相应的IO端口即可。


二 软件模拟实现

1 起始信号

void i2c_Start(void)
{
	macI2C_SDA_1();  //首先确保SDA和SCL都是高电平
	macI2C_SCL_1();
	i2c_Delay();
	macI2C_SDA_0();  //先拉低SDA
	i2c_Delay();
	macI2C_SCL_0();  //在拉低SCL
	i2c_Delay();
}

2 总线产生停止信号

void i2c_Stop(void)
{
	
	macI2C_SDA_0();  //首先确保SDA是低电平
	macI2C_SCL_1();  //先拉高SCL
	i2c_Delay();
	macI2C_SDA_1();  //在拉高SDA
}
3 CPU向I2C总线设备发送8bits的数据

void i2c_SendByte(uint8_t _ucByte)
{
	uint8_t i;

	for (i = 0; i < 8; i++)
	{		
		if (_ucByte & 0x80)
		{
			macI2C_SDA_1();
		}
		else
		{
			macI2C_SDA_0();  
		}
		i2c_Delay();
		macI2C_SCL_1();
		i2c_Delay();	
		macI2C_SCL_0();
		if (i == 7)
		{
			 macI2C_SDA_1(); // 8位数据发送完毕后,主机释放SDA,以检测从机应答
		}
		_ucByte <<= 1;  //左移1个bit
		i2c_Delay();
	}
}
4 CPU从I2C总线读取8个bits的数据

uint8_t i2c_ReadByte(void)
{
	uint8_t i;
	uint8_t value;

	/*读取到的第一个bit为bit7*/
	value = 0;
	for (i = 0; i < 8; i++)
	{
		value <<= 1;
		macI2C_SCL_1();
		i2c_Delay();
		if (macI2C_SDA_READ())
		{
			value++;
		}
		macI2C_SCL_0();
		i2c_Delay();
	}
	return value;
}
5 CPU产生一个时钟,并且读取器件的ACK应答信号

uint8_t i2c_WaitAck(void)
{
	uint8_t re;

	macI2C_SDA_1();	 //CPU释放SDA总线
	i2c_Delay();
	macI2C_SCL_1();	 //CPU驱动SCL=1,此时器件会返回ACK应答
	i2c_Delay();
	if (macI2C_SDA_READ())	//CPU读取SDA口线状态
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	macI2C_SCL_0();
	i2c_Delay();
	return re;
}
6 CPU产生一个ACK信号

void i2c_Ack(void)
{
	macI2C_SDA_0();	
	i2c_Delay();
	macI2C_SCL_1();	
	i2c_Delay();
	macI2C_SCL_0();
	i2c_Delay();
	macI2C_SDA_1();	
}

7 CPU产生一个NACK信号(NACK即无应答信号)

void i2c_NAck(void)
{
	macI2C_SDA_1();	 //CPU驱动SDA产生1
	i2c_Delay();
	macI2C_SCL_1();	 //CPU驱动SCL产生1
	i2c_Delay();
	macI2C_SCL_0();
	i2c_Delay();	
}
8 I2C总线位延时

static void i2c_Delay(void)
{
	uint8_t i;
	for (i = 0; i < 10; i++);
}
对于I2C总线延时来说,不同的单片机写法是不相同的,参考野火的程序,当CPU主频为72MHz时,在内部Flash运行,同时MDK不做优化的情况下


循环次数为10时,SCL频率为205KHz

循环次数为7时,SCL频率为347KHz,SCL高电平时间为1.5us,SCL低电平时间为2.87us

后记:关于I2C通信,我还是有几处地方没有搞明白,这里的程序只是写好了具体的底层封装,对于不同的外设,如AT24C02,MPU6050,应用起来肯定是不相同的,等搞明白其他的一些问题后,我会继续补充这篇文章。



参考资料

1 http://blog.csdn.net/subkiller/article/details/6854910  《I2C总线协议》

2 《手把手教你学51单片机》

3 野火stm32指南者开发板程序

你可能感兴趣的:(STM32)