I2C软件模拟操作流程,I2C的一般工作流程

I2C的硬件接口

I2C的接口一般分成两个部分,SDA和SCK,I2C的时钟采取同步时钟模式,即主机产生时钟同时提供给从机和自身,而SDA有且只有一条线,这也就体现了I2C的半双工工作模式,即在同一时间内,SDA只能起到向从机写和从从机读的功能,而不能同时进行,这也造就了I2C的特点:通讯速率慢。

I2C的通讯协议设置

I2C的通讯协议如下图所示:
在这里插入图片描述

如图,我将对其进行简要说明:

  1. 在初始条件下,SCL和SDA均为高电平,随后在SCL为高电平期间,下拉SDA,是起始条件,如果要通过软件进行模拟,可做如下表示:
MYI2C_SDA_W(1);
MYI2C_SCL_W(1);
MYI2C_SDA_W(0);
MYI2C_SCL_W(0);

这就完成了I2C的起始配置,相当于说:“嘿!准备好了,我要开始发送信息了!”

2.接下来要发送从机的地址位,I2C的写地址遵循高位在前的原则,以OLED的数据手册为例
如图
如图所示,为了防止一个主机连接多个相同型号的从机,b1位作为拓展位可供选择,其中引脚D/C#的所接高低电平影响该位置0或置1,我们看一下原理图:
在这里插入图片描述
在I2C通讯模式下该引脚接地,置0.因此地址位的前七位是:0111100
最后一位决定读写,SSD1306只支持写功能,因此置0,01111000因此发送0X78.
现在的问题在于,如何使用软件实现写8位数据的功能呢,这里我们要从发送一位数据说起。由于I2C的软件特性,我们如果从一个时序周期来理解的话,可以这样简化:在SCL低电平期间,改变SDA的高低电平,在SCL高电平期间,不改变SDA,读取SDA电平,代码实现如下:

void MYI2C_SendByte(uint8_t Byte)
{
   for(uint8_t i=0;i<8;i++)
   {
    MYI2C_SDA_W((0x80>>i) & Byte);//判断该位是高位还是低位
    MYI2C_SCL_W(1);//高电平期间读取
    MYI2C_SCL_W(0);//重新置低电平,为下一次写做准备
   }
}

如此便实现了发送一个字节,是不是简单愉悦呢,笑。

  1. 在我们发送从机地址后,从机将操纵SDA总线进行应答。如果收到,就叫一声高电平,否则就沉默不语,可怜巴巴。那么,再让我们写一下ACK接收函数吧,要注意哦,每个时序的结束和开始,SCL都处在低电平`
uint8_t MYI2C_ReceiveACK(void)
{

MYI2C_SDA_W(1);//主机释放SDA,交给从机操作
MYI2C_SCL_W(1);//将时钟置高,准备做读操作
i=MYI2C_SDA_R();
MYI2C_SCL_W(0);
return i;
}
  1. 我们主机在接收到从机应答后,就可以开始愉快的写数据了,在最后,我们要知道如何中止一个I2C时序,中止过程就是在SCL高电平期间,将SDA拉高,给SCL一种:”呦!你小子要造反!“的感觉,这样就完成了时序的中止。代码如下:
void MYI2C_Finsh(void)
{
MYI2C_SDA_W(0);
MYI2C_SCL_W(1);
MYI2C_SDA_W(1);

}

其实,我们在初始化I2C的时候,之所以先拉高SDA,再拉高SCL就是为了防止在重复起始位时,SCL先置1,SDA再置1而导致中止位置提前出现

在下一节中。我们将学习如何利用I2C的通讯知识对SSD1306进行操作,最后会实现OLED上随心所欲的绘图功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值