博客專欄

EEPW首頁 > 博客 > 什么是 1-Wire 協(xié)議?

什么是 1-Wire 協(xié)議?

發(fā)布人:電子資料庫 時間:2023-01-16 來源:工程師 發(fā)布文章

1-Wire 協(xié)議是一種單線接口、半雙工、雙向、低速和功率、長距離串行數(shù)據(jù)通信協(xié)議。盡管該協(xié)議被歸類為單線標準,但單線標準總線至少需要兩根線——一根用于數(shù)據(jù)和/或電源,另一根用于接地回路。根據(jù)電源模式,可能需要額外的電線。

單線標準具有主從配置,其中只能有一個主設(shè)備、一臺計算機或微控制器以及多個從設(shè)備。可以使用 1-wire 標準總線連接多達 100 個從屬 1-wire 設(shè)備。但是,隨著從設(shè)備添加到總線,主設(shè)備輪詢它們可能需要更多時間。

該協(xié)議不使用時鐘信號。相反,從屬設(shè)備在內(nèi)部計時并與來自主設(shè)備的信號同步。主設(shè)備單獨負責從設(shè)備的讀寫操作,因此它們不能自行發(fā)起數(shù)據(jù)傳輸。他們能做的是在主機復(fù)位時通過總線指示他們的存在。 每個主設(shè)備都由一個 64 位地址標識,存儲在每個單線從設(shè)備的 ROM 中。

這是一種低速串行通信標準,典型數(shù)據(jù)速度為 15.4 kbps??偩€可以超速至 125 kbps 的最大數(shù)據(jù)速度。與其他標準串行數(shù)據(jù)通信協(xié)議(如 UART、I2C 和 SPI)相比,1-Wire 協(xié)議的數(shù)據(jù)速度較低,但 1-wire 總線在生產(chǎn)和運行中非常經(jīng)濟。它提供簡單的硬件實現(xiàn)和極低的功耗占用空間。

雖然硬件簡單,但微控制器端的軟件實現(xiàn)卻非常復(fù)雜。盡管功耗低,但它可以在相對較長的距離內(nèi)傳輸數(shù)據(jù)。

1-Wire 協(xié)議用于溫度傳感器、實時時鐘、定時器、EEPROM 和流行的 iButton。這些 1-wire 從器件中的大多數(shù)都是(現(xiàn)在的)Maxim Integrated 的產(chǎn)品。

讓我們更詳細地討論一下。

什么是 1-Wire 協(xié)議?

1-Wire 協(xié)議是一種單線接口,用于微控制器和計算機中的低速數(shù)據(jù)通信。該協(xié)議在沒有時鐘信號的情況下在單條數(shù)據(jù)線上運行。它是一種主從串行通信協(xié)議,其中與多個從機的半雙工雙向數(shù)據(jù)通信由單個主機單獨管理和控制。

1-wire 標準總線

1-wire 標準總線至少有兩根線。一根是數(shù)據(jù)線,一根是地線返回。主機和從機都與數(shù)據(jù)線有開漏(集電極開路)連接。這就是 4.7K 電阻通常將數(shù)據(jù)線拉高的原因。1-wire 從設(shè)備有兩種可能的供電模式:寄生和傳統(tǒng)。

在寄生模式下,只有數(shù)據(jù)線和接地回路必須追蹤到 1-wire 從器件。如果使用傳統(tǒng)的電源模式,則必須為每個連接到總線的 1-wire 從設(shè)備追蹤一條額外的正電源線。

因此,PCB 上的 1-wire 總線可能有兩根或三根線。傳統(tǒng)的1-wire總線三線供電更可靠。

寄生供電VS常規(guī)供電

如前所述,1-wire 從設(shè)備可以在寄生模式和常規(guī)模式下供電。所有 1-wire 從器件都有三個端子:VDD、GND 和數(shù)據(jù)。在寄生模式下,VDD 和 GND 引腳接地,因此信號和電源在同一根線(即數(shù)據(jù)線)上提供給從設(shè)備。

從屬設(shè)備有一個 800 pF 的內(nèi)部電容器,當數(shù)據(jù)線為高電平時,它會被充電。當數(shù)據(jù)線為低電平時,存儲的電荷使從機保持活動狀態(tài)。數(shù)據(jù)線通常由一個 4.7K 電阻上拉。

寄生供電需要嚴格的時序和準確規(guī)范的供電,以確保從屬設(shè)備正常運行。這就是為什么這種模式不太可靠的原因。通常,使用額外的硬上拉來確定電源。

image.png


1-wire 器件的寄生供電。

image.png


帶有額外硬上拉的 1-wire 器件的寄生供電。

在傳統(tǒng)的供電模式下,1-wire 從設(shè)備由外部供電。每個 1-wire 從屬設(shè)備都跟蹤一根額外的線。從站的外部電源確保即使在惡劣的高溫條件下也能安全運行。

image.png


1-wire 設(shè)備的常規(guī)供電。

典型的 1-wire 器件工作電壓范圍為 – 1.71~1.89V、1.71~3.63V、2.97~6.63V 和 2.97~5.25V。消耗的電流范圍在 1.06~5mA 之間。上拉電阻設(shè)置電流電平,無論設(shè)備是提供寄生電源還是傳統(tǒng)電源。

1-Wire 協(xié)議如何工作

該接口通常不用于微控制器或微型計算機。它通常由使用位拆分或通用異步接收器-發(fā)送器 (UART) 的軟件來實現(xiàn)。

數(shù)據(jù)線上的通信由主機使用復(fù)位啟動。它拉低數(shù)據(jù)線 480 us,然后釋放它,允許典型的上拉電阻將數(shù)據(jù)線拉高。如果從設(shè)備連接到總線,它們通過將數(shù)據(jù)線拉低 60~240 us 來響應(yīng)復(fù)位信號。如果線路被從設(shè)備拉低,則主設(shè)備通過總線確認它們的存在。60~240 us后,slave(s)釋放數(shù)據(jù)線,master開始寫入。

image.png


復(fù)位后,主設(shè)備可以與從設(shè)備寫入和讀取數(shù)據(jù)。最初,它發(fā)送 ROM 命令,如搜索 ROM 命令 (0xF0),以訪問從屬設(shè)備的 ROM 地址。在讀取所有連接的 1-wire 從設(shè)備的 ROM 地址后,主設(shè)備可以通過發(fā)送匹配 ROM 命令(0x55)來訪問一個。ROM 命令之后是功能命令。

例如,如果總線上連接了一個 1-wire 溫度傳感器,微控制器可以發(fā)送功能命令來啟動溫度轉(zhuǎn)換、讀取溫度等。ROM 和功能命令都是 8 位長。

由于 1-Wire 標準不使用任何時鐘信號,“0”和“1”位的通信通過為特定時隙設(shè)置數(shù)據(jù)線的邏輯電平來實現(xiàn)。通常,時隙為 60 us 長。每個時隙之間也有1us的間隔,使數(shù)據(jù)線再次被上拉電阻拉高。在每個 60 us 時隙中,主從之間通信 1 位。如果總線過載,時隙最多可縮短 10 倍。

當主機必須在數(shù)據(jù)線上寫入位時,它會將數(shù)據(jù)線拉低。

  • 要寫入“0”,主機在整個 60 us 時隙內(nèi)拉低數(shù)據(jù)線,然后在時隙之間以 1us 間隔釋放它。

  • 要寫入“1”,主機在整個時隙內(nèi)將數(shù)據(jù)線拉低 15 us 的較短時間,然后在時隙之間以 1 us 的間隔釋放它。

從設(shè)備大約在中間時隙(即 60us 時隙中的 30us)發(fā)出脈沖。他們有一個基本的單穩(wěn)態(tài)多諧振蕩器來檢測脈沖的持續(xù)時間。ROM 和功能命令為 8 位長。傳送的數(shù)據(jù)也是以 8 位為一組。錯誤檢測是通過 8 位循環(huán)冗余校驗來執(zhí)行的。

image.png


主設(shè)備在發(fā)送 ROM 搜索或功能命令后從從設(shè)備讀取。讀取操作由主設(shè)備控制。主機逐位讀取從機,同時數(shù)據(jù)以 8 位為一組傳送給主機。每個位在 60 us 時隙中讀?。ㄈ绻偩€過載則更短)。

master拉低數(shù)據(jù)線1us后釋放。然后,它在 15 us 后從總線采樣數(shù)據(jù)。如果從機在總線上寫入“0”,它會在整個 60 us 時隙內(nèi)保持線路處于下拉狀態(tài),然后在時隙之間以 1us 間隔釋放數(shù)據(jù)線。如果從機在總線上寫入'1',它會保持線下拉15 us,然后釋放上拉電阻將數(shù)據(jù)線拉高的數(shù)據(jù)線。

主機在 15 us 后對每個位進行采樣。如果從設(shè)備發(fā)送的位為“0”,則該線在采樣時被拉低。如果從設(shè)備發(fā)送的位為“1”,則該線在采樣時被拉高。

image.png


主機可以在 1 線標準總線上與多達 100 個從機通信。然而,連接到總線的 1-wire 從機數(shù)量越多,主機從它們拉取數(shù)據(jù)所需的時間就越多。軟件庫通常使用 bit-banging 或 UART 來計時脈沖持續(xù)時間。在 1-Wire 協(xié)議中,LSB 總是最先發(fā)送。

協(xié)議實現(xiàn)

1-wire 通信中有五種總線信號,每一種都由主機發(fā)起和控制。這些信號是 Reset、Presence、Write 0、Write 1 和 Read。

該協(xié)議可以通過微控制器或計算機以兩種方式實現(xiàn):輪詢和中斷驅(qū)動實現(xiàn)。Polled 是一種純軟件實現(xiàn)。中斷驅(qū)動的實現(xiàn)需要一個內(nèi)置的定時器/計數(shù)器。

就 Arduino 而言,可以使用 delayMicroseconds() 函數(shù)完成輪詢實現(xiàn)(僅軟件)。這個函數(shù)有這個源代碼:

void delayMicroseconds(unsigned int us)
{
// calling avrlib’s delay_us() function with low values (e.g. 1 or
// 2 microseconds) gives delays longer than desired.
//delay_us(us);
// for the 16 MHz clock on most Arduino boards
// for a one-microsecond delay, simply return. the overhead
// of the function call yields a delay of approximately 1 1/8 us.
if (–us == 0)
return;
// the following loop takes a quarter of a microsecond (4 cycles)
// per iteration, so execute it four times for each microsecond of
// delay requested.
us <<= 2;
// account for the time taken in the preceeding commands.
us -= 2;
// busy wait
__asm__ __volatile__ (
“1: sbiw %0,1” “nt” // 2 cycles
“brne 1b” : “=w” (us) : “0” (us) // 2 cycles
);
}

對于 Arduino,1-wire 寫操作可以用這個函數(shù)來執(zhí)行:

void OWWrite(uint8_t bit){
if(bit){
//Write bit ‘1’
digitalWrite(PINNUMBER, 0x00);
delayMicroseconds(6);
digitalWrite(PINNUMBER, 0x01);
delayMicroseconds(64);
}
else{
//Write bit ‘0’
digitalWrite(PINNUMBER, 0x00);
delayMicroseconds(60);
digitalWrite(PINNUMBER, 0x01);
delayMicroseconds(10);
}
}

對于計算機來說,同樣的功能可以用C++來寫,如下:

void OWWrite(uint8_t bit){
if(bit==1){
//PF5 is port name
PORTF &= ~(1<<PF5);
delayMicroseconds(6);
PORTF |= (1<<PF5);
delayMicroseconds(64);
}
else{
PORTF &= ~(1<<PF5);
delayMicroseconds(60);
PORTF |= (1<<PF5);
delayMicroseconds(10);
}
}

對于Arduino,1-wire讀取操作可以通過這個函數(shù)來執(zhí)行:

uint8_t OWRead(void){
uint8_t result;
digitalWrite(PINNUMBER, 0x00);
delayMicroseconds(6);
digitalWrite(PINNUMBER, 0x01);
delayMicroseconds(9);
pinMode(PINNUMBER, INPUT);
result = digitalRead(PINNUMBER) & 0x01;
delayMicroseconds(55);
pinMode(PINNUMBER, OUTPUT);
return result;
}

對于計算機,相同的功能可以用 C++ 編寫如下。

uint8_t OWReadBit(void){
uint8_t result = 0;
PORTF &= ~(1<<PF5);
delayMicroseconds(10);
PORTF |= (1<<PF5);
delayMicroseconds(20);
if(PINF & (1<<PF5)){
result = HIGH;
}
delayMicroseconds(30);
return result;
}

對于 Arduino,可以使用此函數(shù)執(zhí)行重置和存在操作:

uint8_t OWResetPresence(void){
uint8_t result;
delayMicroseconds(0);
digitalWrite(PINNUMBER, 0x00);
delayMicroseconds(480);
digitalWrite(PINNUMBER, 0x01);
delayMicroseconds(70);
pinMode(PINNUMBER, INPUT);
result = digitalRead(PINNUMBER)^0x01;
delayMicroseconds(410);
pinMode(PINNUMBER, OUTPUT);
return result;
}

對于計算機,可以用 C++ 編寫相同的函數(shù):

uint8_t OWResetPresence(void){
uint8_t result = LOW;
PORTF &= ~(1<<PF5);
delayMicroseconds(480);
PORTF |= (1<<PF5);
delayMicroseconds(55);
if(PINF&(1<<PF5)){
result = HIGH;
}
return result;
}

微控制器和計算機可以使用 UART 來實現(xiàn) 1-Wire 協(xié)議的中斷驅(qū)動。計算機可能需要一個外部 UART 芯片或分線板來與 1-wire 設(shè)備通信。

UART 的 Tx 和 Rx 必須連接到 1-wire 總線的數(shù)據(jù)線。UART 端口必須有一個集電極開路緩沖器,以便從設(shè)備可以下拉數(shù)據(jù)線。對于復(fù)位和存在信號,波特率必須設(shè)置為 9600,并且控制器/計算機需要傳輸 0xF0。

傳輸過程中:

  • 位 0~3 設(shè)置為'0'

  • 第 4 位設(shè)置為“1”

  • Bits 5~7 由從機寫入。

  • 停止位設(shè)置為高

如果沒有從設(shè)備連接到總線,則接收到的值為 0xF0。如果收到 0xF0 以外的任何值,則表示總線上存在 1-wire 從機。

對于單線寫操作,UART 的波特率必須設(shè)置為 115200。起始位必須設(shè)置為“0”,停止位必須設(shè)置為“1”。

要寫入“1”,UART 必須發(fā)送 0xFF 并接收 0xFF 作為回報。要寫入“0”,UART 必須發(fā)送 0x00 并接收 0x00 作為回報。

對于單線讀取操作,UART 的波特率必須設(shè)置為 115200。起始位必須設(shè)置為“0”,停止位必須設(shè)置為“1”。讀取時,UART 傳輸一個值為 0xFF 的值,相當于釋放拉高狀態(tài)的線。其余位由從機寫入。如果從設(shè)備寫入“1”,則起始位之后的所有位都設(shè)置為“1”,因此 UART 接收到值 0xFF。如果從設(shè)備寫入“0”,則起始位之后的所有位都設(shè)置為“0”,因此 UART 接收到除 0xFF 之外的任何值。

image.png


順序檢測

主設(shè)備可以搜索和檢測總線上任意數(shù)量的 1-wire 從設(shè)備。還可以將多達 100 個從屬設(shè)備連接到 1-wire 標準總線。然而,在標準的 1-wire 總線中,主機沒有檢測總線上從機物理順序的機制。在一些 1-wire 器件中,提供了兩個額外的引腳來支持序列檢測。DS28EA00 就是這樣一種器件。

image.png


1 線接口中的序列檢測。

器件

1-Wire 協(xié)議是專有標準。所有 1-wire 器件均由 Maxim Integrated 制造。該表列出了一些著名的 1-wire 器件。

image.png


*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞: wire 協(xié)議

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉