日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ds18b20温度转换指令_【Proteus】DS18B20简易温控器

發布時間:2024/9/19 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ds18b20温度转换指令_【Proteus】DS18B20简易温控器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

DS18B20是單片機課設或者仿真項目中一個比較常用的數字溫度傳感器,因此使用DS18B20仿真一個簡易的溫控器,超過溫度就打開風扇,低于某溫度就用繼電器打開加熱絲。整個程序我都會附在最后,如果懶得復制粘貼,要所有的工程以及仿真的話,就給我點贊賞吧。

整個仿真如圖:

首先便是查找DS18B20的手冊,編寫DS18B20的驅動程序。閱讀手冊可知:

DS18B20的數據類型

DS18B20提供9位與12位攝氏溫度測量進度,上電默認是12位,如果我們就用默認的12位精度的話,那么最后從DS18B20讀出來的數據要乘以0.0625,之后得到的就是實際溫度,單位攝氏度。測量范圍為 -55℃至125℃。

DS18B20的通信方式

DS18B20是單總線接口,也就是說,只需要一個通信接口與單片機進行通信,DS18B20看起來就比較像三極管,但它是兩根電源線+一根通信線,每個DS18B20都有一個獨一無二的64位序列號,也就是說,在一個總線上可以連接多個DS18B20設備,控制不同的DS18B20來讀取多點溫度。

DS18B20的外圍電路

DS18B20的電路部分也很簡單,不需要外圍元件,使用3V-5.5V供電。

DS20B20的控制流程

DS18B20上電默認是12位精度,主設備必須向DS18B20發送溫度轉換命令[44H]才能開始溫度轉換。當然DS18B20進行溫度轉換需要時間,當發送完[44H]讀命令之后,主設備就可以執行讀數據時序了,等待DS18B20轉換完成,在DS18B20轉換完成之前,都會返回0,轉換完成之后,就會返回1。

DS18B20的溫度數據是以一個16位二進制補碼數的形式存儲在溫度寄存器中。我們現在就確定使用12位精度的形式,那么首位就為符號位,之后是數據位,如圖:

此外要注意這個上電復位時默認是85℃,有些人看到上電85度還以為是錯的,因此瘋狂修改程序,其實是正?,F象,自己程序注意一下即可。

了解了這些,我們就開始著手寫DS18B20的驅動程序。
手冊上對于事件流程的說明如圖:

注意最后一句話:當執行完這些ROM命令之后,主設備必須回到上述步驟中的第一步。也就是說,我們首先需要進行初始化,然后發送ROM命令,然后發送功能命令。之后便是等待ROM命令執行完,如果要發送下一個ROM命令,則又需要重新回到第一步初始化,再發送下一個ROM命令,再發送功能命令。這一點需要記住。

那么我們的整個讀取流程就基本確定了:
初始化->跳過讀序列號(ROM命令)->啟動溫度轉化(功能命令)->延時等待ROM命令與溫度轉換執行結束->初始化->跳過讀序列號(ROM命令)->讀取溫度(功能命令)

因為我們就使用一個DS18B20,因此可以跳過這個讀序列號。下面我們就按照這個流程來編寫各部分程序。

初始化

由時序圖可知,初始化程序首先需要將總線拉為低電平至少480us的時間,然后釋放總線,總線置為高電平,DS18B20就會檢測這個上升沿,檢測到上升沿之后,等待15-60us,將總線再拉低至少480us,也就是說,高電平的時間也要持續15-60us。

初始化程序如下:

/@@**************************************************************************** 函數功能:延時子程序 ****************************************************************************/ void delay(uint k) {while(k--); } /@@**************************************************************************** 函數功能:DS18B20初始化子程序 ****************************************************************************/ void ds18b20_init(void) {DQ=1; //DQ先置高delay(16); //延時DQ = 0; //發送復位脈沖delay(80); //延時(>480us)DQ = 1; //拉高數據線delay(16); //等待(15~60us)delay(60);DQ = 1; }

寫數據

寫數據分為寫0和寫1,在DS18B20中分為寫0時段和寫1時段,每個寫時段最小必須由60us的時序時間并且要有1us的恢復時間。

在寫1時段,在總線拉低之后,主設備必須在15us之內釋放總線,總線釋放后,上拉電阻將總線拉高;在寫0時段,在總線拉低后,整個時段必須一致拉低總線,至少60us。

簡單來說,就是這樣:在主設備初始化寫時段后,DS18B20會在15-60us內對總線進行采樣,如果采樣時候是高電平,則DS18B20會寫入1,反之則寫入0。

程序如下:

/****************************************************************************函數功能:向DS18B20寫一字節數據入口參數:dat出口參數:****************************************************************************/ void WriteOneChar(uchar dat) {uchar i=0;DQ=1;delay(1);for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;delay(5);DQ=1;dat>>=1;} }

讀數據

主設備在執行完讀暫存寄存器[BEh]之后,需要即使生成讀時段,才可以讀取數據。每個讀時段最小必須有60us的持續時間與1us的恢復時間。從DS18B20中發送出來的數據在讀時序后僅有15us的有效時間,因此,主設備在開始讀時段后的15us之內必須釋放總線來讀取數據。時序如上圖所示。

程序如下:

/****************************************************************************函數功能:向DS18B20讀一字節數據入口參數:出口參數:dat****************************************************************************/uchar ReadOneChar(void){uchar i=0;uchar dat=0;DQ=1;delay(1);for (i=8;i>0;i--){DQ=0;dat>>=1;DQ=1;delay(1);if(DQ)dat|=0x80;delay(30);DQ=1;}return dat; }

然后就是根據手冊查找一些重要的命令,包括跳過讀序列號,讀取溫度命令等等,這一部分就不再贅述。然后我們就可以按照我們之前總結的讀取溫度的流程來編寫整個讀取溫度的程序:

/****************************************************************************函數功能:向DS18B20讀溫度值 入口參數: 出口參數:temperature溫度讀取流程: 初始化->跳過讀序列號->啟動溫度轉化->延時->初始化->跳過讀序列號->讀取溫度并顯示****************************************************************************/ float ReadTemperature(void) {float temperature = 0.0;uint temflag = 0;uint tt = 0;uchar tempL=0; //臨時變量低位uchar tempH=0; //臨時變量高位ds18b20_init(); //初始化WriteOneChar(0xcc); //跳過讀序列號的操作WriteOneChar(0x44); //啟動溫度轉換delay(125); //轉換需要一點時間,延時ds18b20_init(); //初始化WriteOneChar(0xcc); //跳過讀序列號的操作WriteOneChar(0xbe); //讀溫度寄存器(頭兩個值分別為溫度的低位和高位)tempL=ReadOneChar(); //讀出溫度的低位LSBtempH=ReadOneChar(); //讀出溫度的高位MSB//溫度轉換,把高低位做相應的運算轉化為實際溫度tt = tempH<<8;tt = tt|tempL;if(tt&0xf800) //判斷是否是負溫度{ //是負溫度tt = ~tt + 1; temflag = 0;}else{tt = tt; temflag = 1;}temperature = (float)tt;temperature = temperature * 0.0625; // delay(200);/*負溫度*/if(temflag == 0){temperature = -temperature;}/*正溫度*/else{temperature = temperature;}return temperature; //返回溫度值 }

然后就是用1602來顯示出來,看一下我們的程序對不對,關于1602的驅動程序,在我之前的文章中有說明,這里就不再說明。

測試主程序如下:

/@@*顯示函數*/ void display(void) {char *string1 = "TEM : ";char *string2 = " C ";char *string3 = "High:";char *string4 = "Low:"; char Display1[16]; //第一行顯示數組char Display2[16]; //第二行顯示數組//顯示溫度sprintf((char*)Display1,"%s%d%s",string1,temp,string2); print_string(Display1,1); //顯示過溫低溫點sprintf((char*)Display2,"%s%d %s%d",string3,tempOver,string4,tempLow); print_string(Display2,2); } void main() {lcd_init();SW = 0;Motor = 0;while(1){temp = (int)ReadTemperature(); //讀取溫度display(); //顯示} }

測試結果:

這里的顯示程序中我加了閾值顯示,這里設置的是高溫閾值為30,低溫閾值為27。因為為了后續方便,所以我就把閾值設置得比較近,這個可以自行修改。

之后就是比較簡單的邏輯了,超過高溫閾值就關閉加熱絲打開風扇,低于低溫閾值就關閉風扇,打開加熱絲。主程序如下:

void main() {lcd_init();SW = 0;Motor = 0;while(1){temp = (int)ReadTemperature(); //讀取溫度display(); //顯示/*過溫 打開風扇,關閉加熱絲*/if(temp > tempOver){SW = 0; Motor = 1;}/*低溫 關閉風扇,打開加熱絲*/else if(temp < tempLow){SW = 1;Motor = 0;}} }

關于風扇的電路,我這里就直接用了一個ULN2003,這個是小電流電機的,如果要更換24V大電流電機驅動,或者要加上PWM調速,我后續會更新這方面的文章。

效果如下:

如果要全部的工程,仿真就點贊私聊我喔。

1602程序在之前的文章中有發,因此1602程序就不發了。我的工程目錄如下:

所有源代碼如下:

main.c

#include <reg52.h> #include <stdio.h> #include "1602.h" #include "ds18b20.h" #define uchar unsigned char #define uint unsigned intsbit SW = P1^0; //繼電器控制加熱絲 sbit Motor = P1^1; //電機接口int temp = 0; //存儲溫度 int tempOver = 30; //過溫溫度 int tempLow = 27; //低溫溫度 sbit key1 = P3^0; //增加過溫溫度 sbit key2 = P3^1; //減小過溫溫度 sbit key3 = P3^0; //增加低溫溫度 sbit key4 = P3^1; //減小低溫溫度uint key_result = 0; //保存按鍵結果void key_delay(uchar t) { int j; for(;t!=0; t--) for (j=0;j<255;j++); }/*按鍵檢測 如果按鍵1被按下就返回1 如果按鍵2被按下就返回2 如果沒有按鍵按下就返回0*/ uint key_scan(void) {uint result = 0;/*先將按鍵電平拉高*/key1 = 1;key2 = 1;/*檢測按鍵1是否被按下*/if(key1 == 0){key_delay(5);if(key1 == 0){result = 1;}}/*檢測按鍵2是否被按下*/if(key2 == 0){key_delay(5);if(key2 == 0){result = 2;}} return result; }/*顯示函數*/ void display(void) {char *string1 = "TEM : ";char *string2 = " C ";char *string3 = "High:";char *string4 = "Low:"; char Display1[16]; //第一行顯示數組char Display2[16]; //第二行顯示數組//顯示溫度sprintf((char*)Display1,"%s%d%s",string1,temp,string2); print_string(Display1,1); //顯示過溫低溫點sprintf((char*)Display2,"%s%d %s%d",string3,tempOver,string4,tempLow); print_string(Display2,2); }void main() {lcd_init();SW = 0;Motor = 0;while(1){temp = (int)ReadTemperature(); //讀取溫度display(); //顯示/*過溫 打開風扇,關閉加熱絲*/if(temp > tempOver){SW = 0; Motor = 1;}/*低溫 關閉風扇,打開加熱絲*/else if(temp < tempLow){SW = 1;Motor = 0;}} }

DS18B20源文件:

#include <reg52.h> #include <stdio.h> #include "ds18b20.h"/***************************溫度傳感器信號引腳******************************************/ sbit DQ=P1^5; //數據傳輸線接單片機的相應的引腳/****************************************************************************函數功能:延時子程序****************************************************************************/ void delay(uint k) {while(k--); }/****************************************************************************函數功能:DS18B20初始化子程序****************************************************************************/ void ds18b20_init(void) {DQ=1; //DQ先置高delay(16); //延時DQ = 0; //發送復位脈沖delay(80); //延時(>480us)DQ = 1; //拉高數據線delay(16); //等待(15~60us)delay(60);DQ = 1; }/****************************************************************************函數功能:向DS18B20讀一字節數據入口參數:出口參數:dat****************************************************************************/uchar ReadOneChar(void){uchar i=0;uchar dat=0;DQ=1;delay(1);for (i=8;i>0;i--){DQ=0;dat>>=1;DQ=1;delay(1);if(DQ)dat|=0x80;delay(30);DQ=1;}return dat; }/****************************************************************************函數功能:向DS18B20寫一字節數據入口參數:dat出口參數:****************************************************************************/ void WriteOneChar(uchar dat) {uchar i=0;DQ=1;delay(1);for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;delay(5);DQ=1;dat>>=1;} }/****************************************************************************函數功能:向DS18B20讀溫度值 入口參數: 出口參數:temperature溫度讀取流程: 初始化->跳過讀序列號->啟動溫度轉化->延時->初始化->跳過讀序列號->讀取溫度并顯示****************************************************************************/ float ReadTemperature(void) {float temperature = 0.0;uint temflag = 0;uint tt = 0;uchar tempL=0; //臨時變量低位uchar tempH=0; //臨時變量高位ds18b20_init(); //初始化WriteOneChar(0xcc); //跳過讀序列號的操作WriteOneChar(0x44); //啟動溫度轉換delay(125); //轉換需要一點時間,延時ds18b20_init(); //初始化WriteOneChar(0xcc); //跳過讀序列號的操作WriteOneChar(0xbe); //讀溫度寄存器(頭兩個值分別為溫度的低位和高位)tempL=ReadOneChar(); //讀出溫度的低位LSBtempH=ReadOneChar(); //讀出溫度的高位MSB//溫度轉換,把高低位做相應的運算轉化為實際溫度tt = tempH<<8;tt = tt|tempL;if(tt&0xf800) //判斷是否是負溫度{ //是負溫度tt = ~tt + 1; temflag = 0;}else{tt = tt; temflag = 1;}temperature = (float)tt;temperature = temperature * 0.0625; // delay(200);/*負溫度*/if(temflag == 0){temperature = -temperature;}/*正溫度*/else{temperature = temperature;}return temperature; //返回溫度值 } 與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的ds18b20温度转换指令_【Proteus】DS18B20简易温控器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人交配视频 | 天堂av免费观看 | 国产成人黄色av | 最新日韩一区 | 干成人网 | 精品黑人一区二区三区 | 国产一区亚洲二区 | 欧美与黑人午夜性猛交久久久 | 免费看一级片 | 亚洲激情中文 | www色网站| 久久午夜场 | 日韩在线观看视频一区 | 一级特黄aa | 日韩黄色大全 | 色香影视 | 91麻豆国产精品 | 亚洲一区二区影院 | 中文字幕免费高清视频 | 兄弟兄弟全集免费观看 | 美女网站免费黄 | 亚洲精品66 | 国产又粗又硬又黄的视频 | 一区二区中文在线 | 午夜影视网| 亚洲精品一区二区18漫画 | 久久中文字 | 另类亚洲色图 | 97国产在线播放 | 日韩精品专区 | 亚州精品国产精品乱码不99按摩 | 在线99| 免费激情视频网站 | 91超碰在线免费观看 | 99re视频在线 | 青青操在线视频 | 麻豆资源| 好吊操视频这里只有精品 | 夫妻性生活黄色片 | 五月天国产视频 | 黄色不卡| 性生交大全免费看 | 日韩小视频 | 国产精品毛片一区二区在线看舒淇 | 在线激情小视频 | 四虎国产在线观看 | 亚洲一级在线观看 | 尹人av| 精品中文字幕一区二区 | 一本大道久久 | 欧美日韩一区二区区 | 国产免费一区二区 | 精品无码人妻一区二区三 | 91福利小视频 | 青青视频在线播放 | 大黑人交交护士xxxxhd | 99re免费视频精品全部 | 亚洲jizzjizz日本少妇 | 亚洲香蕉久久 | 森泽佳奈中文字幕 | 精品96久久久久久中文字幕无 | 久久人人爽人人爽人人 | 男人天堂999| 日本激情视频 | 久久久久久久97 | 人人草人人爽 | 四虎国产 | 本道久久| 亚洲激情免费视频 | 看全色黄大色黄大片女一次牛 | 毛片视屏 | 日本成人福利视频 | 午夜aaa片一区二区专区 | 亚洲AV无码国产成人久久 | 日本不卡一区二区三区 | 日韩黄色免费看 | 亚洲高清一区二区三区 | 午夜影院免费 | 欧美一区二区三区久久成人精品 | 久久精品国产成人av | 成人91免费视频 | 三级网站免费 | 日韩欧美在线免费观看 | 日韩av中文字幕在线免费观看 | 成人精品免费 | 国产精品不卡在线 | 亚洲精品久久久久久久久久 | 毛片88| 国产天堂精品 | 日韩欧美中 | 高h奶汁双性受1v1 | 精品无码久久久久国产 | 亚洲中文一区二区三区 | 日韩丝袜一区 | 国产精品永久免费观看 | 日韩视频一 | 国产传媒国产传媒 | 成人小视频免费看 | 日本免费高清视频 |