|
MCU:PIC16F690
系統(tǒng)頻率:8MHZ
目的:實現(xiàn)對18b20 1-wire協(xié)議的實現(xiàn),通過18b20測得環(huán)境溫度;
18b20通過1-wire協(xié)議與主機(jī)實現(xiàn)通訊,1-wire協(xié)儀非常簡單,關(guān)鍵問題是時序問題,只要時序沒問題,就可以通過1-wire協(xié)議與18b20實現(xiàn)通訊;
測試過的程序如下:
/****************************************************************** ** Function name :Reset_18b20(void) ** Description :reset the 18b20 ** Input parameter : ******************************************************************/ void Reset_18b20(void) { DQ_OUT_HIGH(); Delay(10); //do nothing DQ_OUT_LOW(); Delay(180); //output 0 delay about 639us(480~960us) DQ_OUT_HIGH(); Delay(10); //output 1 delay about 45us(15~60us) DQ_IN(); NOP(); while(DQ); //wait for the response Delay(80); //the response delay 290us(60-240us) } /****************************************************************** ** Function name :Write_18b20(unsigned char cmd) ** Description :write to the 18b20 ** Input parameter :unsigned char cmd ******************************************************************/ void Write_18b20(unsigned char cmd) { unsigned char i; for(i=0;i<8;++i) { if(cmd&(1<<i)) { DQ_OUT_LOW(); Delay(1); //13us (1us-15us) DQ_OUT_HIGH(); Delay(20); //delay 80us 寫時隙至少60us } else { DQ_OUT_LOW(); Delay(20); //delay 80us 至少保持60us的時間 DQ_OUT_HIGH(); Delay(1); //delay 13us 時隙恢復(fù)至少1us的時間 } } } /****************************************************************** ** Function name :Read_18b20(void) ** Description :read from the 18b20 ** Input parameter : **Output parameter :unsigned char ******************************************************************/ unsigned char Read_18b20(void) { unsigned char i; unsigned char result=0; for(i=0;i<8;++i) { DQ_OUT_LOW(); Delay(0); //delay us 讀時隙開始,至少1us的時間 DQ_IN(); //15us內(nèi)讀取 NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); if(DQ) { result |= 1<<i; } Delay(1); //delay 13us 時隙恢復(fù)時間 } return result; } /****************************************************************** ** Function name :Read_temp(void) ** Description :read temperature ** Input parameter : **Output parameter :unsigned int ******************************************************************/ unsigned int Read_temp(void) { unsigned char templ; unsigned char temph; unsigned int result=0; Reset_18b20(); Write_18b20(0xCC); //跳過rom Write_18b20(0x44); //溫度轉(zhuǎn)化命令 Delay(200); //delay us (200~300us) Delay(200); Delay(200); Reset_18b20(); Write_18b20(0xCC); //跳過rom Write_18b20(0xBE); //讀取溫度命令 templ=Read_18b20(); temph=Read_18b20(); signal_flag = 0; if(temph & 0xF0) //讀取溫度為零下負(fù)值,此時將溫度高8位取反,低8位取反后加1,即可獲得正確溫度值 { temph = ~temph; templ = ~templ+1; signal_flag = 1; } result=temph; result=result<<8; result|=templ; result =(float)result * 0.625; //精確到1位小數(shù)點(diǎn) return result; } |