? ?本設(shè)計采用AT89C51單片機(jī)為控制芯片,硬件上用dsb18202做溫度采集(有需要也可以采用dht11溫濕度模塊)直流電機(jī)作為降溫風(fēng)扇,用戶可通過按鍵來控制轉(zhuǎn)速的大小,用繼電器來控制電阻絲提高溫度。用lcd1602顯示屏來顯示環(huán)境溫度并且通過按鍵來設(shè)置模式與最高溫和最低溫。
實驗現(xiàn)象:
?? ?首先它能顯示環(huán)境的溫度并能設(shè)置上下限閥值,這是最基本的功能,系統(tǒng)上電的時候顯示的是當(dāng)前環(huán)境溫度和設(shè)定的溫度閥值,我們可以通過按鍵來修改溫度上下限閥值。我們看,按下這個K1鍵會進(jìn)入溫度閥值設(shè)置?界面,每按一下,切換一次閥值設(shè)置(上下閥值)界面,按第3次時,會自動回到主界面,如此循環(huán)。
?? ?在進(jìn)入溫度閥值設(shè)計界面時,可以通過K2、K3鍵對閥值進(jìn)行加減,這里我們只對溫度整數(shù)部分進(jìn)行設(shè)置,小數(shù)部分我們就不需要了,將設(shè)置好的上下限閥值保存到AT24C02(EEPROM)內(nèi),當(dāng)下一次開啟系統(tǒng)時只需從AT24C02內(nèi)讀取保存的閥值數(shù)據(jù),而不需要重復(fù)設(shè)置上下限閥值。這樣的話,我們用3個按鍵就實現(xiàn)了溫度上下限閥值的設(shè)定,這是溫度檢測控制系統(tǒng)基本的功能。假如我們把溫度上限設(shè)置為32°C,下限設(shè)置為30°C。
?? ?另外還有恒定溫度的功能。當(dāng)設(shè)定好上下限閥值時,系統(tǒng)即會把當(dāng)前的溫度與設(shè)定的上下限閥值對比,如果高于上限溫度,開啟散熱進(jìn)行降溫,同時報警;如果低于下限溫度,開啟加熱,同時報警;如果當(dāng)前溫度處于下限和上限溫度之間時,關(guān)閉散熱、加熱及報警。從而可將溫度控制在閥值的范圍內(nèi)。
仿真圖展示:
溫度高于設(shè)定值,風(fēng)扇反轉(zhuǎn),警報開啟
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?溫度低于設(shè)定值,加溫開啟并發(fā)出警報
部分功能視頻展示:
視頻地址:基于c51單片機(jī)的畢業(yè)設(shè)計——智能溫度控制_嗶哩嗶哩_bilibili
https://www.bilibili.com/video/BV1yU4y177pp/
核心代碼展示:
ds18b20的測溫原理
DS18B20的讀寫時序和測溫原理與DS1820相同,只是得到的溫度值的位數(shù)因分辨率不同而不同,且溫度轉(zhuǎn)換時的延時時間由2s減為750ms。 DS18B20測溫原理如圖3所示。圖中低溫度系數(shù)晶振的振蕩頻率受溫度影響很小,用于產(chǎn)生固定頻率的脈沖信號發(fā)送給計數(shù)器1。高溫度系數(shù)晶振隨溫度變化其振蕩頻率明顯改變,所產(chǎn)生的信號作為計數(shù)器2的脈沖輸入。計數(shù)器1和溫度寄存器被預(yù)置在-55℃所對應(yīng)的一個基數(shù)值。計數(shù)器1對低溫度系數(shù)晶振產(chǎn)生的脈沖信號進(jìn)行減法計數(shù),當(dāng)計數(shù)器1的預(yù)置值減到0時,溫度寄存器的值將加1,計數(shù)器1的預(yù)置將重新被裝入,計數(shù)器1重新開始對低溫度系數(shù)晶振產(chǎn)生的脈沖信號進(jìn)行計數(shù),如此循環(huán)直到計數(shù)器2計數(shù)到0時,停止溫度寄存器值的累加,此時溫度寄存器中的數(shù)值即為所測溫度。斜率累加器用于補(bǔ)償和修正測溫過程中的非線性,其輸出用于修正計數(shù)器1的預(yù)置值。
?
?
lcd1602工作原理
點陣圖形式液晶由M×N個顯示單元組成,假設(shè)LCD顯示屏有64行,每行有128列,每8列對應(yīng)1字節(jié)的8位,即每行由16字節(jié),共16×8=128個點組成。顯示屏上64×16個顯示單元與顯示RAM區(qū)的1024字節(jié)相對應(yīng),每一字節(jié)的內(nèi)容與顯示屏上相應(yīng)位置的亮暗對應(yīng)。例如顯示屏第一行的亮暗由RAM區(qū)的000H~00FH的16字節(jié)的內(nèi)容決定,當(dāng)(000H)=FFH時,屏幕左上角顯示一條短亮線,長度為8個點;當(dāng)(3FFH)=FFH時,屏幕右下角顯示一條短亮線;當(dāng)(000H)=FFH,(001H)=00H,(002H)=00H…,(00EH)=00H,(00FH)=00H時,在屏幕的頂部顯示一條由8條亮線和8條暗線組成的虛線。這就是LCD顯示的基本原理。
?
?
?
?ds18b20初始化
#include "temp.h"
void Delay1ms(unsigned int y)
{
unsigned int x;
for(y;y>0;y--)
for(x=110;x>0;x--);
}
unsigned char Ds18b20Init()//初始化
{
unsigned int i;
DSPORT=0; //將總線拉低480us~960us
i=70;
while(i--);//延時642us
DSPORT=1; //然后拉高總線,如果DS18B20做出反應(yīng)會將在15us~60us后總線拉低
i=0;
while(DSPORT) //等待DS18B20拉低總線
{
i++;
if(i>5000)//等待>5MS
return 0;//初始化失敗
}
return 1;//初始化成功
}
void Ds18b20WriteByte(unsigned char dat)//寫入一字節(jié)
{
unsigned int i,j;
for(j=0;j<8;j++)
{
DSPORT=0; //每寫入一位數(shù)據(jù)之前先把總線拉低1us
i++;
DSPORT=dat&0x01; //然后寫入一個數(shù)據(jù),從最低位開始
i=6;
while(i--); //延時68us,持續(xù)時間最少60us
DSPORT=1; //然后釋放總線,至少1us給總線恢復(fù)時間才能接著寫入第二個數(shù)值
dat>>=1;
}
}
unsigned char Ds18b20ReadByte()//讀取字節(jié)
{
unsigned char byte,bi;
unsigned int i,j;
for(j=8;j>0;j--)
{
DSPORT=0;//先將總線拉低1us
i++;
DSPORT=1;//然后釋放總線
i++;
i++;//延時6us等待數(shù)據(jù)穩(wěn)定
bi=DSPORT; //讀取數(shù)據(jù),從最低位開始讀取
/*將byte左移一位,然后與上右移7位后的bi,注意移動之后移掉那位補(bǔ)0。*/
byte=(byte>>1)|(bi<<7);
i=4; //讀取完之后等待48us再接著讀取下一個數(shù)
while(i--);
}
return byte;
}
void Ds18b20ChangTemp()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳過ROM操作命令
Ds18b20WriteByte(0x44); //溫度轉(zhuǎn)換命令
// Delay1ms(100); //等待轉(zhuǎn)換成功,而如果你是一直刷著的話,就不用這個延時了
}
void Ds18b20ReadTempCom()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳過ROM操作命令
Ds18b20WriteByte(0xbe); //發(fā)送讀取溫度命令
}
short Ds18b20ReadTemp()
{
unsigned char temp=0;
unsigned char tmh,tml;
short tem;
Ds18b20ChangTemp(); //先寫入轉(zhuǎn)換命令
Ds18b20ReadTempCom(); //然后等待轉(zhuǎn)換完后發(fā)送讀取溫度命令
tml=Ds18b20ReadByte(); //讀取溫度值共16位,先讀低字節(jié)
tmh=Ds18b20ReadByte(); //再讀高字節(jié)
if(tmh>7)
{
tmh=~tmh;
tml=~tml;
temp=0;//溫度為負(fù)
}
else
{
temp=1;//溫度為正
}
tem=tmh; //獲得高八位
tem<<=8;
tem|=tml;//獲得底八位
tem=(double)tem*0.625;//轉(zhuǎn)換 放大10倍 精度0.1
if(temp)
return tem; //返回溫度值
else
return -tem;
}
lcd1602初始化
#include "lcd.h"
void Lcd1602_Delay1ms(uint c) //誤差 0us
{
uchar a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
#ifndef LCD1602_4PINS //當(dāng)沒有定義這個LCD1602_4PINS時
void LCD_WriteCmd(uchar com) //寫入命令
{
LCD1602_E = 0; //使能
LCD1602_RS = 0; //選擇發(fā)送命令
LCD1602_RW = 0; //選擇寫入
LCD1602_DATAPINS = com; //放入命令
Lcd1602_Delay1ms(1); //等待數(shù)據(jù)穩(wěn)定
LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5); //保持時間
LCD1602_E = 0;
}
#else
void LCD_WriteCmd(uchar com) //寫入命令
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 0; //選擇寫入命令
LCD1602_RW = 0; //選擇寫入
LCD1602_DATAPINS = com; //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
// Lcd1602_Delay1ms(1);
LCD1602_DATAPINS = com << 4; //發(fā)送低四位
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
#endif
#ifndef LCD1602_4PINS
void LCD_WriteData(uchar dat) //寫入數(shù)據(jù)
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //選擇輸入數(shù)據(jù)
LCD1602_RW = 0; //選擇寫入
LCD1602_DATAPINS = dat; //寫入數(shù)據(jù)
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5); //保持時間
LCD1602_E = 0;
}
#else
void LCD_WriteData(uchar dat) //寫入數(shù)據(jù)
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //選擇寫入數(shù)據(jù)
LCD1602_RW = 0; //選擇寫入
LCD1602_DATAPINS = dat; //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
LCD1602_DATAPINS = dat << 4; //寫入低四位
Lcd1602_Delay1ms(1);
LCD1602_E = 1; //寫入時序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
#endif
#ifndef LCD1602_4PINS
void LcdInit() //LCD初始化子程序
{
LCD_WriteCmd(0x38); //開顯示
LCD_WriteCmd(0x0c); //開顯示不顯示光標(biāo)
LCD_WriteCmd(0x06); //寫一個指針加1
LCD_WriteCmd(0x01); //清屏
LCD_WriteCmd(0x80); //設(shè)置數(shù)據(jù)指針起點
}
#else
void LCD_Init() //LCD初始化子程序
{
LCD_WriteCmd(0x32); //將8位總線轉(zhuǎn)為4位總線
LCD_WriteCmd(0x28); //在四位線下的初始化
LCD_WriteCmd(0x0c); //開顯示不顯示光標(biāo)
LCD_WriteCmd(0x06); //寫一個指針加1
LCD_WriteCmd(0x01); //清屏
LCD_WriteCmd(0x80); //設(shè)置數(shù)據(jù)指針起點
}
#endif
void LCD_Clear()
{
LCD_WriteCmd(0x01);
LCD_WriteCmd(0x80);
}
//在任何位置顯示字符串
void LCD_Dispstring(u8 x,u8 line,u8 *p)
{
char i=0;
if(line<1) //第一行顯示
{
while(*p!='\0')
{
if(i<16-x)
{
LCD_WriteCmd(0x80+i+x);
}
else
{
LCD_WriteCmd(0x40+0x80+i+x-16);
}
LCD_WriteData(*p);
p++;
i++;
}
}
else //第2行顯示
{
while(*p!='\0')
{
if(i<16-x)
{
LCD_WriteCmd(0x80+0x40+i+x);
}
else
{
LCD_WriteCmd(0x80+i+x-16);
}
LCD_WriteData(*p);
p++;
i++;
}
}
}
lcd屏顯示ds18b20檢測溫度
?
void Temp_DataPros()
{
short temp;
u8 temp_buf[5];
temp=Ds18b20ReadTemp();
temp_val=temp;
if(temp<0)
{
temp=-temp;
LCD_Dispstring(2+5,0,"-");
}
else
{
LCD_Dispstring(2+5,0," ");
}
temp_buf[0]=temp/100+0x30;
temp_buf[1]=temp%100/10+0x30;
temp_buf[2]='.';
temp_buf[3]=temp%100%10+0x30;
temp_buf[4]='\0';
LCD_Dispstring(2+6,0,temp_buf); //顯示檢測的溫度xx.x
temp_buf[0]=set_temph/10+0x30;
temp_buf[1]=set_temph%10+0x30;
temp_buf[2]='\0';
LCD_Dispstring(5,1,temp_buf); //顯示設(shè)定的溫度上限值xx
temp_buf[0]=set_templ/10+0x30;
temp_buf[1]=set_templ%10+0x30;
temp_buf[2]='\0';
LCD_Dispstring(14,1,temp_buf); //顯示設(shè)定的溫度下限值xx
}
?
按鍵模式選擇并調(diào)節(jié)文章來源:http://www.zghlxwxcb.cn/news/detail-512826.html
u8 KEY_Scan(u8 mode)
{
static u8 key=1;
if(key&&(k1==0||k2==0||k3==0))
{
delay(1000); //消抖
key=0;
if(k3==0)
{
return K1_MODE;
}
else if(k1==0)
{
return K2_ADD;
}
else if(k2==0)
{
return K3_DEC;
}
}
else if(k1==1&&k2==1&&k3==1)
{
key=1;
}
if(mode)
{
key=1;
}
return 0;
}
void KEY_Pros()
{
u8 key;
u8 temph_buf[3];
key=KEY_Scan(0);
if(key==K1_MODE) //模式選擇
{
mode++;
LCD_Clear();
if(mode==1)
{
LCD_Dispstring(0,1,"SETH: C");
LCD_Dispstring(2,0,"N-TEM: C");
}
else if(mode==2)
{
LCD_Dispstring(0,1,"SETL: C");
LCD_Dispstring(2,0,"N-TEM: C");
}
else
{
mode=0;
LCD_Dispstring(2,0,"Temp: C");
LCD_Dispstring(0,1,"SETH: ");
LCD_Dispstring(9,1,"SETL: ");
}
}
if(mode==1) //溫度上限設(shè)置
{
switch(key)
{
case K2_ADD: //加
set_temph++;
if(set_temph>=80)set_temph=80;
break;
case K3_DEC: //減
set_temph--;
if(set_temph<=0)set_temph=0;
break;
}
temph_buf[0]=set_temph/10+0x30;
temph_buf[1]=set_temph%10+0x30;
temph_buf[2]='\0';
LCD_Dispstring(9,0,temph_buf);
At24c02Write(0,set_temph);
}
else if(mode==2) //溫度下限設(shè)置
{
switch(key)
{
case K2_ADD: //加
set_templ++;
if(set_templ>=80)set_templ=80;
break;
case K3_DEC: //減
set_templ--;
if(set_templ<=0)set_templ=0;
break;
}
temph_buf[0]=set_templ/10+0x30;
temph_buf[1]=set_templ%10+0x30;
temph_buf[2]='\0';
LCD_Dispstring(5,1,temph_buf);
At24c02Write(2,set_templ);
}
核心代碼及仿真圖展示完畢,獲取完整源碼下載地址:https://download.csdn.net/download/weixin_51322363/21106377文章來源地址http://www.zghlxwxcb.cn/news/detail-512826.html
到了這里,關(guān)于基于c51單片機(jī)的畢業(yè)設(shè)計——智能溫度控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!