博客專欄

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

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

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

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

單線標(biāo)準(zhǔn)具有主從配置,其中只能有一個(gè)主設(shè)備、一臺(tái)計(jì)算機(jī)或微控制器以及多個(gè)從設(shè)備??梢允褂?1-wire 標(biāo)準(zhǔn)總線連接多達(dá) 100 個(gè)從屬 1-wire 設(shè)備。但是,隨著從設(shè)備添加到總線,主設(shè)備輪詢它們可能需要更多時(shí)間。

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

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

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

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

讓我們更詳細(xì)地討論一下。

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

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

1-wire 標(biāo)準(zhǔn)總線

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

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

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

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

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

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

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

image.png


1-wire 器件的寄生供電。

image.png


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

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

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é)議如何工作

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

數(shù)據(jù)線上的通信由主機(jī)使用復(fù)位啟動(dòng)。它拉低數(shù)據(jù)線 480 us,然后釋放它,允許典型的上拉電阻將數(shù)據(jù)線拉高。如果從設(shè)備連接到總線,它們通過將數(shù)據(jù)線拉低 60~240 us 來響應(yīng)復(fù)位信號(hào)。如果線路被從設(shè)備拉低,則主設(shè)備通過總線確認(rèn)它們的存在。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)來訪問一個(gè)。ROM 命令之后是功能命令。

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

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

當(dāng)主機(jī)必須在數(shù)據(jù)線上寫入位時(shí),它會(huì)將數(shù)據(jù)線拉低。

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

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

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

image.png


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

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

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

image.png


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

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

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

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

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

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
);
}

對(duì)于 Arduino,1-wire 寫操作可以用這個(gè)函數(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);
}
}

對(duì)于計(jì)算機(jī)來說,同樣的功能可以用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);
}
}

對(duì)于Arduino,1-wire讀取操作可以通過這個(gè)函數(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;
}

對(duì)于計(jì)算機(jī),相同的功能可以用 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;
}

對(duì)于 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;
}

對(duì)于計(jì)算機(jī),可以用 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;
}

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

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

傳輸過程中:

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

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

  • Bits 5~7 由從機(jī)寫入。

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

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

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

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

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

image.png


順序檢測(cè)

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

image.png


1 線接口中的序列檢測(cè)。

器件

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

image.png


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



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

相關(guān)推薦

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

關(guān)閉