ds18b20温度传感器驱动编写
協議
DS18B20的一線工作協議流程是:初始化→ROM操作指令→存儲器操作指令→數據傳輸,其工作時序包括:初始化時序、寫時序、讀時序。
黑色部分表示單片機操作,藍色部分表示18b20操作,每次主機操作完成之后等待18b20狀態時,必須要釋放總線,比如將IO設置為高阻態什么的。否則18B20沒法把狀態寫到線上。
過程1、2是初始化過程,每次讀取都要初始化,否則18b20處于待機狀態,無法成功讀取。過程1:拉低信號線480-700us,使它復位,然后釋放總線15-60us,18b20會拉低總線60-240us,然后它釋放總線。所以初始化成功的一個標志就是能否讀到18b20這個先低后高的操作時序。
與之對應的代碼,其實是按照時序圖編寫的:
注意觀察dq,
DQ=0;TempDelay(80);拉低信號線480-700us,使它復位,對應時序圖上黑色線一開始為0.
DQ=1; TempDelay(5);釋放總線15-60us,對應時序圖上黑色線變成1.
然后如果18b20拉低總線,說明初始化成功
復位的整體代碼:
void ds_reset(void)//復位函數 {DQ=1;_nop_(); //1usDQ=0;TempDelay(80); //當總線停留在低電平超過480us,總線上所以器件都將被復位,這里//延時約530us總線停留在低電平超過480μs,總線上的所有器件都//將被復位。延時的數據取決于芯片 _nop_(); DQ=1; //產生復位脈沖后,微處理器釋放總線,讓總線處于空閑狀態,原因查//18b20中文資料TempDelay(5); //釋放總線后,以便從機18b20通過拉低總線來指示其是否在線,//存在檢測高電平時間:15~60us, 所以延時44us,進行1-wire presence //detect(單線存在檢測)_nop_();_nop_();_nop_();if(DQ==0)flag=1; //detect 18b20 successelseflag=0; //detect 18b20 failTempDelay(20); //存在檢測低電平時間:60~240us,所以延時約140us_nop_();_nop_();DQ=1; //再次拉高總線,讓總線處于空閑狀態 /**/ }過程3、4是寫1bit數據過程。過程3是寫0 ,過程4是寫1。過程3:拉低總線60us,然后抬高總線5us,完成。過程4:拉低總線5us,然后抬高總線60us,完成。
過程5、6是讀1bit過程。過程5是讀0,過程6是讀1。過程5、6:拉低總線5us,然后釋放總線,讀取總線,如果為0,則讀入0,如果為1,則讀入1。
由于我主要研究的是怎么把數據導出來,所以主要看:發送溫度轉換命令和獲得溫度這兩個函數:
發送溫度轉換命令 ------------------------------------------*/void tem_change() {ds_reset(); delay(1); //約2msds_write_byte(0xcc);ds_write_byte(0x44); }/*---------------------------------------- 獲得溫度: ------------------------------------------*/ uint get_temperature() {float wendu;uchar a,b;ds_reset();delay(1); //約2msds_write_byte(0xcc);ds_write_byte(0xbe);a=ds_read_byte();b=ds_read_byte();temp=b;temp<<=8;temp=temp|a;wendu=temp*0.0625; //溫度讀取temp=wendu*10+0.5;return temp; }讓DS18B20進行一次溫度轉換的具體操作如下:
1、主機先做個復位操作;
2、主機再寫跳過ROM的操作(CCH)命令;
3、然后主機接著寫轉換溫度的操作指令,后面釋放總線至少1秒,讓DS18B20完成轉換操作。需要注意的是每個命令字節在寫的時候都是低字節先寫,例如CCH的二進制為11001100,在寫到總線上時要從低位開始寫,寫的順序是“0、0、1、1、0、0、1、1”。
上面讓DS18B20進行一次溫度轉換就涉及到 ds_write_byte()寫操作
讀取RAM的溫度數據,同樣,這個操作也要按照三個步驟:
1、主機發出復位操作并接受DS18B20的應答(存在)脈沖;
2、主機發出跳過對ROM操作的命令(CCH);
3、主機發出讀取RAM的命令(BEH),隨后主機依次讀取DS18B20發出的從第0-第8,共九個字節的數據。如果只想讀取溫度數據,那在讀完第0和第1個數據后就不再理會后面DS18B20發出的數據即可,同樣讀取數據也是低位在前.
獲得溫度的時候,又涉及到了ds_read_byte();讀操作
結構
由上圖可知,讀溫度時要讀兩次,一個是低8位,一個是高8位。最后要合到一塊。
測溫原理
低溫度系數振蕩器溫度影響小,用于產生固定頻率信號送計數器1;
高溫度系數振蕩頻率隨溫度變化,產生信號脈沖送計數器2;
計數器1和溫度寄存器被預置在 -55℃對應的基數值;
計數器1對低溫度系數振蕩器產生的脈沖進行減法計數;
當計數器1預置減到0時,溫度寄存器加1,計數器1預置重新裝入;
計數器1重新對低溫度系數振蕩器計數;
如此循環,直到計數器2計數到0時,停止對溫度寄存器累加,此時溫度寄存器中的數值即為所測溫度。
高溫度系數振蕩器相當于T/ f 轉換器,將被測溫度轉換成頻率信號f ;
當門打開時對低溫度系數振蕩器計數;
計數門的開啟時間有高溫度系數振蕩器決定。
指令
18B20內部自帶5個ROM指令、6條專用指令ROM指令; Read ROM(33h), 讀ROM Match ROM(55h), 比較 Skip ROM(CCh), 跳過ROM Search ROM(F0h), 搜索、查找 Alarm ROM(ECh), 報警專用指令;Write Scratchpad[便簽式](4Eh), 寫便簽RAM Read Scratchpad(BEh), 讀數據 Copy Scratchpad(48h), 復制 Convert T(44h), 啟動轉換 Recall E2(B8h), 搜索、調用 Read Power Supply(B4h), 讀電源電壓代碼:
/*-------------------------------------------------------------------------------------------------------------------- 初始化:檢測總線控制器發出的復位脈沖 和ds18b20的任何通訊都要從初始化開始初始化序列包括一個由總線控制器發出的復位脈沖 和跟在其后由從機發出的存在脈沖。初始化:復位脈沖+存在脈沖具體操作:總線控制器發出(TX)一個復位脈沖 (一個最少保持480μs 的低電平信號),然后釋放總線, 進入接收狀態(RX)。單線總線由5K 上拉電阻拉到高電平。探測到I/O 引腳上的上升沿后 DS1820 等待15~60μs,然后發出存在脈沖(一個60~240μs 的低電平信號)。-------------------------------------------------------------------------------------------------------------------*/ void ds_reset(void)//復位函數 {DQ=1;_nop_(); //1usDQ=0;TempDelay(80); //當總線停留在低電平超過480us,總線上所以器件都將被復位,這里//延時約530us總線停留在低電平超過480μs,總線上的所有器件都//將被復位。延時的數據取決于芯片 _nop_(); DQ=1; //產生復位脈沖后,微處理器釋放總線,讓總線處于空閑狀態,原因查//18b20中文資料TempDelay(5); //釋放總線后,以便從機18b20通過拉低總線來指示其是否在線,//存在檢測高電平時間:15~60us, 所以延時44us,進行1-wire presence //detect(單線存在檢測)_nop_();_nop_();_nop_();if(DQ==0)flag=1; //detect 18b20 successelseflag=0; //detect 18b20 failTempDelay(20); //存在檢測低電平時間:60~240us,所以延時約140us_nop_();_nop_();DQ=1; //再次拉高總線,讓總線處于空閑狀態 /**/ }/*---------------------------------------- 讀/寫時間隙: DS1820 的數據讀寫是通過時間隙處理 位和命令字來確認信息交換。 ------------------------------------------*/ bit ds_read_bit(void) //讀一位 {bit dat;DQ=0; //單片機(微處理器)將總線拉低_nop_(); //讀時隙起始于微處理器將總線拉低至少1usDQ=1; //拉低總線后接著釋放總線,讓從機18b20能夠接管總線,輸出有效數據_nop_();_nop_(); //小延時一下,讀取18b20上的數據 ,因為從ds18b20上輸出的數據//在讀"時間隙"下降沿出現15us內有效dat=ds; //主機讀從機18b20輸出的數據,這些數據在讀時隙的下降沿出現//15us內有效 TempDelay(10); //所有讀"時間隙"必須60~120us,這里77usreturn(dat); //返回有效數據 } /// uchar ds_read_byte(void ) //讀一字節 {uchar value,i,j; value=0; //一定別忘了給初值 for(i=0;i<8;i++) {j=ds_read_bit();value=(j<<7)|(value>>1); //這一步的說明在一個word文檔里面 } return(value); //返回一個字節的數據 }// void ds_write_byte(uchar dat) //寫一個字節 {uchar i;bit onebit; //一定不要忘了,onebit是一位for(i=1;i<=8;i++) {onebit=dat&0x01;dat=dat>>1; if(onebit) //寫 1 { DQ=0; _nop_(); _nop_(); //看時序圖,至少延時1us,才產生寫"時間隙" DQ=1; //寫時間隙開始后的15μs內允許數據線拉到高電平TempDelay(5); //所有寫時間隙必須最少持續60us } else //寫 0 { DQ=0;TempDelay(8); //主機要生成一個寫0 時間隙,必須把數據線拉到低電平并保持至少60μs,這里64us DQ=1; _nop_();_nop_(); }} }/***************************************** 主機(單片機)控制18B20完成溫度轉換要經過三個步驟: 每一次讀寫之前都要18B20進行復位操作,復位成功后發送 一條ROM指令,最后發送RAM指令,這樣才能對DS18b20進行 預定的操作。 復位要求主CPU將數據線下拉500us,然后釋放,當ds18B20 受到信號后等待16~60us,后發出60~240us的存在低脈沖, 主CPU收到此信號表示復位成功 ******************************************/ /*---------------------------------------- 進行溫度轉換: 先初始化 然后跳過ROM:跳過64位ROM地址,直接向ds18B20發溫度轉換命令,適合單片工作 發送溫度轉換命令 ------------------------------------------*/void tem_change() {ds_reset(); delay(1); //約2msds_write_byte(0xcc); //跳過romds_write_byte(0x44); //啟動轉換 }/*---------------------------------------- 獲得溫度: ------------------------------------------*/ uint get_temperature() {float wendu;uchar a,b;ds_reset();delay(1); //約2msds_write_byte(0xcc);ds_write_byte(0xbe);a=ds_read_byte();b=ds_read_byte();temp=b;temp<<=8;temp=temp|a;wendu=temp*0.0625; //溫度讀取temp=wendu*10+0.5;return temp; } /*---------------------------------------- 讀ROM ------------------------------------------*/ void ds_read_rom() {uchar a,b;ds_reset();delay(30);ds_write_byte(0x33);a=ds_read_byte();b=ds_read_byte(); }void main() {while(1){tem_change(); //12位轉換時間最大為750msdisplay( get_temperature());} }總結
以上是生活随笔為你收集整理的ds18b20温度传感器驱动编写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: xshell6 不更新无法使用_世纪金花
- 下一篇: matlab guide 打开图像并将图