Embedded 如何为EFR32上的SI7021图表提供带标志的I2C功能

Embedded 如何为EFR32上的SI7021图表提供带标志的I2C功能,embedded,Embedded,下图显示了与控制器主机的I2C通信。 从下面显示的API中,我得到了以下命令,需要为其提供标志以充当图表。 我对向I2C_trnasfer证明旗帜并不敏感。 它是怎么做的? 谢谢 I2C_传输(I2C_类型定义*I2C) 这对你来说只是一个粗略的起点。你必须进行试验,找出任何问题 这意味着您必须调用I2C\u TransferInit()来设置传输。您可以尝试使用seq->flags=I2C\u FLAG\u WRITE\u READ设置单个传输。但我怀疑该方法不会在测量过程中处理从机发出的N

下图显示了与控制器主机的I2C通信。 从下面显示的API中,我得到了以下命令,需要为其提供标志以充当图表。 我对向I2C_trnasfer证明旗帜并不敏感。 它是怎么做的? 谢谢

I2C_传输(I2C_类型定义*I2C)


这对你来说只是一个粗略的起点。你必须进行试验,找出任何问题

这意味着您必须调用
I2C\u TransferInit()
来设置传输。您可以尝试使用
seq->flags=I2C\u FLAG\u WRITE\u READ
设置单个传输。但我怀疑该方法不会在测量过程中处理从机发出的NACK。因此,这段代码将其分为两次传输。第一次传输写入测量命令。第二次传输读取测量值。并且,如果由于从属测量正在进行而接收到NACK,则重复第二传输

您必须为
MEASURE\u CMD
SLAVE\u ADDRESS
提供值。但是
I2C\u标志*
值是在EFR32的em\u I2C.h中定义的

I2C_TransferSeq_TypeDef *seq;
I2C_TransferReturn_TypeDef ret;

// Write the measure command.
uint8_t meas_cmd = MEASURE_CMD;
seq->addr = SLAVE_ADDRESS;
seq->flags = I2C_FLAG_WRITE;
seq->buf[0].data = &meas_cmd;
seq->buf[0].len = 1;
ret = I2C_TransferInit(I2C0, seq);
while (ret == i2cTransferInProgress)
{
  ret = I2C_Transfer(I2C0);
}

// If the write was successful
if (ret == i2cTransferDone)
{
  // Read the measured value.
  uint8_t meas_val_bytes[2];
  seq->addr = SLAVE_ADDRESS;
  seq->flags = I2C_FLAG_READ;
  seq->buf[0].data = &meas_val_bytes[0];
  seq->buf[0].len = 2;

  // The intention of this do-while loop is to repeat the I2C_TransferInit() if the slave NACKs the read request.
  do
  {
    ret = I2C_TransferInit(I2C0, seq);
    while (ret == i2cTransferInProgress)
    {
      ret = I2C_Transfer(I2C0);
    }
  } while (ret == i2cTransferNack);

  // If the read was successful
  if (ret == i2cTransferDone)
  {
    // The first byte received is the most significant byte.
    uint16_t measured_value = (meas_val_bytes[0] << 8) + meas_val_bytes[1];
  }
}
I2C_TransferSeq_TypeDef*seq;
I2C_TransferReturn_TypeDef ret;
//编写measure命令。
uint8_t meas_cmd=MEASURE_cmd;
seq->addr=从机地址;
seq->flags=I2C_FLAG_WRITE;
seq->buf[0]。数据=&meas_cmd;
seq->buf[0]。len=1;
ret=I2C_TransferInit(I2C0,序号);
while(ret==i2cTransferInProgress)
{
ret=I2C_传输(I2C0);
}
//如果写入成功
如果(ret==i2cTransferDone)
{
//读取测量值。
uint8表示字节[2];
seq->addr=从机地址;
seq->flags=I2C_FLAG_READ;
seq->buf[0]。数据=&meas_val_字节[0];
seq->buf[0]。len=2;
//此do while循环的目的是,如果从机拒绝读取请求,则重复I2C_TransferInit()。
做
{
ret=I2C_TransferInit(I2C0,序号);
while(ret==i2cTransferInProgress)
{
ret=I2C_传输(I2C0);
}
}而(ret==i2cTransferNack);
//如果读取成功
如果(ret==i2cTransferDone)
{
//接收到的第一个字节是最高有效字节。

uint16_t measured_value=(meas_val_bytes[0]您好,我试图在您的代码中可视化图表的顺序。在我们的图表中,我们将地址和命令从主设备发送到从设备,从设备发送到它们。代码中发生了什么?@rocko445,确认是I2C协议的一部分,就像开始一样和停止(P)位。这些协议详细信息由I2C硬件外围设备和
I2C_传输
函数处理。EFR32的I2C库API将这些协议详细信息提取出来,以便您的应用程序可以关注更大的画面。您的应用程序在
seq
中提供从机地址、传输类型和传输缓冲区传递给
I2C\u TransferInit()的指令
。然后,
I2C_传输
函数和I2C硬件外围设备负责启动、停止和确认等细节。如果传输过程中出现NACK,则
I2C_传输
函数返回NACK状态,以便应用程序可以采取适当的操作。我的示例代码和图表是重复开始位(Sr)。我的代码执行两个单独的传输,每个传输都有开始和停止。因此,我的代码将重复开始位替换为停止和新开始。您必须使用I2C_标志_写_读传输类型来获得重复开始位。(然后还必须在
seq->buf
中初始化两个缓冲区)但我怀疑I2C_FLAG_WRITE_READ传输类型是否会在读取部分处理NACK。我希望它会以NACK状态结束传输,而不是尝试重复读取。因此,我将传输分为两次传输,并添加了do while循环,以便在必要时重复读取。