本設(shè)計(jì)是基于51單片機(jī)多路溫度檢測(cè)proteus仿真_ds18b20(仿真+程序+原理圖)
仿真圖proteus 7.8
程序編譯器:keil 4/keil 5
編程語(yǔ)言:C語(yǔ)言
設(shè)計(jì)編號(hào):C0042
功能說明:
通過對(duì)多路DS18B20溫度傳感器的數(shù)據(jù)采集,實(shí)現(xiàn)8路/4路溫度采集并將數(shù)值顯示在LCD顯示屏上;
通過按鍵設(shè)置溫度報(bào)警值,逐個(gè)顯示傳感器的溫度,當(dāng)lcd顯示溫度超過設(shè)定值時(shí),系統(tǒng)聲光報(bào)警。
資料下載鏈接(可點(diǎn)擊)
8路仿真圖(提供源文件):
主要由51單片機(jī)最小系統(tǒng)和溫度傳感器,LCD1602顯示屏和按鍵組成。可以設(shè)置檢測(cè)溫度閾值,到了閾值會(huì)觸發(fā)蜂鳴器報(bào)警。
軟件工程文件
KEIL工程文件,代碼有注釋方便理解
main函數(shù)
void main (void)
{
unsigned char i=0,t=0;
delay_nms(50);
IT0=0;
EX0=1;
EA=1;
search_rom();//搜索ROM并且存儲(chǔ),把18B20的每一個(gè)ROM讀取出來(lái),方便下次調(diào)用
reset();
while(1)
{
if(keyflag==0)
{
for(i=0;i<num;i++) //每一個(gè) ds18b20 循環(huán)顯示
{
if(keyflag==1) break;
read_temp(i); //讀編號(hào) i 的ds18b20 的溫度
if(keyflag==1) break;
temp_convert(); //調(diào)用溫度轉(zhuǎn)換
if(keyflag==1) break;
if(tempalarm>alarm)//報(bào)警判斷
{
for(t=0;t<3;t++)
{
buzzer=0;//打開報(bào)警蜂鳴器
led=0; //打開報(bào)警指示燈
delay_nms(100);
buzzer=1;//關(guān)閉報(bào)警蜂鳴器
led=1; //關(guān)閉報(bào)警指示燈
delay_nms(100);
}
}
display_ds18b20(i);//顯示 編號(hào) i 的溫度
}
}
else//設(shè)置按鍵按下 進(jìn)行按鍵掃描動(dòng)作
{
display_alarm(alarm);
keyflag=0;
while(1)
{
if(keyenter==0&&keyflag==0)//進(jìn)入設(shè)置以后,再按設(shè)置按鍵,就退出設(shè)置,重新顯示每一個(gè)通道溫度
{
delay_nms(200);
if(keyenter==0)
{
while(keyenter==0);
lcdinit();
display_alarm_normal(alarm);//顯示報(bào)警溫度
break;//退出按鍵掃描
}
}
if(keyup==0)//
{
delay_nms(200);
if(keyup==0&&alarm<125)
{
alarm++;//報(bào)警溫度加1
}
display_alarm(alarm);
}
if(keydown==0&&alarm>-55)//
{
delay_nms(200);
if(keydown==0)
{
alarm--;//報(bào)警溫度減1
}
display_alarm(alarm);
}
delay_nms(50);
}
EX0=1;
}
}//while(1)結(jié)束
}
其他子函數(shù)
void read_temp(unsigned char num_data)//讀取溫度 子程序 參數(shù)表示讀第幾個(gè)傳感器
{
unsigned char f;
reset();
write_byte(0xcc);//發(fā)送跳過ROM號(hào)命令
write_byte(0x44);//發(fā)送溫度轉(zhuǎn)換命令
delay_nms(2000);
reset();
write_byte(0x55);//發(fā)送匹配ROM號(hào)命令
for(f=0;f<8;f++) //8字節(jié)ROM號(hào)
{
write_byte(ID[num_data][f]);//發(fā)匹配ROM
}
delay_nus(100);
write_byte(0xbe);//讀寄存器命令
delay_nus(100);
temp_l=read_byte();
temp_h=read_byte();
}
void temp_convert(void)//溫度轉(zhuǎn)換
{
negetiveflag=0;
negetiveflag=temp_h&0x80;
if(negetiveflag)
{
negetiveflag=1;
temp_h=~temp_h;
if(temp_l==0)
{
temp_h++; //若低8位全為0且溫度為負(fù),取補(bǔ)時(shí)就要向高位進(jìn)1
}
temp_l=~temp_l+1;
}
temp_h<<=4;
temp_l>>=4;
temp_over=temp_h|temp_l;
tempalarm=temp_over;
if(negetiveflag==1)
{
tempalarm=tempalarm*(-1);
}
}
/*******************顯示***************************/
void search_cartoon(void)//搜索ROM動(dòng)畫
{
lcdinit();
LCD_write_com(0x80);//液晶第一行地址
for(i=0;i<16;i++)
{
LCD_write_data(lcd0[i]);
}
LCD_write_com(0xc0);//液晶第二行地址
for(i=0;i<16;i++)
{
LCD_write_data(0xff);//顯示類似進(jìn)度條的黑點(diǎn)
delay_nms(num*80);
}
}
void display_alarm_normal(signed char alarm_data)//顯示報(bào)警溫度
{
unsigned int data_b,data_temp,l,datx[6]={0};
data_b=alarm_data;
negetiveflag=0;
LCD_write_com(0x80);
for(l=0;l<6;l++)
{
LCD_write_data(pointinfo[l]);
}
if(alarm_data>=0)
{
data_b=alarm_data/100;//百位//
}
else
{
negetiveflag=1;
alarm_data=alarm_data*(-1);//變成正溫度
}
data_temp=alarm_data%100;//對(duì)100取余,也就是十位數(shù)和個(gè)位數(shù)
datx[0]=data_temp/10;//十位
datx[1]=data_temp%10;//個(gè)位
datx[2]=13;//空格符號(hào)
datx[3]=13;//空格符號(hào)
datx[4]=11;//攝氏度符號(hào)
datx[5]=12;//攝氏度符號(hào)
LCD_write_com(0x88);
if(negetiveflag==1)
{
LCD_write_data(0x2d);//顯示"-" “負(fù)號(hào)”
}
else
{
LCD_write_data(lcd4[data_b]);//如果大于0就顯示百位數(shù),否則百位數(shù)就顯示“負(fù)號(hào)”
}
for(l=0;l<6;l++)//顯示報(bào)警值和攝氏度符號(hào)
{
LCD_write_data(lcd4[datx[l]]);
}
}
void display_total(void) //顯示搜索到的DS18B20傳感器數(shù)目
{
lcdinit();
LCD_write_com(0x80);//第一行地址
for(i=0;i<14;i++)
{
LCD_write_data(lcd1[i]);
}
LCD_write_com(0xc0);//第二行地址
for(i=0;i<13;i++)
{
LCD_write_data(lcd2[i]);
}
LCD_write_data(lcd4[num]);
delay_nms(2000);
lcdinit(); //清屏,準(zhǔn)備顯示溫度
display_alarm_normal(alarm);//顯示報(bào)警溫度
}
void display_ds18b20(i)//顯示編號(hào)為i的DS18B20的溫度//
{
unsigned int data_b,data_temp,l;
data_b=temp_over/100;//百位//
data_temp=temp_over%100;
dat[0]=data_temp/10;//十位//
dat[1]=data_temp%10;//個(gè)位//
dat[2]=13; //空格
dat[3]=13; //空格
dat[4]=11; //攝氏度符號(hào)
dat[5]=12; //攝氏度符號(hào)
LCD_write_com(0xc0);
for(l=0;l<7;l++)
{
LCD_write_data(lcd3[l]);
}
LCD_write_com(0xc4);
LCD_write_data(lcd4[++i]);
LCD_write_com(0xc8);
if(negetiveflag==1)
{
LCD_write_data(0x2d);
}
else
{
LCD_write_data(lcd4[data_b]);
}
for(l=0;l<6;l++)
LCD_write_data(lcd4[dat[l]]);
delay_nms(1000);
}
void display_alarm(signed char alarm_data)//顯示報(bào)警溫度
{
unsigned int data_b,data_temp,l;
data_b=alarm_data;
negetiveflag=0;
if(alarm_data>=0)
{
data_b=alarm_data/100;//百位//
}
else
{
negetiveflag=1;
alarm_data=alarm_data*(-1);//變成正溫度
}
data_temp=alarm_data%100;//對(duì)100取余,也就是十位數(shù)和個(gè)位數(shù)
dat[0]=data_temp/10;//十位
dat[1]=data_temp%10;//個(gè)位
dat[2]=13;//空格符號(hào)
dat[3]=11;//攝氏度符號(hào)
dat[4]=12;//攝氏度符號(hào)
if(keyflag==1)//剛剛進(jìn)入設(shè)置報(bào)警溫度
{
lcdinit();
LCD_write_com(0x80);//第一行地址
for(l=0;l<16;l++)
{
LCD_write_data(setinfo[l]);
}
LCD_write_com(0xc0);//第二行地址
for(l=0;l<8;l++)
{
LCD_write_data(pointinfo[l]);
}
}
LCD_write_com(0xc7);
if(negetiveflag==1)
{
LCD_write_data(0x2d);//顯示"-" “負(fù)號(hào)”
}
else
{
LCD_write_data(lcd4[data_b]);//如果大于0就顯示百位數(shù),否則百位數(shù)就顯示“負(fù)號(hào)”
}
for(l=0;l<5;l++)//顯示報(bào)警值和攝氏度符號(hào)
{
LCD_write_data(lcd4[dat[l]]);
}
}
原理圖(僅供參考)
*資料清單(提供資料清單所有文件):*