|
基于51單片機(jī)和DS18B20的數(shù)字溫度計(jì)設(shè)計(jì)的資料,包括了protues的仿真設(shè)計(jì)和報(bào)告。
目錄
摘要 2
一、 緒論 2
1.1單片機(jī)簡介 2
1.2 DS18B20溫度傳感器簡介 2
1.3基于單片機(jī)和溫度傳感器設(shè)計(jì)數(shù)字溫度計(jì)的發(fā)展現(xiàn)狀 2
1.4選題的意義 3
1.5本數(shù)字溫度計(jì)設(shè)計(jì)的工作 3
二、設(shè)計(jì)方案論證與選擇 4
2.1單片機(jī)具體方案論證與設(shè)計(jì) 4
2.2溫度傳感器具體方案論證與設(shè)計(jì) 4
三、主要芯片與硬件介紹 5
3.1 stc89C51 5
3.2 DS18B20 6
3.3四位一體數(shù)碼管 9
四、 系統(tǒng)電路設(shè)計(jì) 10
4.1單片機(jī)最小系統(tǒng)電路設(shè)計(jì) 10
4.2 DS18B20溫度傳感器電路 11
4.3四位一體數(shù)碼管顯示電路 11
五、 系統(tǒng)的軟件設(shè)計(jì) 11
5.1主程序 12
5.2讀出溫度子程序 12
5.3 溫度轉(zhuǎn)換命令子程序 13
5.4計(jì)算溫度子程序 14
5.5 顯示數(shù)據(jù)刷新子程序 14
5.6按鍵掃描處理子程序 15
六、 溫度數(shù)據(jù)的計(jì)算處理方法 16
七、 仿真調(diào)試及性能分析 17
八、 總結(jié) 17
參考文獻(xiàn) 18
附件一:系統(tǒng)原理圖 18
附件二: 元件清單 19
附件三:程序源代碼 19
單片機(jī)源程序如下:
- # include <reg51.h>
- #define uint unsigned int
- #define uchar unsigned char //宏定義
- #define Disdata P2 //段碼輸出口
- #define discan P0 //掃描口
- sbit p34=P0^0;
- sbit p35=P0^1;
- sbit p36=P0^2;
- sbit dp=P2^7;
- sbit p37=P0^3;
- sbit DQ=P1^0; //定義DS18B20總線I/O
- sbit set=P1^6; //定義選擇報(bào)調(diào)整警溫度上限和下限(1為上限,0為下限)
- /****P1.4和P1.4為調(diào)整溫度報(bào)警增加鍵和減少鍵******/
- sbit SET=P3^2;
- sbit add=P1^4;
- sbit dec=P1^5;
- sbit led_red=P1^2; //超過上限溫度或低于下限溫度,紅燈亮·
- sbit led_green=P1^3; //溫度在正常范圍內(nèi),綠燈亮
- sbit speaker=P3^5; //定義響鈴
- int temp1;
- signed char m; //溫度值全局變量
- bit sign=0; //外部中斷狀態(tài)標(biāo)志
- signed char shangxian=38; //上限報(bào)警溫度,默認(rèn)值為38
- signed char xiaxian=6; //下限報(bào)警溫度,默認(rèn)值為5
- uchar code LEDData[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; /*****延時(shí)子程序*****/
- uchar code dis_7[12]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF,0xBF};
- /*共陽LED段碼表 "0","1","2","3","4","5","7","8","9","不亮","-"*/
- uchar code scan_con[4]={0xf1,0xF2,0xF4,0xF8}; //列掃描控制字
- uchar data temp_data[2]={0x00,0x00}; //讀出溫度暫存
- uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //顯示單元數(shù)據(jù),共4個(gè)數(shù)據(jù),其中一個(gè)作為運(yùn)算暫存用
- void Delay(uint i)
- {
- while( i-- );
- }
- /******************顯示掃描函數(shù)**********************/
- void scan()
- {
- char k;
- for(k=0;k<4;k++) //循環(huán)掃描4個(gè)口,并顯示
- {
- Disdata=dis_7[display[k]];
- if(k==1){dp=0;}
- discan=scan_con[k];
- Delay(65);
- discan=0xff;
- }
-
- }
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ=1; Delay(8); //稍做延時(shí)
- DQ=0; //單片機(jī)將DQ拉低
- Delay(80); //精確延時(shí),大于480us
- DQ=1; //拉高總線
- Delay(14);
- x=DQ; //稍做延時(shí)后,如果x=0則初始化成功,x=1則初始化失敗
- Delay(20);
- }
- /***************18b20讀一字節(jié)函數(shù)****************/
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat=0;
- for (i=8;i>0;i--)
- {
- DQ=0; // 給脈沖信號(hào)
- dat>>=1;
- DQ=1; // 給脈沖信號(hào)
- if(DQ) dat|=0x80;
- Delay(4);
- }
- return(dat); }
- /***************18b20寫命令函數(shù)**************/
- void WriteOneChar(unsigned char dat)
- { unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ=0;
- DQ=dat&0x01;
- Delay(5);
- DQ=1; dat>>=1;
- }
- }
- void Tmpchange(void) //發(fā)送溫度轉(zhuǎn)換命令
- {
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號(hào)列號(hào)的操作
- WriteOneChar(0x44); //啟動(dòng)溫度轉(zhuǎn)
- }
- unsigned int ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Tmpchange();
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號(hào)列號(hào)的操作
- WriteOneChar(0xBE); //讀取溫度寄存器
- a=ReadOneChar(); //讀低8位
- b=ReadOneChar(); //讀高8位
- t=b; t<<=8; t=t|a; tt=t*0.0625; t= tt*100+0.5; //放大10倍輸出并四舍五入
- return(t); } /*****顯示開機(jī)初始化等待畫面*****/
- Disp_init() {
- P2 = 0x80; //顯示-
- p34=1;p35=0;p36=0;p37=0;
- Delay(200);
- P2 = 0x80;
- p34=0;p35=1;p36=0;p37=0;
- Delay(200);
- P2 = 0x80;
- p34=0;p35=0;p36=1;p37=0;
- Delay(200);
- P2 = 0x80;
- p34=0;p35=0;p36=0;p37=1;
- Delay(200);
- P2 = 0x80;
- }
- /******************溫度數(shù)據(jù)處理函數(shù)****************/
- work_temp() //顯示溫度
- { uint a,b,c,d,e;
- e=ReadTemperature(); //獲取溫度值
- a=e/10000; //計(jì)算得到百位數(shù)
- b=e/1000; //計(jì)算得到十位數(shù)
- c=e/100-b*10; //計(jì)算得到個(gè)位數(shù)字
- d=(e%100)/10; //計(jì)算得到小數(shù)點(diǎn)后一位
- m=e/100;
- p34=0;p35=0;p36=0;p37=0;
- P2 =LEDData[d]; //顯示小數(shù)點(diǎn)后一位
- p34=1;p35=0;p36=0;p37=0;
- Delay(300); p34=0;p35=0;p36=0;p37=0;
- P2 =LEDData[c]; //顯示個(gè)位
- dp=0;p34=0;p35=1;p36=0;p37=0;
- Delay(300);
- p34=0;p35=0;p36=0;p37=0;
- P2 =LEDData[b]; //顯示十位
- p34=0;p35=0;p36=1;p37=0;
- Delay(300); p34=0;p35=0;p36=0;p37=0;
- P2 =LEDData[a]; //顯示百位
- if(LEDData[a]==0){P0=0x0A;
- if(LEDData[b]==0){P0=0x0A;}} //最高位為0時(shí)都不顯示
- p34=0;p35=0;p36=0;p37=1;
- Delay(300); p34=0;p35=0;p36=0;p37=0; //關(guān)閉顯示
- }
- disptiaozheng()
- {
- uchar f,g,j,k;
- f=shangxian/10;
- g=shangxian%10;
- j=xiaxian/10;
- k=xiaxian%10;
- p34=0;p35=0;p36=0;p37=0;
- P2 =dis_7[display[2]]; //顯示0
- p34=0;p35=1;p36=0;p37=0;
- Delay(200);
- p34=0;p35=0;p36=0;p37=0;
- P2 =0xc0; //顯示0
- p34=0;p35=0;p36=1;p37=0;
- Delay(200);
- p34=0;p35=0;p36=0;p37=0;
- if(SET==1)
- {
- P2 =LEDData[g];
- dp=0; //顯示上限溫度個(gè)位
- }
- else
- {
- P2 =LEDData[k];
- dp=0;
- }
- p34=0;p35=0;p36=1;p37=0;
- Delay(200); p34=0;p35=0;p36=0;p37=0;
- if(SET==1) P2 =LEDData[f]; //顯示上限溫度十位
- else { if(f==0) P0=0x00; //不顯示下限溫度十位
- else P2 =LEDData[j]; //顯示下限溫度十位
- } p34=0;p35=0;p36=0;p37=1;
- Delay(200);
- p34=0;p35=0;p36=0;p37=0; //關(guān)閉顯示
- Delay(20);
- }
- /******************設(shè)置溫度顯示轉(zhuǎn)換******************/
- exchange(int horl)
- {
- int n=0;
- if(horl>128)
- {
- horl=256-horl;n=1; //負(fù)溫度求補(bǔ)碼
- }
- display[3]=horl/100; //百位數(shù)據(jù)暫存
- display[3]=display[3]&0x0f;
- display[2]=horl%100/10; //十位數(shù)據(jù)暫存
- display[1]=horl%10; //個(gè)位數(shù)據(jù)暫存
- display[0]=0;
- if(!display[3]){display[3]=0x0A;
- if(!display[2]){display[2]=0x0A;}} //最高位為0時(shí)都不顯示
- if(n){display[3]=0x0B;} //負(fù)溫度時(shí)最高位顯示為“-”
-
- p34=0;p35=0;p36=0;p37=0;
- P2 =0xc6; //顯示0
- p34=1;p35=0;p36=0;p37=0;
- Delay(200);
- p34=0;p35=0;p36=0;p37=0;
- P2 =dis_7[display[1]];dp=0; //顯示個(gè)位
- p34=0;p35=1;p36=0;p37=0;
- Delay(200);
- p34=0;p35=0;p36=0;p37=0;
- P2=dis_7[display[2]];
- p34=0;p35=0;p36=1;p37=0;
- Delay(200);
- p34=0;p35=0;p36=0;p37=0;
- P2=dis_7[display[3]];
- p34=0;p35=0;p36=0;p37=1;
- Delay(200);
- p34=0;p35=0;p36=0;p37=0; //關(guān)閉顯示
- Delay(20);
- }
- /******************蜂鳴器報(bào)警程序*********************/
- void beep()
- {
- if(m>=shangxian &&m<129|| m<xiaxian) //溫度不在范圍內(nèi)報(bào)警
- { speaker=~speaker;
- led_red=0; //紅燈亮
- led_green=1;} //綠燈滅
- else
- {
- speaker=0;
- led_red=1;
- led_green=0;} //綠燈亮
- }
- /******************按鍵查詢程序**********************/
- void keyscan()
- {
- if(set==0) //判斷設(shè)置溫度鍵是否按下
- {
- while(1)
- {
- Delay(500); //消抖
- if(set==0)
- {
- temp1++;
- while(!set)
- scan();
- }
- if(temp1==1) //1時(shí),顯示溫度上限
- {
- exchange(shangxian); //顯示溫度上限值
- scan();
- if(add==0) //判斷增加鍵是否按下
- {
- while(!add)
- scan();
- shangxian+=1;
- }
- if(dec==0) //判斷減少鍵是否按下
- {
- while(!dec)
- scan();
- shangxian-=1;
- }
- }
- if(temp1==2) //2時(shí),顯示溫度下限
- {
- exchange(xiaxian); //顯示溫度下限值
- scan();
- if(add==0) //判斷增加鍵是否按下
- {
- while(!add)
- scan();
- xiaxian+=1;
- }
- if(dec==0) //判斷減少鍵是否按下
- {
- while(!dec)
- scan();
- xiaxian-=1;
- }
- scan();
- }
- if(temp1==3) //3時(shí)返回,顯示當(dāng)前溫度
- {
- temp1=0;
- break;
- }
- }
- }
- }
- void int0(void) interrupt 0
- { EX0=0; //關(guān)外部中斷0
- sign=1;
- if(SET==1) shangxian++; else xiaxian++;
- Delay(500); EX0=1;
- } /*****外部中斷1服務(wù)程序*****/
- void int1(void) interrupt 2
- {
- EX1=0; //關(guān)外部中斷0
- sign=1; if(SET==1) shangxian--;
- else xiaxian--; Delay(500); EX1=1;
- } /*****主函數(shù)*****/
- void main(void)
- {
- uint h;
- IT0=1;
- IT1=1;
- EX0=1;
- EX1=1;
- EA=1;
- for(h=0;h<4;h++)
- {
- display[h]=8; //開機(jī)顯示8888
- }
- ReadTemperature();
- speaker=0;
- for(h=0;h<500;h++)
- {
- scan(); //開機(jī)顯示“8888”2s
- }
- while(1)
- {
- if(temp1==0)
- {
- work_temp();
- beep(); //檢測是否超過上限或低于下限
- keyscan(); //按鍵檢測
- }
- else
- {
- keyscan(); //按鍵檢測
- }
- }
- }
-
復(fù)制代碼
全部資料51hei下載地址:
數(shù)字溫度計(jì)設(shè)計(jì).zip
(633.93 KB, 下載次數(shù): 222)
2019-1-2 11:25 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|