1 前 言 DS18B2普遍都是和單片機配合使用,很少有關于DSP與DS18B20的連接的接口報道,所以此文詳細介紹了TMS320LF2407與 DS18B20的連接方法,并且很詳細的介紹了如何用C語言完成精確的軟件延時,從而完成DS18B20與TMS320LF2407之間的基于單線總線協議的數據通訊。 2 DS18B20的時序 2. 1 復位時序 復位使用DS18B20時,首先需將其復位,然后才能執行其它命令。復位時,主機將數據線拉為低電平并保持480us~960us,然后釋放數據線,再由上拉電阻將數據線拉高15~60us,等待DS18B20發出存在脈沖,存在脈沖有效時間為60~240us,這樣,就完成了復位操作。 2.2 寫時序 在主機對DS18B20寫數據時,先將數據線置為高電平,再變為低電平,該低電平應大于1us。在數據線變為低電平后15us內,根據寫“1”或寫“0” 使數據線變高或繼續為低。DS18B20將在數據線變成低電平后15us~60us內對數據線進行采樣。要求寫入DS18B20的數據持續時間應大于 60us而小于120us,兩次寫數據之間的時間間隔應大于1us。 2.3 讀時序 讀時隙當主機從DS18B20讀數據時,主機先將數據線置為高電平,再變為低電平,該低電平應大于1us,然后釋放數據線,使其變為高電平。DS18B20在數據線從高電平變為低電平的15us內將數據送到數據線上。主機可在15us后讀取數據線.。 3 TMS320LF2407與DS18B20的連接 DS18B20有三個引腳。其與TMS320LF2407A的接線圖如下。VDD管腳接5V電壓給傳感器供電。DQ管腳為數據線,與 TMS320LF2407A的IOPA6連接的同時,還要接一個4.7K的上拉電阻,并接到5V的電源上,使數據線在空閑狀態下能自動上拉為高電平。 GND管腳接地。 4 軟件設計 4.1 精確的軟件定時的實現 眾所周知,TMS320LF2407的內核屬于C2000系列的處理器,處理速度達到30MIPs,也就是每條指令所花的時間理論上只有33ns。但是實際情況是,由于DSP外部電路的數據處理速度和數據調用等因素,往往處理速度達不到這個數量級。那怎樣測出每條指令的處理時間從而計算出軟件延時程序的精確時間呢?計算方法如下: 1)、延時程序的C語言代碼為: for(loopindex=0;loopindex 其中loopindex 為unsigned int,無符號整形數值, N為常量,根據所要求的延時時間,計算得出。具體算法在下面給出。 2)、這個for語句在CCS中的編譯器編譯后所產生的匯編語言為: LACL #0h SACL *, 0 LACL * SUB N(計算得到的循環次數) BCND 轉移的地址,GEQ LACC *, 0 ADD #1h SACL *, 0 LACL * SUB N(計算得到的循環次數) BCND 轉移的地址,LT 這些匯編語句所占用的時間可以計算成公式:DELAY=(9N+4)*單個指令周期。 3)、測試出一個指令周期 系統所用晶振為20M,倍頻以后的時鐘頻率為40M,定時器1的分頻為1,也就是說定時器的計時周期為25ns。開啟定時器,單步運行上面的匯編語句,看定時器每次運行后所增加的數值。測試得到,在每次單步運行占一個指令周期的匯編語句后,定時器的數值增加10。也就是說,每個單指令周期的指令占用的時間為:25ns*10=250ns,也就是0.25us。 4)、延時程序的最終計算公式為: DELAY =(9n+4)*0.25us。 由公式可以看出,當n=0時,DELAY=1us,當n=65535時,DELAY= 150ms。 4.2 主要程序 由于文章篇幅的關系,這里只給出復位程序、讀字節程序和整個讀溫度的主程序,寫命令字的程序可以根據上面所述的時序自行編寫。 #define nop() {asm( nop );} #define DATA_PORT PADATDIR #define DATA_MODE 0x0040 #define DATA_OUT 0x4000 #define DATA_BIT 0x0040 #define PIN_HIGH() {PADATDIR=PADATDIR|DATA_OUT|DATA_BIT;} #define PIN_LOW() {DATA_PORT=(PADATDIR|DATA_OUT)&(~DATA_BIT);} #define PIN_LEAVE() {DATA_PORT=DATA_PORT&(~DATA_OUT)|DATA_BIT;} /* 傳感器復位程序 */ unchar reset(void) { unchar retval; unint loopindex="0"; PIN_HIGH(); nop();nop();nop();nop(); /* 延時1us*/ PIN_LOW(); for(loopindex=0;loopindex<213;loopindex++){;} /*置總線為低電平并保持至少480us */ PIN_HIGH(); for(loopindex=0;loopindex<26;loopindex++){;} /*等電阻拉高總線并保持15-60us */ PIN_LEAVE(); /*接受應答信號*/ nop(); if((DATA_PORT & DATA_BIT) == 0x0000) { retval = 0; } else { retval = 1; } PIN_HIGH(); for(loopindex=0;loopindex<106;loopindex++){;} /*延時60-240us */ return(retval); /*返回應答信號 */ } /* 從傳感器中讀一個字節 */ void read_byte(unchar *ReadByte) { int i; unchar temp="0"; unint loopindex="0"; PIN_HIGH(); for(i=0;i<8;i++) { temp="temp">>1; PIN_LOW(); nop();nop();nop();nop(); /*延時2us */ nop();nop();nop();nop(); PIN_HIGH(); for(loopindex=0;loopindex<6;loopindex++){;} /* 延時14us */ PIN_LEAVE(); nop(); if((DATA_PORT & DATA_BIT) == 0x0000) { temp="temp" & 0x7F; } else { temp="temp" | 0x80; } PIN_HIGH(); nop();nop();nop();nop(); /* 延時1us*/ } *ReadByte=temp; return; } /* 將讀得的溫度轉化為十進制 */ float transform(unchar *T) { unchar temp="0"; float temprature="0"; temp=temp|(*(T+1)<<8); temp=temp|*T; if((temp&0x0F800)==0x0F800) { temprature="0-"((~temp)+1)*0.0625; } else { temprature="temp"*0.0625; } return(temprature); } /* 讀取溫度主函數,返回十進制溫度數 */ float read_temp() { Unchar buff; float temprature="0"; unint loopindex="0"; while (reset()==1){}; /* 復位等待從機應答 */ write_byte(0xCC); /* 忽略ROM匹配 */ write_byte(0x44); /* 發送溫度轉化命令 */ for(loopindex=0;loopindex<65535;loopindex++){;} /* 延時300ms,等待數模轉換 */ for(loopindex=0;loopindex<65535;loopindex++){;} while(reset()==1){}; /* 再次復位,等待從機應答 */ write_byte(0xCC); /* 忽略ROM匹配 */ write_byte(0xBE); /* 發送讀溫度命令 */ read_byte(buff); /* 讀出溫度低8位 */ read_byte(buff+1); /* 讀出溫度高8位 */ temprature="transform"(buff); PIN_HIGH(); /* 釋放總線 */ return(temprature); } 5 結束語 DS18B20是一款非常優秀的單總線數字式傳感器。硬件設計簡單,運行可靠。通過分析C語言編譯后的匯編語言可以很明確的計算出軟件延時的時間,從而滿足單線總線通訊的時序要求,從而可以出色的完成DSP與DS18B20通訊的軟件設計。 6 本文創新點 1)、通過C編譯器編譯出來的相應的C語言的延時程序,從而得到其對應的匯編語言,再通過定時器計時,能夠知道單指令周期的時間,從而能夠精確的計算出軟件延時程序的延時時間。 2)、通常DS18B20都是與單片機配合使用的,而本文則詳細的介紹了DS18B20與DSP的結合使用方法,其區別主要是在端口的操作上和延時的控制上。 |