很簡單,很基礎的,共享給大家
完整的課程設計下載:
數字溫度計的設計.doc
(525 KB, 下載次數: 190)
2016-6-6 15:57 上傳
點擊文件名下載附件
摘 要隨著“信息時代”的到來,作為獲取信息的手段——傳感器技術得到了顯著的進步,其應用領域越來越廣泛,對其要求越來越高,需求越來越迫切。傳感器技術已成為衡量一個國家科學技術發展水平的重要標志之一。因此,了解并掌握傳感器的基本結構、工作原理及特性是非常重要的。在日常生活及工農業生產中,經常要用到溫度的檢測及控制,傳統的測溫元件有熱電偶和熱電阻。而熱電偶和熱電阻測出的一般都是電壓,再轉換成對應的溫度,需要比較多的外部硬件支持, 其缺點如下:1. 硬件電路復雜;2. 軟件調試復雜;3. 制作成本高。為了提高對傳感器的認識和了解,尤其是對溫度傳感器的深入研究以及其用法與用途,基于實用、廣泛和典型的原則而設計了本系統。本文利用單片機結合傳感器技術開發設計,文中把傳感器理論與單片機實際應用有機結合,詳細地講述了利用溫度傳感器DS18B20測量環境溫度,同時51單片機在現代電子產品中廣泛應用以及其技術已經非常成熟,DS18B20可以直接讀出被測溫度值,而且采用三線制與單片機相連,減少了外部的硬件電路,具有低成本和易使用的特點。 關鍵詞: 信息時代 溫度傳感器 51單片機
目 錄
摘 要 目 錄 第一章 緒論 1.1 背景 1.2 設計目的 1.2.1掌握溫度計,報警系統的設計、組裝與調試方法。 1.2.2熟悉仿真軟件(proteus)的使用。 1.2.3重點掌握單片機的使用及其各引腳的功能。 第二章 原理分析 2.1原理框圖 2.2 原理分析 第三章 實現過程 3.1顯示電路 3.2數碼管驅動電路 3.3報警電路 3.4數字溫度傳感器 3.5單片機最小系統電路 3.6 按鍵電路 3.7數字溫度計的實物圖 3.8系統板上硬件連錢 3.9 系統調試與分析 3.10 元件清單及程序代碼 心得體會
1.1 背景 在日常生活及工農業生產中,經常要用到溫度的檢測及控制,傳統的測溫元件有熱電偶和熱電阻。而熱電偶和熱電阻測出的一般都是電壓,再轉換成對應的溫度,需要比較多的外部硬件支持, 其缺點如下:1. 硬件電路復雜;2. 軟件調試復雜;3. 制作成本高。為了提高對傳感器的認識和了解,尤其是對溫度傳感器的深入研究以及其用法與用途,基于實用、廣泛和典型的原則而設計了本系統。 1.2 設計目的 1.2.1掌握溫度計,報警系統的設計、組裝與調試方法。 1.2.2熟悉仿真軟件(proteus)的使用。 1.2.3重點掌握單片機的使用及其各引腳的功能。 第二章 原理分析 2.1原理框圖 protues仿真圖
Protues仿真圖顯示當前溫度30℃ 2.2 原理分析 整個系統由單片機控制,溫度傳感器采用18B20。18b20采用單總線方式與單片機相連.把采集到得溫度信息傳給單片機。單片機采集到的溫度輸出到四個數碼管上進行顯示。當四位數碼管顯示的溫度超過上限值時可以實現報警功能。 DS18B20原理與分析 DS18B20是美國DALLAS半導體公司繼DS1820之后最新推出的一種改進型智能溫度傳感器。與傳統的熱敏電阻相比,他能夠直接讀出被測溫度并且可根據實際要求通過簡單的編程實現9~12位的數字值讀數方式?梢苑謩e在93.75 ms和750 ms內完成9位和12位的數字量,并且從DS18B20讀出的信息或寫入DS18B20的信息僅需要一根口線(單線接口)讀寫,溫度變換功率來源于數據總線,總線本身也可以向所掛接的DS18B20供電,而無需額外電源。因而使用DS18B20可使系統結構更趨簡單,可靠性更高。他在測溫精度、轉換時間、傳輸距離、分辨率等方面較DS1820有了很大的改進,給用戶帶來了更方便的使用和更令人滿意的效果。 1.DS18B20簡介 (1)獨特的單線接口方式:DS18B20與微處理器連接時僅需要一條口線即可實現微處理器與DS18B20的雙向通訊。 (2)在使用中不需要任何外圍元件。 (3)可用數據線供電,電壓范圍:+3.0~ +5.5 V。 (4)測溫范圍:-55 ~+125 ℃。固有測溫分辨率為0.5 ℃。 (5)通過編程可實現9~12位的數字讀數方式。 (6)用戶可自設定非易失性的報警上下限值。 (7)支持多點組網功能,多個DS18B20可以并聯在惟一的三線上,實現多點測溫。 (8)負壓特性,電源極性接反時,溫度計不會因發熱而燒毀,但不能正常工作。 DS18B20的測溫原理 DS18B20的測溫原理如圖2所示,圖中低溫度系數晶振的振蕩頻率受溫度的影響很小〔1〕,用于產生固定頻率的脈沖信號送給減法計數器1,高溫度系數晶振隨溫度變化其震蕩頻率明顯改變,所產生的信號作為減法計數器2的脈沖輸入,圖中還隱含著計數門,當計數門打開時,DS18B20就對低溫度系數振蕩器產生的時鐘脈沖后進行計數,進而完成溫度測量。計數門的開啟時間由高溫度系數振蕩器來決定,每次測量前,首先將-55 ℃所對應的基數分別置入減法計數器1和溫度寄存器中,減法計數器1和溫度寄存器被預置在 -55 ℃ 所對應的一個基數值。減法計數器1對低溫度系數晶振產生的脈沖信號進行減法計數,當減法計數器1的預置值減到0時溫度寄存器的值將加1,減法計數器1的預置將重新被裝入,減法計數器1重新開始對低溫度系數晶振產生的脈沖信號進行計數,如此循環直到減法計數器2計數到0時,停止溫度寄存器值的累加,此時溫度寄存器中的數值即為所測溫度。圖2中的斜率累加器用于補償和修正測溫過程中的非線性,其輸出用于修正減法計數器的預置值,只要計數門仍未關閉就重復上述過程,直至溫度寄存器值達到被測溫度值,這就是DS18B20的測溫原理。 第三章 實現過程 3.1顯示電路 四位共陽LED數碼管:用來顯示溫度的大小,可直接讀取,溫度精確到0.1℃。四位數碼管如圖所示,從左到右依次是百位,十位,個位,十分位。 圖 1 數碼管 3.2數碼管驅動電路 三極管8050:來驅動四位數碼管,如下圖所示三極管Q1 、Q2 、Q3、Q4。 圖 2 三極管8050 3.3報警電路 三極管8550驅動蜂鳴器:如下圖所示三極管Q6來驅動蜂鳴器BUZ1。 圖 3 三極管8550、蜂鳴器BUZ1 3.4數字溫度傳感器 數字溫度傳感器DS18B20:如下圖所示 圖 4 DS18B20 3.5單片機最小系統電路 單片機最小化系統:如下圖所示系統工作時,最小化系統運行。
圖 5 最小化系統 3.6 按鍵電路 按鍵:如圖所示按鍵K1為進入/退出設置鍵;K2為增加鍵;K3為減少鍵。
圖 6 按鍵
3.7數字溫度計的實物圖 數字溫度計顯示當前溫度25.7℃ I
圖7 數字溫度計實物圖 3.8系統板上硬件連錢 1). 把“單片機系統“區域中的P0.0-P0.7端口用8芯排線依次連接到數碼管A-DP端口上; (2). 把“單片機系統”區域中的P3.0-P3.2端口用線連接到按鍵K1-K3的一端上,如圖表7所示,其他所有連線按圖表7連接即可。 (3)把單片機的P2.0端口接數碼管的位選3,P2.1端口接數碼管的位選2,P2.2端口接數碼管的位選1,P2.3端口接數碼管的位選4。 (4).電源可用外接電源(用手機充電器可做電源),但必須申明電源小于+5V當然也不能太小 3.9 系統調試與分析 在系統制作和調試過程中遇到了不少問題,下面是具體問題與解決方法。 檢查之后發現原來是4個8550三極管管腳接錯,改正之后該問題即解決了。 ②4個數碼管亮度不一樣 8550管腳改正過后,顯示不一樣了,但4個數碼管亮度不一樣。當某一個數碼管顯示的字段較少,比如“1”時,亮度較強,但是當顯示的字段較多比如“8”時,亮度較暗。分析其原因是:共陰數碼管限流電阻用在控制位選的共陰極的輸入端,這樣當顯示“1”時,電流相對集中,顯示“8”字段較多,電流分配后較小,因此“1”顯示時比顯示“8”時亮。 解決方法:減小這里的限流電阻,使其流入數碼管的電流變的很大,這樣在較大電流時,即使字段多的電流較小,也比原來大了。這樣就減小了差距,雖然還是有差距但已不太明顯。 3.10 元件清單及程序代碼 元件清單: 單片機AT89C52:1個 40引腳底座:1個 DS18B20:1個 蜂鳴器:1個 三極管:8050 5個;8550 1個 電阻:1k 6個;10K 1個 電容:極性電容10uf 1個;瓷片電容10pf 2個 按鍵:3個 晶振:1個 四位共陽數碼管:1個 程序代碼: - #include
- #define uchar unsigned char
- #define uint unsigned int
- sbit d1=P2^2;
- sbit d2=P2^1;
- sbit d3=P2^0;
- sbit d4=P2^3;
- sbit key1=P3^0;
- sbit key2=P3^1;
- sbit key3=P3^2;
- sbit beep=P3^3;
- sbit DS=P1^2;
- sbit ACC_7=ACC^7;
- uint count=1000,alarm=300;
- uchar shu;
- uchar shi,fen,ri,yue,nian,xq,miao,ss;
- uint temp; // 溫度變量
- uchar flag;
- uchar code tab[]=
- {0xc0,0xf9,0xa4,0xb0,
- 0x99,0x92,0x82,0xf8,
- 0x80,0x90
- };
- uchar code tab1[]=//小數點點亮
- {0x40,0x79,0x24,0x30,
- 0x19,0x12,0x02,0x78,0x00,0x10
- };
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=120;y>0;y--);
- }
- void dsreset()//發復位
- {
- uint i;
- DS=0;
- i=103;
- while(i>0)i--;
- DS=1;
- i=4;
- while(i>0)i--;
- }
- uchar tmpread() //讀取一字節
- {
- uchar j,k,dat;
- uint i;
- for(j=1;j<=8;j++)
- {
- DS=0;i++; //延時
- DS=1;i++;i++;
- k=DS;
- i=8;while(i>0)i--;
- dat=(k<<7)|(dat>>1);//讀出的數據最低位在最前面存一個字節在DAT里
- }
- return(dat);
- }
- void tmpwritebyte(uchar dat) //寫一個字節
- {
- uint i;
- uchar j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb) //寫 1
- {
- DS=0;
- i++;i++;
- DS=1;
- i=8;while(i>0)i--;
- }
- else
- {
- DS=0; //寫 0
- i=8;while(i>0)i--;
- DS=1;
- i++;i++;
- }
- }
- }
- void tmpchange() //DS18B20溫度變換
- {
- dsreset();
- delay(1);
- tmpwritebyte(0xcc); //跳過讀取內存rom
- tmpwritebyte(0x44); //開始轉換
- }
- uint tmp() //讀取溫度
- {
- float tt;
- uchar a,b;
- dsreset();
- delay(1);
- tmpwritebyte(0xcc);
- tmpwritebyte(0xbe);
- a=tmpread(); //a為低字節8位
- b=tmpread(); //b為高字節8位
- temp=b; //temp為溫度值UINT 16bit
- temp<<=8; //兩個字節組合到一起
- temp=temp|a;
- if(b>127)
- {
- flag=1;
- ss=flag;
- temp=~temp+1;
- }
- tt=temp*0.0625; // temp/16 則是溫度的真實值tt.7位整數,4位小數
- temp=tt*10+0.5; // 擴大十倍取出了第一位小數
- return(temp);
- }
- void displayTemp(uint temp) //顯示溫度程序
- {
- uchar ge,shi,bai,qian,ser;
- d1=0;
- d1=0;
- d3=0;
- d4=0;
- dsreset();
- ser=temp/10; //分離出三位要顯示的數字
- SBUF=ser;
- qian=temp/1000;
- bai=temp/100%10; // 百位數字
- shi=temp/10%10; // 十位數字
- ge=temp%10; // 個位數字
- if(flag==1)
- {
- flag=0;
- P0=0xbf;
- d1=1;
- delay(2);
- d1=0;
- }
- if(qian!=0)
- {
- P0=tab[qian];
- d1=1;
- delay(2);
- d1=0;
- }
- else
- {
- P0=0xff;
- d1=1;
- delay(2);
- d1=0;
- }
- if(temp>99)
- {
- P0=tab[bai];
- d2=1;
- delay(2);
- d2=0;
- }
- P0=tab1[shi];
- d3=1;
- delay(2);
- d3=0;
- P0=tab[ge];
- d4=1;
- delay(2);
- d4=0;
- }
- uint keyscan()
- {
- if(key1==0)
- {
- delay(5);
- if(key1==0)
- {
- while(!key1);
- shu++;
- }
-
-
- }
- if(key2==0)
- {
- delay(5);
- if(key2==0)
- {
- while(!key2);
- count=count+10;
- if(shu==2)
- {
- alarm+=10;
- }
-
- }
- }
- if(key3==0)
- {
- delay(5);
- if(key3==0)
- {
- while(!key3);
- count=count-10;
- if(shu==2)
- {
- alarm-=10;
- }
- }
- }
- return(count);
-
- }
-
- void main()
- {
- beep=0;
- delay(10);
- while( 1 )
- {
- tmpchange();
- if(shu==0)
- {
- displayTemp(tmp( ));
- }
- keyscan();
- if(shu==1)
- {
- displayTemp(count);
- }
- if(shu==2)
- {
- displayTemp(alarm);
- }
- if(shu==3)
- {
- shu=0;
- }
- if(temp>count||(temp<alarm))
- {
- beep=0;
-
- }
- else
- beep=1;
-
- }
- }
-
-
復制代碼
|