引言
在沒有專用總線主機(jī)的情況下,微處理器可以輕松地產(chǎn)生1-Wire時(shí)序信號(hào)。本應(yīng)用筆記給出了一個(gè)采用‘C’語言編寫、支持標(biāo)準(zhǔn)速率的1-Wire主機(jī)通信基本子程序?qū)嵗?。此外,本文也討論了高速通信模式。要使該?shí)例中的代碼正常運(yùn)行,系統(tǒng)必須滿足以下幾點(diǎn)要求:- 微處理器的通信端口必須是雙向的,其輸出為漏極開路,且線上具有弱上拉。這也是所有1-Wire總線的基本要求。關(guān)于簡(jiǎn)單的1-Wire主機(jī)微處理器電路實(shí)例,請(qǐng)參見1-Wire網(wǎng)絡(luò)可靠設(shè)計(jì)指南(應(yīng)用筆記148)的附錄A。
- 微處理器必須能產(chǎn)生標(biāo)準(zhǔn)速度1-Wire通信所需的精確1μs延時(shí)和高速通信所需要的0.25μs延時(shí)。
- 通信過程不能被中斷。
表1. 1-Wire操作
| Operation | Description | Implementation |
| Write 1 bit | Send a '1' bit to the 1-Wire slaves (Write 1 time slot) | Drive bus low, delay A Release bus, delay B |
| Write 0 bit | send a '0' bit to the 1-Wire slaves (Write 0 time slot) | Drive bus low, delay C Release bus, delay D |
| Read bit | Read a bit from the 1-Wire slaves (Read time slot) | Drive bus low, delay A Release bus, delay E Sample bus to read bit from slave Delay F |
| Reset | Reset the 1-Wire bus slave devices and ready them for a command | Delay G Drive bus low, delay H Release bus, delay I Sample bus, 0 = device(s) present, 1 = no device present Delay J |

圖1. 1-Wire時(shí)序圖
表2. 1-Wire主機(jī)時(shí)序
| Parameter | Speed | Min (μs) | Recommended (μs) | Max (μs) | Notes |
| A | Standard | 5 | 6 | 15 | 1, 2 |
| Overdrive | 1 | 1.5 | 1.85 | 1, 3 | |
| B | Standard | 59 | 64 | N/A | 2, 4 |
| Overdrive | 7.5 | 7.5 | N/A | 3, 4 | |
| C | Standard | 60 | 60 | 120 | 2, 5 |
| Overdrive | 7 | 7.5 | 14 | 3, 5 | |
| D | Standard | 8 | 10 | N/A | 2, 6 |
| Overdrive | 2.5 | 2.5 | N/A | 3, 6 | |
| E | Standard | 5 | 9 | 12 | 2, 7, 8 |
| Overdrive | 0.5 | 0.75 | 0.85 | 3, 7, 8 | |
| F | Standard | 50 | 55 | N/A | 2, 9 |
| Overdrive | 6.75 | 7 | N/A | 3, 9 | |
| G | Standard | 0 | 0 | 0 | ? |
| Overdrive | 2.5 | 2.5 | N/A | 3, 14 | |
| H | Standard | 480 | 480 | 640 | 2, 10, 15 |
| Overdrive | 68 | 70 | 80 | 3, 10 | |
| I | Standard | 63 | 70 | 78 | 2, 11 |
| Overdrive | 7.2 | 8.5 | 8.8 | 3, 11 | |
| J | Standard | 410 | 410 | N/A | 2, 12, 13 |
| Overdrive | 39.5 | 40 | N/A | 3, 12 |
有關(guān)表中這些值的詳細(xì)計(jì)算,可參考:http://files.dalsemi.com/auto_id/public/an126.zip
注釋:
- 在產(chǎn)品數(shù)據(jù)資料中,表示為tW1L (寫1低)減去ε (上升至VTH的時(shí)間)加上tF (下降至VTL的時(shí)間)。
- 假定網(wǎng)絡(luò)為標(biāo)準(zhǔn)速度的中等距離網(wǎng)絡(luò),且上升和下降時(shí)間不超過3μs。
- 假定網(wǎng)絡(luò)為高速的小型網(wǎng)絡(luò),且上升和下降時(shí)間不超過0.5μs。
- 數(shù)據(jù)資料中,表示為tSLOT (時(shí)隙時(shí)間)減去‘A’所代表的時(shí)間。
- 數(shù)據(jù)資料中,表示為tW0L (寫0低)減去δ (上升至VIHMASTER的時(shí)間)加上tF (下降至VTL的時(shí)間)。
- 數(shù)據(jù)資料中,表示為tREC (恢復(fù)時(shí)間)加上δ (上升至VIHMASTER的時(shí)間)。
- 數(shù)據(jù)資料中,表示為tMSR (主機(jī)采樣讀時(shí)間)加上tF (下降至VTL的時(shí)間),再減去‘A’。
- 在該范圍內(nèi),采樣要盡可能晚,以便獲得最長(zhǎng)的恢復(fù)時(shí)間。
- 數(shù)據(jù)資料中,表示為tSLOT (時(shí)隙時(shí)間)減去‘A’,再減去‘E’。
- 數(shù)據(jù)資料中,表示為tRSTL (復(fù)位為低的時(shí)間)減去ε (上升至VTH的時(shí)間)加上tF (下降至VTL的時(shí)間)。
- 數(shù)據(jù)資料中,表示為tMSP (主機(jī)采樣應(yīng)答時(shí)間)加上ε (上升至VTH的時(shí)間)。
- 數(shù)據(jù)資料中,其最小值表示為tRSTL (復(fù)位低電平時(shí)間)減去‘I’所用的時(shí)間。
- 這里所提到的1-Wire復(fù)位操作沒有把DS2404和DS1994使用的擴(kuò)展應(yīng)答(報(bào)警)脈沖序列考慮進(jìn)去,關(guān)于這種特殊情況,請(qǐng)查看產(chǎn)品的數(shù)據(jù)資料。在1-Wire復(fù)位序列的未尾進(jìn)行采樣,可以驗(yàn)證1-Wire總線是否已返回到上拉電平。如果電平仍為0,則可能是1-Wire總線與地之間短路,或DS2404/DS1994發(fā)出了報(bào)警信號(hào)。
- 表示為tREC (恢復(fù)時(shí)間)減去‘D’所用的時(shí)間。在高速應(yīng)用時(shí),一些器件在tRSTL (低電平復(fù)位時(shí)間)之前要求額外的延時(shí),以保證器件的寄生電源被完全充滿。
- 對(duì)于低電壓工作方式,有些器件可能需要更長(zhǎng)的延時(shí)。關(guān)于合適的參數(shù)值,請(qǐng)參閱器件數(shù)據(jù)資料。
代碼實(shí)例
下面代碼實(shí)例都依賴于兩個(gè)通用的‘C’函數(shù)outp和inp,從IO端口讀寫字節(jié)數(shù)據(jù)。他們通常位于// send 'databyte' to 'port' int outp(unsigned port, int databyte); // read byte from 'port' int inp(unsigned port);代碼中的常量PORTADDRESS (圖3)用來定義通信端口的地址。這里我們假定使用通信端口的第0位控制1-Wire總線。設(shè)定該位為1,將使1-Wire總線變?yōu)榈碗娖?;設(shè)定該位為0,1-Wire總線將被釋放,此時(shí)1-Wire總線被電阻上拉,或被1-Wire從器件下拉。
代碼中的tickDelay函數(shù)是一個(gè)用戶編制的子程序,此函數(shù)用于產(chǎn)生一個(gè)1/4μs整數(shù)倍的延時(shí)。在不同的平臺(tái)下,該函數(shù)的實(shí)現(xiàn)也是不同的,故在此不做具體描述。以下是tickDelay函數(shù)聲明代碼,以及一個(gè)SetSpeed函數(shù),用于設(shè)定標(biāo)準(zhǔn)速度和高速模式的延時(shí)時(shí)間。
實(shí)例1. 1-Wire時(shí)序的生成
// Pause for exactly 'tick' number of ticks = 0.25us
void tickDelay(int tick); // Implementation is platform specific
// 'tick' values
int A,B,C,D,E,F,G,H,I,J;
//-----------------------------------------------------------------------------
// Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0).
//
void SetSpeed(int standard)
{
// Adjust tick values depending on speed
if (standard)
{
// Standard Speed
A = 6 * 4;
B = 64 * 4;
C = 60 * 4;
D = 10 * 4;
E = 9 * 4;
F = 55 * 4;
G = 0;
H = 480 * 4;
I = 70 * 4;
J = 410 * 4;
}
else
{
// Overdrive Speed
A = 1.5 * 4;
B = 7.5 * 4;
C = 7.5 * 4;
D = 2.5 * 4;
E = 0.75 * 4;
F = 7 * 4;
G = 2.5 * 4;
H = 70 * 4;
I = 8.5 * 4;
J = 40 * 4;
}
}
1-Wire基本操作的代碼程序如實(shí)例2所示。實(shí)例2. 基本的1-Wire函數(shù)
//----------------------------------------------------------------------------- // Generate a 1-Wire reset, return 1 if no presence detect was found, // return 0 otherwise. // (NOTE: Does not handle alarm presence from DS2404/DS1994) // int OWTouchReset(void) { int result; tickDelay(G); outp(PORTADDRESS,0x00); // Drives DQ low tickDelay(H); outp(PORTADDRESS,0x01); // Releases the bus tickDelay(I); result = inp(PORTADDRESS) & 0x01; // Sample for presence pulse from slave tickDelay(J); // Complete the reset sequence recovery return result; // Return sample presence pulse result } //----------------------------------------------------------------------------- // Send a 1-Wire write bit. Provide 10us recovery time. // void OWWriteBit(int bit) { if (bit) { // Write '1' bit outp(PORTADDRESS,0x00); // Drives DQ low tickDelay(A); outp(PORTADDRESS,0x01); // Releases the bus tickDelay(B); // Complete the time slot and 10us recovery } else { // Write '0' bit outp(PORTADDRESS,0x00); // Drives DQ low tickDelay(C); outp(PORTADDRESS,0x01); // Releases the bus tickDelay(D); } } //----------------------------------------------------------------------------- // Read a bit from the 1-Wire bus and return it. Provide 10us recovery time. // int OWReadBit(void) { int result; outp(PORTADDRESS,0x00); // Drives DQ low tickDelay(A); outp(PORTADDRESS,0x01); // Releases the bus tickDelay(E); result = inp(PORTADDRESS) & 0x01; // Sample the bit value from the slave tickDelay(F); // Complete the time slot and 10us recovery return result; }該程序包括了1-Wire總線的所有位操作,通過調(diào)用該程序可以構(gòu)成以字節(jié)為處理對(duì)象的函數(shù),見實(shí)例3。
實(shí)例3. 派生的1-Wire函數(shù)
//-----------------------------------------------------------------------------
// Write 1-Wire data byte
//
void OWWriteByte(int data)
{
int loop;
// Loop to write each bit in the byte, LS-bit first
for (loop = 0; loop < 8; loop++)
{
OWWriteBit(data & 0x01);
// shift the data byte for the next bit
data >>= 1;
}
}
//-----------------------------------------------------------------------------
// Read 1-Wire data byte and return it
//
int OWReadByte(void)
{
int loop, result=0;
for (loop = 0; loop < 8; loop++)
{
// shift the result to get it ready for the next bit
result >>= 1;
// if result is one, then set MS bit
if (OWReadBit())
result |= 0x80;
}
return result;
}
//-----------------------------------------------------------------------------
// Write a 1-Wire data byte and return the sampled result.
//
int OWTouchByte(int data)
{
int loop, result=0;
for (loop = 0; loop < 8; loop++)
{
// shift the result to get it ready for the next bit
result >>= 1;
// If sending a '1' then read a bit else write a '0'
if (data & 0x01)
{
if (OWReadBit())
result |= 0x80;
}
else
OWWriteBit(0);
// shift the data byte for the next bit
data >>= 1;
}
return result;
}
//-----------------------------------------------------------------------------
// Write a block 1-Wire data bytes and return the sampled result in the same
// buffer.
//
void OWBlock(unsigned char *data, int data_len)
{
int loop;
for (loop = 0; loop < data_len; loop++)
{
data[loop] = OWTouchByte(data[loop]);
}
}
//-----------------------------------------------------------------------------
// Set all devices on 1-Wire to overdrive speed. Return '1' if at least one
// overdrive capable device is detected.
//
int OWOverdriveSkip(unsigned char *data, int data_len)
{
// set the speed to 'standard'
SetSpeed(1);
// reset all devices
if (OWTouchReset()) // Reset the 1-Wire bus
return 0; // Return if no devices found
// overdrive skip command
OWWriteByte(0x3C);
// set the speed to 'overdrive'
SetSpeed(0);
// do a 1-Wire reset in 'overdrive' and return presence result
return OWTouchReset();
}
OWTouchByte函數(shù)可以同時(shí)完成讀寫1-Wire總線數(shù)據(jù),通過該函數(shù)可以實(shí)現(xiàn)數(shù)據(jù)塊的讀寫。在一些平臺(tái)上執(zhí)行效率更高, Maxim提供的API就采用了這種函數(shù)。通過OWTouchByte函數(shù),OWBlock函數(shù)簡(jiǎn)化了1-Wire總線的數(shù)據(jù)塊發(fā)送和接收。注意:OWTouchByte(0xFF)與OWReadByte()等效,OWTouchByte(data)與OWWriteByte(data)等效。這些函數(shù)和tickDelay函數(shù)一起構(gòu)成了1-Wire總線進(jìn)行位、字節(jié)和塊操作時(shí)所必需的全部函數(shù)。實(shí)例4給出了利用這些函數(shù)讀取DS2432的SHA-1認(rèn)證頁的實(shí)例。
實(shí)例4. 讀DS2432實(shí)例
//-----------------------------------------------------------------------------
// Read and return the page data and SHA-1 message authentication code (MAC)
// from a DS2432.
//
int ReadPageMAC(int page, unsigned char *page_data, unsigned char *mac)
{
int i;
unsigned short data_crc16, mac_crc16;
// set the speed to 'standard'
SetSpeed(1);
// select the device
if (OWTouchReset()) // Reset the 1-Wire bus
return 0; // Return if no devices found
OWWriteByte(0xCC); // Send Skip ROM command to select single device
// read the page
OWWriteByte(0xA5); // Read Authentication command
OWWriteByte((page << 5) & 0xFF); // TA1
OWWriteByte(0); // TA2 (always zero for DS2432)
// read the page data
for (i = 0; i < 32; i++)
page_data[i] = OWReadByte();
OWWriteByte(0xFF);
// read the CRC16 of command, address, and data
data_crc16 = OWReadByte();
data_crc16 |= (OWReadByte() << 8);
// delay 2ms for the device MAC computation
// read the MAC
for (i = 0; i < 20; i++)
mac[i] = OWReadByte();
// read CRC16 of the MAC
mac_crc16 = OWReadByte();
mac_crc16 |= (OWReadByte() << 8);
// check CRC16...
return 1;
}
附加軟件
本應(yīng)用筆記給出了1-Wire總線操作的基本函數(shù),這些基本函數(shù)都是構(gòu)建復(fù)雜的1-Wire應(yīng)用的基礎(chǔ)。本文忽略的一個(gè)重要操作是1-Wire搜索。通過1-Wire搜索可以搜索到掛接在總線上的多個(gè)1-Wire從機(jī)器件的唯一ID號(hào)。在應(yīng)用筆記187:"1-Wire搜索算法"一文中詳細(xì)介紹了這種搜索方法,同時(shí)也給出了實(shí)現(xiàn)這些1-Wire基本函數(shù)的C程序代碼。1-Wire公共開發(fā)包中含有大量針對(duì)特定器件編寫的代碼,由下列鏈接提供:
http://www.ibutton.com/software/1wire/wirekit.html
其它更詳細(xì)的資料請(qǐng)參閱應(yīng)用筆記155:"1-Wire軟件資源指南"。
替換方案
如果對(duì)于某一特定應(yīng)用,通過軟件實(shí)現(xiàn)1-Wire主機(jī)方案不可行,則作為替換方案,可以采用1-Wire主機(jī)芯片或合成的1-Wire主機(jī)單元。Maxim提供了采用Verilog和VHDL編寫的1-Wire主機(jī)。
DS1WM
如需獲取1-Wire主機(jī)的Verilog/VHDL代碼,請(qǐng)?zhí)峤患夹g(shù)支持申請(qǐng)。
合成的1-Wire主機(jī)工作方式在應(yīng)用筆記120:"利用1-Wire主機(jī)通訊"和應(yīng)用筆記119:"嵌入1-Wire主機(jī)"中進(jìn)行了說明。
有多種1-Wire主機(jī)芯片可以作為微處理器的外設(shè)。串行、1-Wire線驅(qū)動(dòng)器DS2480B能夠很容易地與標(biāo)準(zhǔn)串行口連接。
關(guān)于DS2480B的操作,詳見應(yīng)用筆記192:"DS2480B串行接口1-Wire線驅(qū)動(dòng)器的使用")。
這是為遠(yuǎn)距離1-Wire傳輸線專門設(shè)計(jì)的先進(jìn)的1-Wire線驅(qū)動(dòng)器,在應(yīng)用筆記244:"性能優(yōu)異的1-Wire網(wǎng)絡(luò)驅(qū)動(dòng)器"中,描述了專門為長(zhǎng)線設(shè)計(jì)、更為精細(xì)的1-Wire線驅(qū)動(dòng)器。
修訂歷史記錄
07/06/00:1.0版—最初版本。
05/28/02:2.0版—糾正了1-Wire復(fù)位采樣時(shí)間。增加了波形圖、鏈接和更多的代碼實(shí)例。
02/02/04:2.1版—增加了對(duì)高速模式的支持,給出了時(shí)序的最小值、最大值,更新了代碼實(shí)例。
09/06/05:2.2版—修正代碼例程說明中的PIO極性。
電子發(fā)燒友App





















































評(píng)論