当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Arduino setWireTimeout()用法及代码示例


说明

设置主模式下有线传输的超时时间。

注意:这些超时几乎总是表明存在潜在问题,例如设备异常、噪音、屏蔽不足或其他电气问题。这些超时将阻止您的草图锁定,但不能解决这些问题。在这种情况下,通常(也)会出现数据损坏,但不会导致超时或其他错误,并且仍然未被检测到。因此,当发生超时时,很可能之前读取或写入的某些数据也已损坏。可能需要额外的措施来更可靠地检测此类问题(例如校验和或读回写入的值)并从中恢复(例如完全系统重置)。这个超时和这些额外的措施应该被视为最后一道防线,如果可能的话,应该解决根本原因。

用法

Wire.setWireTimeout(timeout, reset_on_timeout)

Wire.setWireTimeout()

参数

  • timeout a timeout:超时以微秒为单位,如果为零,则禁用超时检查

  • reset_on_timeout : 如果为真,那么 Wire 硬件将在超时时自动重置

当不带参数调用此函数时,将配置默认超时,该超时应足以防止典型 single-master 配置中的锁定。

返回

None。

示例代码

#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
  #if defined(WIRE_HAS_TIMEOUT)
    Wire.setWireTimeout(3000 /* us */, true /* reset_on_timeout */);
  #endif
}

byte x = 0;

void loop() {
  /* First, send a command to the other device */
  Wire.beginTransmission(8); // transmit to device #8
  Wire.write(123);           // send command
  byte error = Wire.endTransmission(); // run transaction
  if (error) {
    Serial.println("Error occured when writing");
    if (error == 5)
      Serial.println("It was a timeout");
  }

  delay(100);

  /* Then, read the result */
  #if defined(WIRE_HAS_TIMEOUT)
  Wire.clearWireTimeoutFlag();
  #endif
  byte len = Wire.requestFrom(8, 1); // request 1 byte from device #8
  if (len == 0) {
    Serial.println("Error occured when reading");
    #if defined(WIRE_HAS_TIMEOUT)
    if (Wire.getWireTimeoutFlag())
      Serial.println("It was a timeout");
    #endif
  }

  delay(100);
}

注意事项和警告

这个超时的实现方式可能在不同平台之间有所不同,但通常会在等待(部分)事务完成时触发超时条件(例如,等待总线再次可用、等待 ACK 位或等待以完成整个交易)。

当这种超时情况发生时,事务被中止并且endTransmission()requestFrom()将分别返回错误代码或零字节。虽然这本身不会解决总线问题(即它不会消除短路),但它至少可以无限期地防止阻塞,并允许您的软件检测并可能解决这种情况。

如果 reset_on_timeout 设置为 true 并且平台支持此设置,Wire 硬件也会重置,这有助于清除 Wire 硬件模块内的任何错误状态。例如,在 AVR 平台上,可能需要在 noise-induced 超时后重新启动通信。

触发超时时,会设置一个标志,该标志可以使用getWireTimeoutFlag() 查询,并且必须使用clearWireTimeoutFlag() 手动清除(并且在调用setWireTimeout() 时也会清除)。

请注意,此超时也可能在等待时钟延长或等待第二个主设备完成其事务时触发。因此,如果需要,请确保调整超时以适应这些情况。典型的超时时间为 25 毫秒(这是 SMBus 协议允许的最大时钟延长),但(很多)更短的值通常也可以工作。

便携性说明

此函数在 Wire 库的原始版本中不可用,并且可能仍无法在所有平台上使用。需要跨平台和版本移植的代码可以使用WIRE_HAS_TIMEOUT宏,该宏仅在Wire.setWireTimeout()Wire.getWireTimeoutFlag()Wire.clearWireTimeout()都可用时定义。

在 AVR 平台上引入此超时函数时,出于兼容性考虑,它最初默认为禁用状态,预计稍后会启用。这意味着超时的默认值可能因平台(版本)而异。默认超时设置可从 WIRE_DEFAULT_TIMEOUTWIRE_DEFAULT_RESET_WITH_TIMEOUT 宏获得。

如果您需要禁用超时,建议您在默认情况下使用 setWireTimeout(0) 禁用它,即使当前是默认设置。

相关用法


注:本文由纯净天空筛选整理自arduino.cc大神的英文原创作品 setWireTimeout()。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。