當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


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()。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。