單片機中使用DSB溫度傳感器C語言程序.doc
《單片機中使用DSB溫度傳感器C語言程序.doc》由會員分享,可在線閱讀,更多相關(guān)《單片機中使用DSB溫度傳感器C語言程序.doc(8頁珍藏版)》請在裝配圖網(wǎng)上搜索。
單片機中使用DS18B20溫度傳感器C語言程序(參考1) /******************************************************************************** DS18B20 測溫程序 硬件:AT89S52 (1)單線ds18b20接 P2.2 (2)七段數(shù)碼管接P0口 (3)使用外部電源給ds18b20供電,沒有使用寄生電源 軟件:Kei uVision 3 **********************************************************************************/ #include "reg52.h" #include "intrins.h" #define uchar unsigned char #define uint unsigned int sbit ds=P2^2; sbit dula=P2^6; sbit wela=P2^7; uchar flag ; uint temp; //參數(shù)temp一定要聲明為 int 型 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //不帶小數(shù)點數(shù)字編碼 uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, 0x87,0xff,0xef}; //帶小數(shù)點數(shù)字編碼 /*延時函數(shù)*/ void TempDelay (uchar us) { while(us--); } void delay(uint count) //延時子函數(shù) { uint i; while(count) { i=200; while(i>0) i--; count--; } } /*串口初始化,波特率9600,方式1 */ void init_com() { TMOD=0x20; //設置定時器1為模式2 TH1=0xfd; //裝初值設定波特率 TL1=0xfd; TR1=1; //啟動定時器 SM0=0; //串口通信模式設置 SM1=1; // REN=1; //串口允許接收數(shù)據(jù) PCON=0; //波特率不倍頻 // SMOD=0; //波特率不倍頻 // EA=1; //開總中斷 //ES=1; //開串行中斷 } /*數(shù)碼管的顯示 */ void display(uint temp) { uchar bai,shi,ge; bai=temp/100; shi=temp%100/10; ge=temp%100%10; dula=0; P0=table[bai]; //顯示百位 dula=1; //從0到1,有個上升沿,解除鎖存,顯示相應段 dula=0; //從1到0再次鎖存 wela=0; P0=0xfe; wela=1; wela=0; delay(1); //延時約2ms P0=table1[shi]; //顯示十位 dula=1; dula=0; P0=0xfd; wela=1; wela=0; delay(1); P0=table[ge]; //顯示個位 dula=1; dula=0; P0=0xfb; wela=1; wela=0; delay(1); } /***************************************** 時序:初始化時序、讀時序、寫時序。 所有時序都是將主機(單片機)作為主設備,單總 線器件作為從設備。而每一次命令和數(shù)據(jù)的傳輸 都是從主機主動啟動寫時序開始,如果要求單總 線器件回送數(shù)據(jù),在進行寫命令后,主機需啟動 讀時序完成數(shù)據(jù)接收。數(shù)據(jù)和命令的傳輸都是低 位在先。 初始化時序:復位脈沖 存在脈沖 讀;1 或 0時序 寫;1 或 0時序 只有存在脈沖信號是從18b20(從機)發(fā)出的,其 它信號都是由主機發(fā)出的。 存在脈沖:讓主機(總線)知道從機(18b20)已 經(jīng)做好了準備。 ******************************************/ /*-------------------------------------------------------------------------------------------------------------------- 初始化:檢測總線控制器發(fā)出的復位脈沖 和ds18b20的任何通訊都要從初始化開始 初始化序列包括一個由總線控制器發(fā)出的復位脈沖 和跟在其后由從機發(fā)出的存在脈沖。 初始化:復位脈沖+存在脈沖 具體操作: 總線控制器發(fā)出(TX)一個復位脈沖 (一個最少保持480μs 的低電平信號),然后釋放總線, 進入接收狀態(tài)(RX)。單線總線由5K 上拉電阻拉到高電平。探測到I/O 引腳上的上升沿后 DS1820 等待15~60μs,然后發(fā)出存在脈沖(一個60~240μs 的低電平信號)。 具體看18b20 單線復位脈沖時序和1-wire presence detect "的時序圖 -------------------------------------------------------------------------------------------------------------------*/ void ds_reset(void) { ds=1; _nop_(); //1us ds=0; TempDelay(80); //當總線停留在低電平超過480us,總線上所以器件都將被復位,這里延//時約530us總線停留在低電平超過480μs,總線上的所有器件都將被復位。 _nop_(); ds=1; //產(chǎn)生復位脈沖后,微處理器釋放總線,讓總線處于空閑狀態(tài),原因查18b20中文資料 TempDelay(5); //釋放總線后,以便從機18b20通過拉低總線來指示其是否在線, //存在檢測高電平時間:15~60us, 所以延時44us,進行1-wire presence detect(單線存在檢測) _nop_(); _nop_(); _nop_(); if(ds==0) flag=1; //detect 18b20 success else flag=0; //detect 18b20 fail TempDelay(20); //存在檢測低電平時間:60~240us,所以延時約140us _nop_(); _nop_(); ds=1; //再次拉高總線,讓總線處于空閑狀態(tài) /**/ } 原理解釋:控制器對 18B20 操作流程: 1 , 復位 : 首先我們必須對 DS18B20 芯片進行復位 , 復位就是由控制器 ( 單片機 ) 給 DS18B20 單總線至少 480uS 的低電平信號 。 當 18B20 接到此復位信號后則會 在 15~60uS 后回發(fā)一個芯片的存在脈沖。 2 , 存在脈沖 : 在復位電平結(jié)束之后 , 控制器應該將數(shù)據(jù)單總線拉高 , 以便于 在 15~60uS 后接收存在脈沖,存在脈沖為一個 60~240uS 的低電平信號。至此,通信雙方已經(jīng)達成了基本的協(xié)議,接下來將會是控制器與 18B20 間的數(shù)據(jù)通信 。 /*---------------------------------------- 讀/寫時間隙: DS1820 的數(shù)據(jù)讀寫是通過時間隙處理 位和命令字來確認信息交換。 ------------------------------------------*/ bit ds_read_bit(void) //讀一位 { bit dat; ds=0; //單片機(微處理器)將總線拉低 _nop_(); //讀時隙起始于微處理器將總線拉低至少1us ds=1; //拉低總線后接著釋放總線,讓從機18b20能夠接管總線,輸出有效數(shù)據(jù) _nop_(); _nop_(); //小延時一下,讀取18b20上的數(shù)據(jù) ,因為從ds18b20上輸出的數(shù)據(jù) //在讀"時間隙"下降沿出現(xiàn)15us內(nèi)有效 dat=ds; //主機讀從機18b20輸出的數(shù)據(jù),這些數(shù)據(jù)在讀時隙的下降沿出現(xiàn)//15us內(nèi)有效 TempDelay(10); //所有讀"時間隙"必須60~120us,這里77us return(dat); //返回有效數(shù)據(jù) } 原理:圖 8 讀時間隙時控制時的采樣時間應該更加的精確才行 , 讀時間隙時也是必須先由主 機產(chǎn)生至少 1uS 的低電平,表示讀時間的起始。隨后在總線被釋放后的 15uS 中 DS18B20 會發(fā)送內(nèi)部數(shù)據(jù)位,這時控制如果發(fā)現(xiàn)總線為高電平表示讀出 “ 1 ” , 如果總線為低電平則表示讀出數(shù)據(jù) “ 0 ” 。每一位的讀取之前都由控制器加一個 起始信號。注意:如圖 8 所示,必須在讀間隙開始的 15uS 內(nèi)讀取數(shù)據(jù)位才可以 保證通信的正確。 在通信時是以 8 位 “ 0 ” 或 “ 1 ” 為一個字節(jié) , 字節(jié)的讀或?qū)懯菑母呶婚_始的 , 即A7 到 A0. 字節(jié)的讀寫順序也是如圖 2 自上而下的。 uchar ds_read_byte(void ) //讀一字節(jié) { uchar value,i,j; value=0; //一定別忘了給初值 for(i=0;i<8;i++) { j=ds_read_bit(); value=(j<<7)|(value>>1); //這一步的說明在一個word文檔里面 ?? } return(value); //返回一個字節(jié)的數(shù)據(jù) } void ds_write_byte(uchar dat) //寫一個字節(jié) { uchar i; bit onebit; //一定不要忘了,onebit是一位 for(i=1;i<=8;i++) { onebit=dat&0x01; dat=dat>>1; //由低到高傳送數(shù)據(jù) if(onebit) //寫 1 { ds=0; _nop_(); _nop_(); //看時序圖,至少延時1us,才產(chǎn)生寫"時間隙" ds=1; //寫時間隙開始后的15μs內(nèi)允許數(shù)據(jù)線拉到高電平 TempDelay(5); //所有寫時間隙必須最少持續(xù)60us } else //寫 0 { ds=0; TempDelay(8); //主機要生成一個寫0 時間隙,必須把數(shù)據(jù)線拉到低電平并保持至少60μs,這里64us ds=1; _nop_(); _nop_(); } } } /***************************************** 主機(單片機)控制18B20完成溫度轉(zhuǎn)換要經(jīng)過三個步驟: 每一次讀寫之前都要18B20進行復位操作,復位成功后發(fā)送 一條ROM指令,最后發(fā)送RAM指令,這樣才能對DS18b20進行 預定的操作。 復位要求主CPU將數(shù)據(jù)線下拉500us,然后釋放,當ds18B20 受到信號后等待16~60us,后發(fā)出60~240us的存在低脈沖, 主CPU收到此信號表示復位成功 ******************************************/ /*---------------------------------------- 進行溫度轉(zhuǎn)換: 先初始化 然后跳過ROM:跳過64位ROM地址,直接向ds18B20發(fā)溫度轉(zhuǎn)換命令,適合單片工作 發(fā)送溫度轉(zhuǎn)換命令 ------------------------------------------*/ void tem_change() { ds_reset(); delay(1); //約2ms ds_write_byte(0xcc);//單線情況下,跳躍ROM指令 ds_write_byte(0x44);//溫度轉(zhuǎn)換指令 } /*---------------------------------------- 獲得溫度: ------------------------------------------*/ uint get_temperature() { float wendu; uchar a,b; ds_reset(); delay(1); //約2ms ds_write_byte(0xcc); ds_write_byte(0xbe);//發(fā)送讀溫度命令 a=ds_read_byte();//讀出溫度低8位 b=ds_read_byte();//讀書溫度高8位 temp=b; temp<<=8; temp=temp|a; wendu=temp*0.0625; //得到真實十進制溫度值,因為DS18B20 //可以精確到0.0625度,所以讀回數(shù)據(jù)的最低位代表的是 //0.0625度 temp=wendu*10+0.5; //放大十倍,這樣做的目的將小數(shù)點后第一位 //也轉(zhuǎn)換為可顯示數(shù)字,同時進行一個四舍五入操作。 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() { uint a; init_com(); while(1) { tem_change(); //12位轉(zhuǎn)換時間最大為750ms for(a=10;a>0;a--) { display( get_temperature()); } } } [此文檔可自行編輯修改,如有侵權(quán)請告知刪除,感謝您的支持,我們會努力把內(nèi)容做得更好] 最新可編輯word文檔- 1.請仔細閱讀文檔,確保文檔完整性,對于不預覽、不比對內(nèi)容而直接下載帶來的問題本站不予受理。
- 2.下載的文檔,不會出現(xiàn)我們的網(wǎng)址水印。
- 3、該文檔所得收入(下載+內(nèi)容+預覽)歸上傳者、原創(chuàng)作者;如果您是本文檔原作者,請點此認領(lǐng)!既往收益都歸您。
下載文檔到電腦,查找使用更方便
15 積分
下載 |
- 配套講稿:
如PPT文件的首頁顯示word圖標,表示該PPT已包含配套word講稿。雙擊word圖標可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設計者僅對作品中獨創(chuàng)性部分享有著作權(quán)。
- 關(guān) 鍵 詞:
- 單片機 使用 DSB 溫度傳感器 語言 程序
鏈接地址:http://weibangfood.com.cn/p-5377243.html