首页 > 其他分享 >STM32-I2C软件模拟

STM32-I2C软件模拟

时间:2024-12-26 10:53:54浏览次数:4  
标签:SCL 引脚 主机 电平 STM32 从机 SDA I2C 模拟

1.I2C介绍
I2C是一种多主机、两线制、低速串行通信总线,广泛用于微控制器和各种外围设备之间的通信。它使用两条线路:串行数据线(SDA)和串行时钟线(SCL)进行双向传输。

2.时序

启动条件:SCL高电平时、SDA由高电平变为低电平
停止条件:SCL高电平时、SDA由低电平变为高电平
除此之外,不允许在SCL高电平时变换SDA电平。

数据传输
主机发送起始信号后,通信开始,每次传输一字节数据,传输完毕后应答(ACK)
主机拉低SCL电平,此时可改变SDA的电平
主机拉高SCL电平,此时开始读取SDA电平
如此重复8次,一字节数据传输完毕,数据接收方在下一个CLK低电平在SDA上进行应答,0代表数据接收成功,1数据接收失败或通信结束。

3.通信时序

如图,主机发送完起始信号后,再次拉低SCL,并改变SDA的电平为0或1,电平改变完成后,主机拉高(释放)SCL,代表此时从机可以读取SDA数据,之后主机再拉高SLC重复操作,如此重复8次,就发送了一个字节。
主机发送完字节最后一位数据后,拉高(释放)SCL等待从机读取完成,然后拉低SCL(代表主机准备好接受ACK)并且拉高(释放)SDA,将SDA的控制权交给从机,此时收到该数据的从机会对SDA进行操作,0(拉低SDA)代表存在从机收到该字节数据,可以继续发送数据,1(拉高,或者无从机操作SDA)代表从机数据接收完毕或根本没有从机,主机发送停止信号结束通信。

读取与写入数据
仔细研究以上通信时序,我们发现时序为
Start(起始信号)+8位数据+ACK(应答)+Stop(结束信号)
那么我们怎么知道主机跟从机通信是要读取数据还是写入数据呢?
实际使用中,我们会按照约定格式进行通信。

①读取数据

a.主机发送一个起始信号Start
这时通信总线上的设备准备接受数据
b.接着发送7位从设备ID+读写位(0写1读)
从机开始解析数据,发现该ID是自己ID那就发送ACK(0,代表有从机对SDA进行了操作)拉低SDA线,继续进行通信。
如果SDA保持1,即没有任何从机作出反应,那主机就发送Stop信号结束通信
c.发送要访问的从设备寄存器地址
主设备告诉从设备我要访问你该地址的数据,从设备收到地址后再次回应一个ACK(拉低SDA,告诉主设备我收到地址数据了)
d.根据之前发送发送的读写位进行数据交换
如果是7位地址+0,即写操作,则数据为主机发送给从机,从机接收到后回复一个ACK(0,即有从机拉低SDA),直到主机发送完成,产生一个Stop信号。
如果是7位地址+1,即读操作。则此时数据为从机发送给主机,主机接收完后向从机发送ACK位,当主机读取完成后就产生一个NACK(1),之后发送Stop信号结束通信。
e.产生一个结束信号Stop
主机在SCL高时拉高SDA(本质上为释放SCL与SDA两条线路,即不对该两条线路产生任何操作)

线与特性:
I2C的时钟线(SCL)与数据线(SDA)都使用开漏输出(OD)+上拉电阻的方式进行驱动,即线上连接的IO口全都只有拉低电平的能力,当线上连接的任意一个引脚输出低电平时,整条线路都会接地处于低电平状态。而IO口输出高电平时,引脚处于浮空状态,此时线上为高电平,但只要线上连接的任意一个IO口处于低电平,那整条线路都会处于低电平。

主机引脚电平 从机引脚电平 传输线电平
0 0 0
1 0 0
0 1 0
1 1 1

为何使用开漏输出上拉电阻?
既然都是简单的电平变换,那为什么I2C要使用开漏输出呢?直接使用推挽输出,不但省下一个上拉电阻,IO口还不会因上拉电阻影响到传输速率不是更好吗?这是我们就要仔细研究一下I2C时序了。
I2C因为被设计运用在多主机多从机的场景,所以不可避免地会遇到一个问题——总线冲突
若因某种原因时序混乱导致一个IO口输出高电平,一个输出低电平,那么就会出现短路现象,有烧坏设备的风险。

正点原子软件模拟I2C引脚使用推挽输出?
那么问题来了,正点原子例程中软件模拟I2C的GPIO配置代码如下:
GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5;
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;
GPIO_Initure.Pull=GPIO_PULLUP;
GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
我们惊讶的发现,他们将引脚的输出方式设置为了推挽输出,这是为什么?
查阅了资料,理由如下:
1.该例程的使用场景为单主-单从,即整条线上只有一个主机、一个从机,SCL不存在争抢控制权的现象。
2.在主机交出SDA控制权时,SDA引脚被设置为了输入模式
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA输入模式
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();
else
IIC_Ack();
return receive;
}
输入模式时,主机SDA引脚浮空,只对SDA上的电平进行读取,此时从机改变SDA上的电平是安全的。
综上,使用推挽输出只适用于单主从模式,并且该方式需要对SDA输入输出状态进行切换。

问题探究:
1.推挽模式读取引脚状态需要改变引脚输入输出状态,开漏难道不需要吗?
请看GPIO基本构造:

如图所示STM32引脚输出靠下方的两个MOS管进行强上拉、下拉。当使用推挽输出时会用到两个MOS管,无论输出高电平还是低电平会是引脚保持强上拉、下拉状态,因此引脚输出高电平就会读到高电平,引脚输出低电平就会读到低电平。
而使用开漏输出时只会用到下方连接GND的NMOS管,也就是说该模式只有强下拉,如果给引脚输出高电平,那么此时引脚实际处于浮空状态,受连接线上的电平影响,此时读取的电平即为连接线上的电平。

标签:SCL,引脚,主机,电平,STM32,从机,SDA,I2C,模拟
From: https://www.cnblogs.com/Osen/p/18630637

相关文章

  • 请使用es5模拟实现一个es6的symbol
    在ES5中,没有原生的Symbol类型,但我们可以尝试通过创建一个具有唯一标识符的对象来模拟Symbol的行为。请注意,这种模拟并不完全等同于ES6的Symbol,但它可以提供类似的功能。以下是一个简单的模拟实现:(function(){varsymbolRegistry={};varsymbolCounter=0;fu......
  • 【Unity 低多边形像素风格 3D 资源包】PIXELGON Muscle Cars Pack 提供了精心设计的车
    PIXELGONMuscleCarsPack是一款专注于肌肉车主题的低多边形像素风格3D资源包,包含多种经典和现代肌肉车设计,适合需要像素艺术风格的游戏项目。这款资源包提供了精心设计的车辆模型,兼具美观与性能优化,能为赛车类、城市模拟、开放世界等项目增添丰富的视觉效果。核心功能与......
  • STM32单片机定时器定时方法计算
    定时器是STM32单片机非常常见的外设,使用定时器来设置定时时间需要配置预分频系数(Prescaler)和自动重装载值(CounterPeriod)。 假设设置一个500ms的定时器,时钟频率72MHz,把预分频系数设置为7200(即写入预分频寄存器的值为7200-1),72MHz/7200=10KHz,这样就得到计数器的计数频......
  • 省选模拟 2
    T营模拟,所以四道题,梦回NOIP前模拟赛。A石子游戏(stone)点击查看天天放博弈论,博弈论是你爹吗?先打表,发现B赢麻了,A赢的时候几乎全是\(1\),前面全是\(1\),后面带了一个\(2\)的时候A也会赢,由于A每次拿一堆,B每次拿两堆,直接猜答案与\(1\),\(2\),和其他数的个数有关。考......
  • STM32外部SPI-FLASH字库实践
    背景使用STM32使用液晶屏时,对于一些点阵屏,预先需定义好相应的字模,对于12864的话,使用的自身的FLASH空间就可以存放下所需的字模,几十KB的空间。如果使用大的点阵屏,或者点阵密度较大时,且使用到的字体较多,如果只是用STM32自身的FLASH,对于一些小空间的芯片就不太够有空间去存放字模了......
  • C#开发实例2—模拟考试
    实例练习目的主要是为了体会编程思想,理解高内聚、低耦合,掌握编程思维逻辑的大招,告别垃圾代码,重点体会编程之美…目录1.软件实现的功能有哪些?(UI如何设计)2.数据在哪里获取?3.对象有哪些,它们之间的关系是什么?4.如何设计类(列出属性<成员>、方法<功能>)?5.代码实现6.软件效果7.......
  • stm32+I2C +W24C02
     首先I2C支持同步串行半双工通信,允许多个主从设备间低速通信。传输速率的话,标准模式下是100kbit/s,快速模式为400kbit/s,高速模式3.4Mbit/s(大部分设备不支持)I2C通讯时管脚应该被配置为复用开漏模式,因为它支持多个主从设备,推挽的话会造成设备间短接。使用开漏的话设备空闲统......
  • 嵌入式linux驱动框架 I2C系统驱动程序模型分析
    引言:在嵌入式Linux系统中,I2C(Inter-IntegratedCircuit)是一种常用的通信协议,用于连接低速设备(如传感器、显示器、存储器等)与主控制器。I2C系统驱动程序模型通过层次化的设计,使得I2C总线设备和驱动程序能够高效、灵活地进行通信和管理。本分析旨在详细介绍I2C驱动程序框......
  • 基于模拟数据与逻辑回归的交通流量预测模型:设计与实现全解析
    一、项目概述本项目旨在通过模拟生成的交通相关数据,构建一个逻辑回归模型来预测交通流量。通过对时间、天气、是否为周末等因素的分析,实现对交通流量的分类预测(流量高或低),并评估模型的准确性。二、功能模块设计数据生成模块功能描述:生成包含时间、天气、是否为周末以及相应交......
  • Oray Virtual Game Controller 驱动程序的主要目的是在没有物理游戏控制器的情况下,通
    OrayVirtualGameController是由OrayTechnologies,Inc.开发的一个虚拟游戏控制器驱动程序。它的版本为1.0.0.0,并且该驱动程序的发布日期是2022年12月29日。OrayVirtualGameController驱动程序简介功能:虚拟游戏控制器 是一种虚拟设备,允许通过软件模拟游戏控制......