STM32 软件模拟IIC

0、系列目录

  1. STM32 软件模拟IIC
  2. STM32 使用DMP库处理MPU6050数据
  3. STM32 MPU6050与匿名上位机通讯(V2.6版)

1、IIC通讯过程

在这里插入图片描述
SCL和SDA在空闲时候均为高电平。
MCU接收到通讯命令后,首先广播从机地址(例:MPU6050地址为0x68,0x69)+读/写操作,从机收到后产生应答,随后开始SCL强制拉低,开始传送一字节数据
①收到应答信号后,继续传送第二个字节……
②收到非应答信号后,停止传输

2、IIC通讯协议

在这里插入图片描述
从图中可以看到
IIC起始信号:SCL保持高电平,SDA从高电平跳变到低电平
IIC结束信号:SCL保持高电平,SDA从低电平跳变到高电平
开始和结束信号的SCL相同,SDA相反。
IIC应答信号:STM32接收到8bit的数据后,向发送数据的外设发送低电平,表示收到数据,CPU向外设发出信号后,等待外设发送一个应答信号,接收到应答信号后判断是否要继续传递数据。未收到应答,表示外设故障。

复合通讯协议

在这里插入图片描述

3、有效数据传输

在这里插入图片描述
IIC的SCL在高电平的时候会读取SDA,所以必须保持SDA电平时间多于SCL高电平时间,数据有效。
在软件模拟IIC通讯时,不需要IIC时必须保持SCL和SDA为高电平,在广播从机地址得到应答后,必须保持SCL为低电平,相当于钳制住SCL,以保证MCU与从机正常通讯。

4、代码示例

代码的编写要严格按照IIC的通讯协议控制IO的电平,否则会出现数据错误。

/**  
  *  功能:软模拟IIC引脚初始化 PB6->SCL  PB7->SDA
  *  入口参数:无
  *  返回值:无
  */
void IIC_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7);
	
}
//IIC操作的宏定义
//IO方向设置
#define SDA_IN() 			{GPIOB->CRL &= 0x0FFFFFFF;GPIOB->CRL |=(u32)8<<28;}
#define SDA_OUT() 			{GPIOB->CRL &= 0x0FFFFFFF;GPIOB->CRL |=(u32)3<<28;}

//IO操作函数
#define IIC_SCL				PBout(6)
#define IIC_SDA				PBout(7)//输出数据
#define READ_SDA			PBin(7)//读数据

起始信号

/**  
  *  功能:IIC开始信号 SCL保持高电平,SDA从高电平跳变到低电平
  *  入口参数:无
  *  返回值:无
  */
void IIC_Start(void)
{
	SDA_OUT();
	IIC_SDA=1;
	IIC_SCL=1;
	delay_us(4);
	IIC_SDA=0;
	delay_us(4);
	IIC_SCL=0;//钳制IIC总线,准备发送或接受数据
}

结束信号

/**  
  *  功能:IIC结束信号 SCL保持高电平,SDA从低电平跳变到高电平
  *  入口参数:无
  *  返回值:无
  */	
void IIC_Stop(void)
{
	SDA_OUT();
	IIC_SDA=0;
	IIC_SCL=0;
	delay_us(4);
	IIC_SCL=1;
	IIC_SDA=1;
	delay_us(4);
}

等待应答信号ACK

/**  
  *  功能:等待应答信号ACK
  *  入口参数:无
  *  返回值:0,接受应答成功;1,接受应答失败
  */
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime = 0;
	SDA_IN();
	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;
	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;
}

发送一个字节数据

/**  
  *  功能:IIC发送一个字节(8 bit)
  *  入口参数:无
  *  返回值:返回从机有无应答。0,无应答;1,有应答
  */
void IIC_Send_Byte(u8 txd)
{
	u8 t;
	SDA_OUT();
	IIC_SCL=0;//拉低IIC总线时钟开始数据传输
	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);
	}
}

读取一个字节数据

/**  
  *  功能:IIC读取一个字节(8 bit)
  *  入口参数:ack,应答
  *  返回值:一个字节(8 bit)
  */
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();
	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;
}

总结

IIC通讯协议不难,只需要按照协议,一步一步控制IO的电平,就可以模拟出IIC通讯,下篇会使用软模拟IIC获取MPU6050的原始数据,牵扯到IIC的连续读和连续写。连续读写,以及与MCU与从机之间的通讯方式非常重要,本节作为基础,理解最好。

Python可以通过使用GPIO口来模拟IIC(I2C)通信协议。通过控制GPIO口的高电平和低电平来复制出与I2C通信协议相同的波形。这样可以实现对IIC从机设备的读写操作。 首先,你需要确保你的设备上安装了Python的GPIO库,例如RPi.GPIO或者Adafruit_GPIO等。然后,你可以使用GPIO库的函数来控制GPIO口的状态,以实现模拟IIC通信。 在Python中,你可以定义一个函数,使用GPIO库的函数来控制GPIO口的高低电平。你可以使用循环和延时来控制时序,发送和接收数据。 在模拟IIC通信的过程中,你需要发送起始条件、器件地址、数据和控制信号等。具体的实现方法可以参考GPIO库的文档和示例代码。 总结起来,要使用Python来模拟IIC通信,你需要: 1. 确保安装了合适的GPIO库; 2. 使用GPIO库的函数来控制GPIO口的状态,复制出与I2C通信协议相同的波形; 3. 发送起始条件、器件地址、数据和控制信号等; 4. 参考GPIO库的文档和示例代码,根据具体需求进行适当的修改和调试。 注意,由于不同的硬件平台和操作系统可能有所差异,所以在Windows下模拟IIC通信可能会略有不同。但是,基本的原理和方法是相同的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [IO口软件模拟IIC](https://blog.csdn.net/zhejfl/article/details/82866684)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [GPIO实现I2C协议模拟(1)](https://blog.csdn.net/weixin_36181191/article/details/114020192)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个旅者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值