一、系統(tǒng)方案 1、本設(shè)計(jì)采用這51單片機(jī)作為主控器。 2、DS18B20采集溫度值送到液晶1602顯示。 3、按鍵設(shè)置報(bào)警值。 4、溫度控制風(fēng)扇檔位。
1.jpg (4.6 KB, 下載次數(shù): 26)
下載附件
2023-11-23 19:58 上傳
二、硬件設(shè)計(jì) 原理圖如下:
2.jpg (39.76 KB, 下載次數(shù): 40)
下載附件
2023-11-23 19:58 上傳
三、單片機(jī)軟件設(shè)計(jì) 1、首先是系統(tǒng)初始化 /*******************T0初始化********************/ void init_t0() { //TMOD=0x01;//定時(shí)器0工作方式1 TH0=(65536-100)/256;//賦初值定時(shí) TL0=(65536-100)%256;//0.01ms EA=1;//開總中斷 ET0=1;//開定時(shí)器0中斷 TR0=1;//啟動(dòng)定時(shí)器0
SCON = 0X50; //UART方式1;8位UART REN = 1; //允許串行口接收數(shù)據(jù) PCON = 0x00; //SMOD=0;波特率不加倍 TMOD = 0x21; //T1方式2,用于產(chǎn)生波特率 TH1 = 0xFD; //裝初值 TL1 = 0xFD; TR1 = 1; //啟動(dòng)定時(shí)器1 EA = 1; //打開全局中斷控制 ES = 1; //打開串行口中斷
} 2、液晶顯示程序 /******************************************************************* 寫命令 ************************************************************************/ void xiemingling(unsigned char mingling) { en=0; rs=0; rw=0; P0=mingling; delayxms(5); en=1; delayxms(10); en=0; } /******************************************************************* 寫數(shù)據(jù) ************************************************************************/ void xieshuju(unsigned char shuju) { en=0; rs=1; rw=0; P0=shuju; delayxms(5); en=1; delayxms(10); en=0; } /******************************************************************* 液晶初始化 ************************************************************************/ void chushihua() { en=0; xiemingling(0x38);//設(shè)置16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口 delayxms(20); xiemingling(0x0c);//設(shè)置開顯示,不顯示光標(biāo) delayxms(20); xiemingling(0x06);//寫一個(gè)字符后地址指針加1 delayxms(20); xiemingling(0x01);//顯示清零,數(shù)據(jù)指針清零 delayxms(20); xiemingling(0x80);//指定字符顯示的實(shí)際地址,,,顯示位置的確定方法規(guī)定為"80H+地址碼x" delayxms(20); } /***********************lcd1602上顯示這字符函數(shù)************************/ void write_string(uchar hang,uchar add,uchar *p) { if(hang==1) xiemingling(0x80+add); else xiemingling(0x80+0x40+add); while(1) { if(*p == '\0') break; xieshuju(*p); p++; } } /***********************lcd1602上顯示2位十進(jìn)制數(shù)************************/ void write_num2(uchar hang,uchar add,uint date) { if(hang==1) xiemingling(0x80+add); else xiemingling(0x80+0x40+add); xieshuju(0x30+date/10); xieshuju(0x30+date%10); } /***********************lcd1602上顯示1位十進(jìn)制數(shù)************************/ void write_num1(uchar hang,uchar add,uint date) { if(hang==1) xiemingling(0x80+add); else xiemingling(0x80+0x40+add); xieshuju(0x30+date%10); } 3、DS18B20程序 /***************************初始化****************************************/ Init_DS18B20(void) { DQ = 1; //DQ復(fù)位 Delay(8); //稍做延時(shí) DQ = 0; //將DQ拉低 Delay(90); //精確延時(shí) 大于 480us DQ = 1; //拉高總線 Delay(8); presence = DQ; //讀取存在信號(hào) Delay(100); DQ = 1; return(presence); //返回信號(hào),0=presence,1= no presence } /***************************讀一位****************************************/ uchar read_bit(void) { uchar i; DQ = 0; //將DQ 拉低開始讀時(shí)間隙 DQ = 1; // then return high for (i=0; i<3; i++); // 延時(shí)15μs return(DQ); // 返回 DQ 線上的電平值 } /***************************讀一個(gè)字節(jié)****************************************/ uchar ReadOneChar(void) { uchar i = 0; uchar dat = 0;
for (i=0;i<8;i++) { // 讀取字節(jié),每次讀取一個(gè)字節(jié) if(read_bit()) dat|=0x01<<i; // 然后將其左移
Delay(4); } return (dat); } /***************************寫一位****************************************/ void write_bit(uchar bitval) { DQ = 0; // 將DQ 拉低開始寫時(shí)間隙 if(bitval==1) DQ =1; // 如果寫1,DQ 返回高電平 Delay(5); // 在時(shí)間隙內(nèi)保持電平值, DQ = 1; // Delay函數(shù)每次循環(huán)延時(shí)16μs,因此delay(5) = 104μs } /***************************寫一個(gè)字節(jié)****************************************/ void WriteOneChar(uchar dat) { uchar i = 0; uchar temp;
for (i=0; i<8; i++) // 寫入字節(jié), 每次寫入一位 { temp = dat>>i; temp &= 0x01; write_bit(temp); } Delay(5); } /*------------------------------------------------ 單個(gè)DS18B20 讀取溫度 ------------------------------------------------*/ int ReadTemperature() { uchar a; uchar b; Init_DS18B20(); WriteOneChar(0xCC); // 跳過讀序號(hào)列號(hào)的操作 WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換 delayxms(10); Init_DS18B20(); WriteOneChar(0xCC); //跳過讀序號(hào)列號(hào)的操作 WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度 a = ReadOneChar(); //低位 b = ReadOneChar(); //高位 t = b; t <<= 8; t |= a;
if(t < 0) //溫度為負(fù)數(shù) { flag_temp = 1; t -= 1; t = ~t; t = t * 0.0625;//溫度值擴(kuò)大-倍,精確到-位小數(shù) } else { flag_temp = 0; t = t * 0.0625;//溫度值擴(kuò)大-倍,精確到-位小數(shù) } return(t); } 4、核心算法程序 if(number==0) { /*根據(jù)溫度控制檔位*/ if(t<alarm) { dangwei = 0;
PWM1=0; TR0=0; pwm(0); //控制PWM輸出,進(jìn)而控制電機(jī)的速度
} else if(t<alarm+5) { dangwei = 1;
TR0=1; pwm(20); //控制PWM輸出,進(jìn)而控制電機(jī)的速度 } else if(t<alarm+10) { dangwei = 2;
TR0=1; pwm(50); //控制PWM輸出,進(jìn)而控制電機(jī)的速度 } else { dangwei = 3;
TR0=1; pwm(99); //控制PWM輸出,進(jìn)而控制電機(jī)的速度 } 四、 proteus仿真設(shè)計(jì) Proteus軟件是一款應(yīng)用比較廣泛的工具,它可以在沒有硬件平臺(tái)的基礎(chǔ)上通過自身的軟件仿真出硬件平臺(tái)的運(yùn)行情況,這樣就可以通過軟件仿真來驗(yàn)證我們?cè)O(shè)計(jì)的方案有沒有問題,如果有問題,可以重新選擇器件,連接器件,直到達(dá)到我們?cè)O(shè)定的目的,避免我們搭建實(shí)物的時(shí)候,如果當(dāng)初選擇的方案有問題,我們器件都已經(jīng)焊接好了,再去卸載下去,再去焊接新的方案的器件,測試,這樣會(huì)浪費(fèi)人力和物力,也給開發(fā)者帶來一定困惑,Proteus仿真軟件就很好的解決這個(gè)問題,我們?cè)谠O(shè)計(jì)之初,就使用該軟件進(jìn)行模擬仿真,測試,選擇滿足我們?cè)O(shè)計(jì)的最優(yōu)方案。最后根據(jù)測試沒問題的仿真圖紙,焊接實(shí)物,調(diào)試,最終完成本設(shè)計(jì)的作品。
|