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