本设计是基于51单片机多路温度检测proteus仿真_ds18b20(仿真+程序+原理图)
仿真图proteus 7.8
程序编译器:keil 4/keil 5
编程语言:C语言
设计编号:C0042
功能说明:
通过对多路DS18B20温度传感器的数据采集,实现8路/4路温度采集并将数值显示在LCD显示屏上;
通过按键设置温度报警值,逐个显示传感器的温度,当lcd显示温度超过设定值时,系统声光报警。
资料下载链接(可点击)
8路仿真图(提供源文件):
主要由51单片机最小系统和温度传感器,LCD1602显示屏和按键组成。可以设置检测温度阈值,到了阈值会触发蜂鸣器报警。
软件工程文件
KEIL工程文件,代码有注释方便理解
main函数
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 循环显示
{
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)结束
}
其他子函数
void read_temp(unsigned char num_data)//读取温度 子程序 参数表示读第几个传感器
{
unsigned char f;
reset();
write_byte(0xcc);//发送跳过ROM号命令
write_byte(0x44);//发送温度转换命令
delay_nms(2000);
reset();
write_byte(0x55);//发送匹配ROM号命令
for(f=0;f<8;f++) //8字节ROM号
{
write_byte(ID[num_data][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取余,也就是十位数和个位数
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就显示百位数,否则百位数就显示“负号”
}
for(l=0;l<6;l++)//显示报警值和摄氏度符号
{
LCD_write_data(lcd4[datx[l]]);
}
}
void display_total(void) //显示搜索到的DS18B20传感器数目
{
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取余,也就是十位数和个位数
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就显示百位数,否则百位数就显示“负号”
}
for(l=0;l<5;l++)//显示报警值和摄氏度符号
{
LCD_write_data(lcd4[dat[l]]);
}
}
原理图(仅供参考)
*资料清单(提供资料清单所有文件):*
阅读全文