i2c讲解以及zyqn中的使用

i2c讲解以及zyqn中的使用

什么是i2c

https://blog.csdn.net/qq_39829913/article/details/104718185
这个i2c讲的非常好

它是电平触发采集的,不是边沿,时钟为0的时候,数据可以发生变化,的一种同步通信,IIC使用两根信号线进行通信:一根时钟线SCL,一根数据线SDA。IIC将SCL处于高时SDA拉低的动作作为开始信号,SCL处于高时SDA拉高的动作作为结束信号;传输数据时,SDA在SCL低电平时改变数据,在SCL高电平时保持数据,每个SCL脉冲的高电平传递1位数据。

工作时序:

  1. 数据有效性
    在scl为高的时候,sda才有效
  2. 开始和结束
    开始:在scl为高的时候,sda从高变低
    结束:在scl为高的时候,sda从低变高
  3. 重复开始信号
    重复开始信号(ReSTART/Sr): 在结束时不给出STOP信号,而以一个时钟周期内再次给出开始信号作为替代
  4. 字节格式
    SDA数据线上的每个字节必须是8位,对于每次传输的字节数没有限制。每个字节(8位)数据传送完后紧跟着应答信号(ACK,第9位)。数据的先后顺序为:高位在前 。
  5. 应答信号
    协议规定数据传输过程必须包含应答(ACK)。接收器通过应答告知发送的字节已被成功接收,之后发送器可以进行下一个字节的传输。主机产生数据传输过程中的所有时钟,包括用于应答的第9个时钟。发送器在应答时钟周期内释放对SDA总线的控制,这样接收器可以通过将SDA线拉低告知发送器:数据已被成功接收。
      应答信号分为两种:
        1)当第9位(应答位)为 低电平 时,为 ACK  (Acknowledge)   信号
        2)当第9位(应答位)为 高电平 时,为 NACK(Not Acknowledge)信号
      主机发送数据,从机接收时,ACK信号由从机发出。当在SCL第9位时钟高电平信号期间,如果SDA仍然保持高电平,则主机可以直接产生STOP条件终止以后的传输或者继续ReSTART开始一个新的传输
      从机发送数据,主机读取数据时,ACK信号由主机给出。主机响应ACK表示还需要再接收数据,而当主机接收完想要的数据后,通过发送NACK告诉从机读取数据结束、释放总线。随后主机发送STOP命令,将总线释放,结束读操作。

总线速度

在这里插入图片描述

在这里插入图片描述

为什么双向最高位3.4Mbps?

  1. 电气特性: I2C总线使用开漏(open-drain)或开集(open-collector)方式驱动,需要通过上拉电阻来提供高电平。这种设计使得数据线可以被任何一个设备拉低,以实现多主机控制。然而,这也意味着信号边沿的上升时间受到了限制,特别是在总线负载较重(许多设备连接到总线上)或总线电容较大的情况下。较慢的上升时间限制了最高传输速度。

  2. 时序和容错: 为了确保通信的可靠性,I2C协议定义了一系列时序要求,包括起始条件、停止条件、数据有效性等。这些时序要求确保了数据的完整性和设备之间的同步,但也对传输速率造成了限制。此外,协议还必须容纳一定的电气噪声和信号退化,这意味着必须有足够的时序余量来应对这些问题。

  3. 标准和模式: I2C协议定义了几种不同的速率模式,包括标准模式(最高100kbps)、快速模式(最高400kbps)、快速模式加(Fast Mode Plus,最高1Mbps)和高速模式(High Speed Mode,最高3.4Mbps)。每种模式都有其电气特性和时序要求,以适应不同的应用场景和性能需求。3.4Mbps的限制是高速模式下的最大速率,是通过改进驱动能力和时序控制来实现的。

  4. 兼容性和通用性: I2C总线的设计考虑了广泛的兼容性和通用性,以支持各种不同性能级别的设备共存。这意味着总线协议和电气特性必须在保持低成本和简单设计的同时,提供足够的通信速度。过高的速度可能会增加设计的复杂性和成本,同时减少与低速设备的兼容性。

IIC的IO有什么特点

https://blog.csdn.net/jiangdf/article/details/72779046
IIC总线上所有器件的SDA、SCL引脚输出驱动都为 开漏(OD) 结构,通过外接上拉电阻实现总线上所有节点SDA、SCL信号的线与逻辑关系。
在这里插入图片描述

oc门和od门

oc门与od门的基础知识

https://zhuanlan.zhihu.com/p/555471581
这个视频讲的挺好
https://www.bilibili.com/video/BV1EJ411T76A/?spm_id_from=333.337.search-card.all.click&vd_source=4a58493d16f50229c3283d2be2c272ba

oc门和od门的功能

在这里插入图片描述

推挽电路

推挽输出两个管子始终处在一个导通另一个截止的状态。
在这里插入图片描述

但是推挽不能实现线与功能。

开漏od和开集oc

开漏和开集差不多,一个是cmos管,一个是三极管,现在就以三极管的oc来说,具体看知乎连接
在这里插入图片描述

因为 OC/OD 门电路不具备输出高电平的能力,所以在一般应用中,是需要外接上拉电阻的。 接上上拉电阻之后,输出是1就是三极管截止,输出是0就是三极管导通接地,不同的带上拉电阻的oc门都可以输出端相连,实现线与功能

i2c访问温度传感器芯片SI7021

已经是硬核的i2c,arm直接调用函数即可

首先初始化i2c

int InitialIic(XIicPs *iic, XIicPs_Config *config)
{
	int Status;
	//查找外设设备的配置结构体;
	config = XIicPs_LookupConfig(IIC_DEVICE_ID);
	//判断指针是否为空
	if (NULL == config) {
		return XST_FAILURE;
	}
	//通过配置结构体进行初始化外设;
	Status = XIicPs_CfgInitialize(iic, config, config-> BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	//设置 IIC速率;
	Status = XIicPs_SetSClk(iic, IIC_SCLK_RATE);//这里设置的是100k
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}

温度湿度寄存器的读操作

读寄存器时序(分两个步骤),
在这里插入图片描述

  1. 通过写命令设置准备读的寄存器地址,i2c读之前要先写设备id+写命令、温湿度寄存器地址,
    在这里插入图片描述

这里用封装好的函数来

	status = XIicPs_MasterSendPolled(iic, &HumCmd,ByteCount_part1,IIC_SLAVE_ADDR);//IIC_SLAVE_ADDR为设备id,HumCmd为寄存器地址,ByteCount_part1是要写入的字节数(因为寄存器地址为1个字节所以设置为1)
	if (status != XST_SUCCESS) {
		return XST_FAILURE;
	}
  1. 然后再启动读数据,7个设备id+1个读命令
    在这里插入图片描述

这里用封装好的函数来

	status = XIicPs_MasterRecvPolled(iic, Hdata, ByteCount_part2, IIC_SLAVE_ADDR);//ByteCount_part2为2,因为要读2个字节出来,IIC_SLAVE_ADDR还要给进去,但寄存器地址不给了,满足i2c时序
	if (status != XST_SUCCESS) {
		return XST_FAILURE;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

帅癌晚期的彦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值