引言
DS1WM1-Wire總線主機(jī)內(nèi)部生成1-Wire時(shí)序和控制信號(hào),無需CPU產(chǎn)生逐位控制時(shí)序。該控制功能使系統(tǒng)程序設(shè)計(jì)人員能夠使用API函數(shù)進(jìn)行程序開發(fā)。DS1WM API采用ANSI C語言編寫,可以為多種支持ANSI C的微處理器平臺(tái)所用。以下例程介紹了如何在網(wǎng)絡(luò)中識(shí)別、選擇1-Wire從設(shè)備,并與其進(jìn)行通信。圖1. 1-Wire網(wǎng)絡(luò)總線示例電路
圖1所示的電路配置適用于以下所有示例程序。主機(jī)CPU利用DS1WM與帶有鏈路模式和GPIO的1-Wire數(shù)字溫度傳感器DS28EA00以及1-Wire 1Kb EEPROM DS2431進(jìn)行通信。示例程序重點(diǎn)演示API,而非從設(shè)備功能。16MHz的系統(tǒng)時(shí)鐘通過CLK引腳提供1-Wire主機(jī)時(shí)序。1-Wire主機(jī)的端口引腳需要映射到應(yīng)用微處理器的引腳。API文件DS1WM.h中包含了引腳映射功能。API頭文件中的MaxNumberDevices宏必須更改為實(shí)際可能的最大器件數(shù)。DS1WM.c API文件中的ReadByteFromRegister和WriteByte2Register函數(shù)也需要進(jìn)行修改,以便正確觸發(fā)微處理器端口。VPUP電壓典型值為5.0V,RPUP不大于2.2kΩ。
概述
通過Maxim支持中心,可以申請(qǐng)免費(fèi)的DS1WM和API。下面討論了初始化和1-Wire復(fù)位控制的DS1WM代碼。此外還提供了一個(gè)示例,用于演示如何使用DS1WM ROM搜索引擎確定每個(gè)器件的唯一注冊(cè)碼(ROM ID)。使用存儲(chǔ)的注冊(cè)碼以及家族碼,可以識(shí)別每個(gè)1-Wire從設(shè)備,并通過匹配ROM命令進(jìn)行訪問。家族碼列表,請(qǐng)參見應(yīng)用筆記155:“1-Wire?軟件資源指南”。DS28EA00示例演示了如何進(jìn)行溫度轉(zhuǎn)換。第二個(gè)示例給出了高速讀寫DS2431暫存器的兩種方法。總線主機(jī)基本操作
微處理器通過觸發(fā)復(fù)位引腳初始化DS1WM,API接口執(zhí)行所有1-Wire通信。示例程序通過調(diào)用DS1WM API函數(shù)進(jìn)行工作。由于響應(yīng)中斷時(shí)會(huì)改變微處理器代碼,因此后續(xù)示例中采用輪詢方式替代中斷方式通信。后續(xù)的示例程序中用到了表1所示的1-Wire操作。
表1. 1-Wire操作
Operation* | Description |
OWReset | Sends the 1-Wire reset stimulus and checks for the pulses of 1-Wire slave devices that are present on the bus. |
OWWriteByte/OWReadByte | Sends or receives a single byte of data from the 1-Wire bus. |
OWWriteBytes/OWReadBytes | Sends or receives multiple bytes of data from the 1-Wire bus. |
OWSearch | Performs the 1-Wire Search Algorithm (see application note 187, "1-Wire Search Algorithm"). |
OverdriveEnable | Sets the 1-Wire communication speed for the DS1WM to overdrive. Note that this only changes the communication speed of the DS1WM; the 1-Wire slave device must be instructed to make the switch when going from normal to overdrive. The 1-Wire slave will always revert to standard speed when it encounters a standard-speed 1-Wire reset. |
OverdriveDisable | Sets the 1-Wire communication speed for the DS1WM to standard. Note that this only changes the communication speed of the DS1WM; a standard-speed 1-Wire reset is required for slave devices to exit overdrive. |
MatchROM | Selects device by issuing the Match ROM command followed by the 64-bit ROM ID selected. |
SetClockFrequency | Sets the clock frequency for the DS1WM. |
InterruptEnableRegisterWrite | Writes a single byte of data to the DS1WM Interrupt Enable register. |
InterruptRegisterRead | Reads a single byte of data from the DS1WM Interrupt register. |
ReceiveBufferRead | Reads a single byte of data from the DS1WM Receive Buffer register. |
初始化
通過初始化DS1WM,啟動(dòng)主機(jī),提供正確的1-Wire總線時(shí)序。主機(jī)將數(shù)值16 (代表頻率值)傳遞至SetClockFrequency函數(shù),將0x90h寫入時(shí)鐘分頻寄存器(請(qǐng)參見DS1WM數(shù)據(jù)資料)。中斷使能寄存器設(shè)置為0x00h,防止INTR引腳產(chǎn)生中斷。上電時(shí),接收緩存可能包含無效值,因此在發(fā)送1-Wire命令之前,最好對(duì)接收緩存進(jìn)行清理。啟動(dòng)時(shí)對(duì)中斷寄存器和接收緩存器的讀操作將清除其中的各個(gè)位。//---------------------------------------------------------------------------------------------------- //Start of initialization example SetClockFrequency(16); //Set clock frequency to 16MHz (power-on default) InterruptEnableRegisterWrite(0x00); //Clear interrupts //Flush receive buffer InterruptRegisterData = InterruptRegisterRead(); ReceiveBufferRead(); //End of initialization example //----------------------------------------------------------------------------------------------------
1-Wire復(fù)位(OWReset API函數(shù))
初始化完成后,主機(jī)必須確定1-Wire總線上是否接有設(shè)備。主機(jī)調(diào)用OWReset函數(shù),以實(shí)現(xiàn)該目的。如果檢測(cè)到器件存在脈沖,該函數(shù)返回1;如果沒有檢測(cè)到器件或發(fā)送錯(cuò)誤,則函數(shù)返回0。如果返回值為0,需要檢查ErrorStatus變量,以確定故障狀態(tài)。1-Wire復(fù)位的優(yōu)先級(jí)高于所有1-Wire命令(例如,Match ROM、Skip ROM、Read ROM),但調(diào)用OWSearch函數(shù)時(shí)除外,該函數(shù)自身帶有復(fù)位。軟件設(shè)計(jì)人員應(yīng)當(dāng)在程序中加入適當(dāng)?shù)墓收咸幚泶a,在發(fā)生故障時(shí)能夠觸發(fā)執(zhí)行這些代碼。ErrorStatus值意味著發(fā)生了如下錯(cuò)誤中的一種:沒有進(jìn)行在線檢測(cè);沒有檢測(cè)到器件;存在1-Wire短路;1-Wire總線始終處于低電平狀態(tài)。Result = OWReset(); if(!Result){ switch(ErrorStatus){ case -1: //DS1WM did not recognize 1-Wire reset (PD=0) //To d add your error code here break; case -2: //No device found (PDR=1) //To d add your error code here break; case -7: //1-Wire IO is shorted (OW_SHORT=1) //To d add your error code here break; case -8: //1-Wire IO is shorted (OW_LOW=1) //To d add your error code here break; } }
利用ROM搜索引擎確定ROM ID
總線上的每個(gè)1-Wire設(shè)備都必須進(jìn)行識(shí)別。存儲(chǔ)在每個(gè)1-Wire器件中的唯一64位ROM ID用于選擇各個(gè)器件,并根據(jù)家族碼識(shí)別器件類型。為降低例程的復(fù)雜度,采用8位家族碼識(shí)別DS28EA00和DS2431。注意:如果1-Wire總線上連接了不止一種器件類型(例如,具有相同的家族碼),則后續(xù)的方法無法對(duì)器件進(jìn)行識(shí)別。不對(duì)總線上的多個(gè)1-Wire器件進(jìn)行識(shí)別,則無法對(duì)特定的1-Wire器件發(fā)送功能命令。如果使用了兩個(gè)或更多的類似器件,則必須通過查找表才能正確訪問特定器件。
調(diào)用OWSearch函數(shù)可以識(shí)別總線上所有的1-Wire器件,該函數(shù)將8字節(jié)ROM ID排成一列。這期間無需調(diào)用OWReset函數(shù),因?yàn)樵摵瘮?shù)已經(jīng)包含在OWSearch函數(shù)中。OWSearch函數(shù)例外的包含了OWReset函數(shù),是因?yàn)槠渌阉魉惴ň哂械^程。OWSearch函數(shù)的返回值為搜索到的1-Wire器件個(gè)數(shù),并將每個(gè)64位ROM ID寫入一個(gè)名為ROMCodes的二維數(shù)組。
下列例程僅演示了調(diào)用一次OWSearch的情況,因此后續(xù)連接至該1-Wire總線的器件將無法通過該代碼進(jìn)行識(shí)別。OWSearch函數(shù)成功執(zhí)行后將返回搜索到的器件個(gè)數(shù)。如果搜索失敗,ErrorStatus變量將返回錯(cuò)誤值,其中包括產(chǎn)生OWReset的故障條件。搜索成功后,對(duì)ROMCodes數(shù)組進(jìn)行了遍歷,并保存每個(gè)器件的數(shù)組索引。這種器件索引方式是通過比較搜索到的每個(gè)器件的家族碼實(shí)現(xiàn)的。隨后調(diào)用數(shù)組索引,可以實(shí)現(xiàn)與搜索到的特定1-Wire器件進(jìn)行通信。這相當(dāng)于創(chuàng)建了一個(gè)簡(jiǎn)單的鏈表(注:可以通過指針進(jìn)行操作)。
//---------------------------------------------------------------------------------------------------- //Start of DS1WM search ROM accelerator example //Devices on the 1-Wire IO are: //DS28EA00 Family Code = 42h (6900000004E8C842) //DS2431 Famliy Code = 2Dh (5A0000000FDE052D) //Find all devices on 1-Wire line and populate ROMCodes array Result = OWSearch(ROMCodes); //Returns number of devices found if successful //Set number of 1-Wire devices found if(Result) NumberOfDevices = Result; if(!Result){ switch(ErrorStatus){ case -1: //DS1WM did not recognize 1-Wire Reset (PD=0) //To d add your error code here break; case -2: //No device found (PDR=1) //To d add your error code here break; case -7: //1-Wire IO is shorted (OW_SHORT=1) //To d add your error code here break; case -8: //1-Wire IO is shorted (OW_LOW=1) //To d add your error code here break; case -9: //Invalid CRC for device //To d add your error code here break; case -10: //ROMCodes array too small (Edit MaxNumberDevices in DS1WM.h) //To d add your error code here break; } } //Note: This function is intended to be used when there is only one device with the same //Family Code present on the line for(i=0;i利用DS1WM API函數(shù)控制DS28EA00
該示例利用之前搜索到的ROM ID與DS28EA00進(jìn)行通信。OWReset之后發(fā)送Match ROM命令。ROM碼數(shù)組連同被訪問的器件索引一起,傳遞到Match ROM函數(shù)。1-Wire總線上的器件會(huì)在Match ROM命令0x55h之后收到一個(gè)64位ROM碼,可以使總線主機(jī)在多點(diǎn)總線上尋址到特定的DS28EA00。只有與64位ROM序列完全匹配的DS28EA00才能響應(yīng)接下來的命令,其它的從器件將等待下一個(gè)復(fù)位脈沖。
OWWriteByte和OWReadByte API函數(shù)用來產(chǎn)生存儲(chǔ)器命令(例如,Write/Copy/Read Scratchpad命令)。DS1WM通過發(fā)送Write Scratchpad命令(0x4Eh)以及隨后的高溫、低溫和配置寄存器設(shè)置值,來設(shè)定溫度報(bào)警以及分辨率。上述操作完成后,發(fā)送OWReset以及Match ROM命令、ROM ID和Copy Scratchpad命令(0x48h) (將暫存器的內(nèi)容復(fù)制到寄存器存儲(chǔ)器),完成溫度分辨率設(shè)置。必須為CPU主機(jī)增加10ms的延時(shí),以完成復(fù)制操作。考慮到微處理器延時(shí)子程序的差異,API僅提供了注釋偽碼。
復(fù)制操作完成后,再次執(zhí)行OWReset,然后發(fā)送Match ROM、ROM ID和轉(zhuǎn)換溫度命令(0x44h)。需要增加100ms的延時(shí),以完成溫度轉(zhuǎn)換。最后,發(fā)送OWReset和Match ROM、ROM ID和Read Scratchpad命令(0xBEh),讀取兩字節(jié)溫度數(shù)據(jù)。需要注意的是,選擇DS28EA00時(shí),必須始終遵循OWReset之后發(fā)送Match ROM命令和ROM ID的命令格式。當(dāng)總線上僅有一個(gè)器件時(shí),才能夠使用Skip ROM命令(即無需Search ROM)。//---------------------------------------------------------------------------------------------------- //Start of DS28EA00 example Result = OWReset(); if(!Result){ switch(ErrorStatus){ case -1: //DS1WM did not recognize 1-Wire reset(PD=0) //To d add your error code here break; case -2: //No device found(PDR=1) //To d add your error code here break; case -7: //1-Wire IO is shorted(OW_SHORT=1) //To d add your error code here break; case -8: //1-Wire IO is shorted(OW_LOW=1) //To d add your error code here break; } } //Set temperature resolution Result = MatchROM(ROMCodes,DS28EA00); //Select device Result = OWWriteByte(0x4E); //Issue Write Scratchpad command Result = OWWriteByte(0x00); //TH register data Result = OWWriteByte(0x00); //TL degister data Result = OWWriteByte(0x1F); //Config. reg. data (set 9-bit temp. resolution) OWReset(); //Error code removed for conciseness MatchROM(ROMCodes,DS28EA00); //Select device OWWriteByte(0x48); //Issue Copy Scratchpad command //To d add microprocessor-specific code delay to allow copy to complete //Delay(10MS); //Psuedo code OWReset(); //1-Wire reset MatchROM(ROMCodes,DS28EA00); //Select device OWWriteByte(0x44); //Issue Convert Temperature command //To d add microprocessor-specific code delay to allow temperature conversion to complete //Delay(100MS); //Psuedo code //Read temperature results from scratchpad OWReset(); //1-Wire reset MatchROM(ROMCodes,DS28EA00); //Select device OWWriteByte(0xBE); //Issue Read Scratchpad command TempLSB = OWReadByte(); //Read byte TempMSB = OWReadByte(); //Read byte //End of DS28EA00 example //----------------------------------------------------------------------------------------------------利用DS1WM API函數(shù)控制高速模式下的DS2431
該示例利用之前搜索到的ROM ID與DS2431進(jìn)行通信。OWReset之后發(fā)送Overdrive Skip ROM命令(0x3Ch),將所有支持高速模式的1-Wire器件置于高速模式。調(diào)用OverdriveEnable函數(shù)激活DS1WM高速時(shí)序。此時(shí)所有1-Wire器件工作在高速模式。標(biāo)準(zhǔn)速率模式和高速模式下的1-Wire時(shí)序請(qǐng)參見應(yīng)用筆記126:“用軟件實(shí)現(xiàn)1-Wire?通信”。
使用目標(biāo)地址TA1和TA2變量
在第一個(gè)示例方法中,變量TA1和TA2設(shè)置為DS2431期望的存儲(chǔ)器地址。發(fā)送OWReset,之后是Match ROM、DS2431 ROM ID、Write Scratchpad命令(0x0Fh)、目標(biāo)地址1 & 2以及要寫入DS2431 64位暫存器的8字節(jié)數(shù)據(jù)。推薦進(jìn)行回讀及CRC16校驗(yàn)操作。關(guān)于CRC16的詳細(xì)討論,請(qǐng)參考應(yīng)用筆記27:“理解和運(yùn)用Maxim iButton?產(chǎn)品中的循環(huán)冗余校驗(yàn)(CRC)”。
OWWriteBytes和OWReadBytes
在第二個(gè)示例方法中,調(diào)用了兩個(gè)新的API函數(shù):OWWriteBytes和OWReadBytes。這兩個(gè)API函數(shù)簡(jiǎn)化了大量數(shù)據(jù)至?xí)捍嫫鞯淖x寫操作。
寫暫存器的方法是:設(shè)置目標(biāo)地址1 & 2、將數(shù)據(jù)寫入WriteBytes數(shù)組、執(zhí)行OWReset、然后發(fā)送Match ROM、DS2431 ROM ID、Write Scratchpad命令(0x0Fh)、目標(biāo)地址1 & 2、利用OWWriteBytes函數(shù)寫入保存在WriteBytes的所有10個(gè)字節(jié)、回讀CRC16并對(duì)CRC16進(jìn)行校驗(yàn)。
讀暫存器的方法是:執(zhí)行OWReset、發(fā)送Match ROM、DS2431 ROM ID、Read Scratchpad命令(0xAAh)、利用OWReadBytes函數(shù)讀取所有13個(gè)字節(jié)(TA1、TA2、ES、CRC16 & 8字節(jié)數(shù)據(jù))并保存到ReadBytes。
調(diào)用API函數(shù)OverdriveDisable,并隨后發(fā)送標(biāo)準(zhǔn)OWReset,可以退出高速模數(shù),使所有器件返回至標(biāo)準(zhǔn)速率。//---------------------------------------------------------------------------------------------------- //Start of DS2431 example Result = OWReset(); //Error code removed for conciseness Result = OWWriteByte(0x3C); //Overdrive Skip ROM (all devices are now in overdrive) OverdriveEnable(); //Enable Overdrive Mode //Write scratchpad with data //First method TA1 = 0x00; TA2 = 0x00; Result = OWReset(); //1-Wire reset Result = MatchROM(ROMCodes,DS2431); //Select device Result = OWWriteByte(0x0F); //Issue Write Scratchpad command Result = OWWriteByte(TA1); //Send target address 1 (TA1) Result = OWWriteByte(TA2); //Send target address 2 (TA2) //Write 8 Bytes of Data Result = OWWriteByte(0x11); //Send Data Byte for all Result = OWWriteByte(0x22); Result = OWWriteByte(0x33); Result = OWWriteByte(0x44); Result = OWWriteByte(0x55); Result = OWWriteByte(0x66); Result = OWWriteByte(0x77); Result = OWWriteByte(0x88); //It is recommended that the CRC16 be read back and verified //CRC16 code was left out for conciseness Result = OWReset(); //1-Wire Reset Result = MatchROM(ROMCodes,DS2431); //Select device Result = OWWriteByte(0xAA); //Issue Read Scratchpad command Result = OWReadByte(); //Read TA1 if(Result != TA1){ //To d Add your error code here } Result = OWReadByte(); //Read TA2 if(Result != TA2){ //To d Add your error code here } ES = OWReadByte(); //Read ES //To d add your error code after reads Result = OWReadByte(); //Read Data Byte (0x11) Result = OWReadByte(); //Read Data Byte (0x22) Result = OWReadByte(); //Read Data Byte (0x33) Result = OWReadByte(); //Read Data Byte (0x44) Result = OWReadByte(); //Read Data Byte (0x55) Result = OWReadByte(); //Read Data Byte (0x66) Result = OWReadByte(); //Read Data Byte (0x77) Result = OWReadByte(); //Read Data Byte (0x88) //It is recommended that the CRC16 be read back and verified //CRC16 code was left out for conciseness //Second method TA1 = 0x00; TA2 = 0x00; WriteBytes[0] = TA1; WriteBytes[1] = TA2; for(i=2;i<10;i++){ WriteBytes[i] = i; } Result = OWReset(); //1-Wire reset Result = MatchROM(ROMCodes,DS2431); //Select device Result = OWWriteByte(0x0F); //Issue Write Scratchpad command //Write 10 bytes of data (TA1, TA2 & 8 bytes of data) OWWriteBytes(WriteBytes,10); //Write data bytes //It is recommended that the CRC16 be read back and verified //CRC16 code was left out for conciseness Result = OWReset(); //1-Wire reset Result = MatchROM(ROMCodes,DS2431); //Select device Result = OWWriteByte(0xAA); //Issue Read Scratchpad command //Read 13 bytes of data (TA1, TA2, ES, CRC16 & 8 bytes of data) OWReadBytes(ReadBytes,13); //Read data bytes //It is recommended that the CRC16 be read back and verified //CRC16 code was left out for conciseness //Exit overdrive OverdriveDisable(); Result = OWReset(); //Std. reset issued (all devices are now in standard speed) //End of DS2431 example //----------------------------------------------------------------------------------------------------結(jié)論
本應(yīng)用筆記給出了使用API函數(shù)控制DS1WM的示例,無需主機(jī)CPU產(chǎn)生1-Wire時(shí)序。用戶現(xiàn)在應(yīng)該對(duì)選擇和訪問總線上多個(gè)1-Wire器件的通用API函數(shù)有了一定的了解。本文給出了DS28EA00和DS2431總線示例器件的控制和訪問示例,此外還演示了高速模式以及單字節(jié)/多字節(jié)數(shù)據(jù)的讀寫操作。
評(píng)論
查看更多