多路温度检测及报警系统(DS18B20)

与世无争的帅哥 提交于 2020-01-22 00:30:21

整体布图

此温度报警系统具体为3路检测及报警,二路显示。
温度上下限自由设置,但被传感器(ds18b20)限制。报警则为由3盏led灯分别对应各自传感器,一旦超过上下限,则灯长亮。
主要有四个部分构成单片机部分,显示部分,led报警部分,传感器部分
三路温度报警,二路温度显示

单片机及LED报警部分

采用80c51 时钟频率为12MHz

以下为具体配置

传感器ds18b20 部分


以下为具体配置


显示器LM016L部分


以下为具体配置

代码部分

#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS=P2^4;
sbit RW=P2^1;
sbit EN=P2^2;
sbit DQ=P3^2; 

sbit LED1=P1^0;
sbit LED2=P1^3;
sbit LED3=P1^7;

uchar code str1[]={0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e};
uchar code str2[]={0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9};
uchar code str3[]={0x28,0x32,0xc5,0xb8,0x00,0x00,0x00,0xe0};
uchar code table[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};        
uchar data disdata[5];

uint tvalue;//温度数据储存
uchar tflag;//温度符号位
uint high=600;//最高温
uint low=100;//最低温

/*************************lcd1602初始化**************************/
void delay1ms(uint ms)//1ms延时
{  uint i,j;
   for(i=0;i<ms;i++)
    for(j=0;j<100;j++);
}

void wr_com(uchar com)  //向LCD1602写入指令
{ delay1ms(1);
   RS=0;//指令
   RW=0;//写入
   EN=0;//
   P0=com;
   delay1ms(1);
   EN=1;//允许
   delay1ms(1);
   EN=0;
}

void wr_dat(uchar dat)//向LCD1602写入数据
{ delay1ms(1);;
   RS=1;//数据
   RW=0;//写入
   EN=0;
   P0=dat;
   delay1ms(1);
   EN=1;//允许
   delay1ms(1);
   EN=0;
}

void wr_new()                   //设置显示位置
{
        uchar i;
        wr_com(0x40);
        for(i=0;i<8;i++)
        {
                wr_dat(table[ i]);
        }
}

void lcd_init()//显示字符串函数
{        delay1ms(15);
        wr_com(0x38);delay1ms(5);
        wr_com(0x08);delay1ms(5);
        wr_com(0x01);delay1ms(5);
         wr_com(0x06);delay1ms(5);
        wr_com(0x0c);delay1ms(5);
        wr_new();
        wr_com(0x80);
    wr_dat('A');
        wr_com(0x81);
    wr_dat(':');
          wr_com(0x89);
    wr_dat(0x00);
        wr_com(0x8a);
    wr_dat('C');
        wr_com(0xc9);
    wr_dat(0x00);                       
        wr_com(0xca);
    wr_dat('C');
        wr_com(0xc0);
    wr_dat('B');
        wr_com(0xc1);
    wr_dat(':');
}

/******************************ds18b20部分**************************************/
void delay_18B20(uint i)//延时函数
{
   while(i--);
}

void ds1820rst()/ds18b20
{   uchar x=0;
        DQ = 1;          //DQ拉高
        delay_18B20(4); //延时20us
        DQ = 0;          //DQ拉低
        delay_18B20(100); //延时480us
        DQ = 1;          //拉高
        delay_18B20(40);延时200us
}

uchar ds1820rd()//数据读取
{ uchar i=0;
  uchar dat = 0;
  for (i=0;i<8;i++)
        {   DQ = 0; //拉低
    dat>>=1;
    DQ = 1; //拉高
    if(DQ)
    dat|=0x80;
    delay_18B20(10);
        }
   return(dat);
}

void ds1820wr(uchar dat)//写入数据
{         uchar i=0;
    for (i=0; i<8; i++)
                   { DQ = 0;
              DQ = dat&0x01;
              delay_18B20(10);
              DQ = 1;
              dat>>=1;
                   }
}

void b20_Matchrom(uchar a)         //分别匹配3个ROM
{
        char j;
        ds1820wr(0x55);           //发送匹配ROM序列
        if(a==1)
        {
        for(j=0;j<8;j++)
                ds1820wr(str1[j]);                //发送18B20序列号,先发送低字节
        }
        if(a==2)
        {
        for(j=0;j<8;j++)
                ds1820wr(str2[j]);                //发送18B20序列号,先发送低字节
        }
        if(a==3)
        {
        for(j=0;j<8;j++)
                ds1820wr(str3[j]);                //发送18B20序列号,先发送低字节
        }
}

read_temp(uchar z)/*温度读取并转换*/
{        uchar a,b;
        float tt;
        ds1820rst();   
        ds1820wr(0xcc);                        //跳过序列号读取
        ds1820rst();
        if(z==1)
        {
                b20_Matchrom(1);                 //匹配ROM 1
        }
        if(z==2)
        {
                b20_Matchrom(2);                 //匹配ROM 2
        }
				        if(z==3)
        {
                b20_Matchrom(3);                 //匹配ROM 3
        }
        ds1820wr(0x44);//启动温度转换
        delay1ms(5);
        ds1820rst();   
        ds1820wr(0xcc);                                //跳过温度读取
        ds1820rst();
        if(z==1)
        {
                b20_Matchrom(1);                            //匹配ROM 1
        }
        if(z==2)
        {
                b20_Matchrom(2);                              //匹配ROM 2
        }
			        if(z==3)
        {
                b20_Matchrom(3);                             //匹配ROM 3
        }	
        ds1820wr(0xbe);//读取温度
        a=ds1820rd();
        b=ds1820rd();
        tvalue=b;
        tvalue<<=8;
        tvalue=tvalue|a;
    if(tvalue<0x0fff)
    tflag=0;
    else
                   {        tvalue=~tvalue+1;
                tflag=1;
                 }
        tt=tvalue*0.0625;
        tvalue=tt*10;
        return(tvalue);
}


/*****************显示函数******************************/
void ds1820disp(uchar z)//温度显示
{    uchar flagdat;
     disdata[0]=tvalue/1000+0x30;//显示百位
     disdata[1]=tvalue%1000/100+0x30;//显示十位
     disdata[2]=tvalue%100/10+0x30;//显示个位
     disdata[3]=tvalue%10+0x30;//显示小数位
   
     if(tflag==0)
     flagdat=0x20;//符号位为正
     else
       flagdat=0x2d;//符号位为负

     if(disdata[0]==0x30)
    {disdata[0]=0x20;//如百位为0,则不显示
   if(disdata[1]==0x30)
    {disdata[1]=0x20;//如十位不为0,则不显示
    }
   }
  if(z==1)
    {
    wr_com(0x82);
    wr_dat(flagdat);//符号字位
    wr_com(0x83);
    wr_dat(disdata[0]);//百位数
    wr_com(0x84);
    wr_dat(disdata[1]);//十位数
    wr_com(0x85);
    wr_dat(disdata[2]);//个位数
    wr_com(0x86);
    wr_dat(0x2e);//小数点
    wr_com(0x87);
    wr_dat(disdata[3]);//小数位
   }
  if(z==2)
    {
    wr_com(0xc2);
    wr_dat(flagdat);//·符号字位
    wr_com(0xc3);
    wr_dat(disdata[0]);//百位数
    wr_com(0xc4);
    wr_dat(disdata[1]);//十位数
    wr_com(0xc5);
    wr_dat(disdata[2]);//个位数
    wr_com(0xc6);
    wr_dat(0x2e);//小数点
    wr_com(0xc7);
    wr_dat(disdata[3]);//小数位
   }
}

void alarm(uchar z)//报警函数
{
	if(z==1)
	{
		if(tvalue>high|tvalue<low)
			LED1=1;
		else
			LED1=0;
	}
	if(z==2)
	{
		if(tvalue>high|tvalue<low)
			LED2=1;
		else
			LED2=0;
	}
	if(z==3)
	{
		if(tvalue>high|tvalue<low)
			LED3=1;
		else
			LED3=0;
	}
}



/********************主函数***********************************/
void main()
{
        lcd_init();//LCD1602
    while(1)
    {
                 read_temp(1);//读取数据
                 ds1820disp(1);//显示数据
				alarm(1);	//温度检测
                read_temp(2);//读取数据
                ds1820disp(2);//显示数据
								alarm(2);	
								read_temp(3);//读取数据
								alarm(3);	

  }
}
//-----------------------------------------------

延时设置原因具体参考数据手册
百度均能获得

作者为初学者如有错误,欢迎大家指正提出。

此文章为作者原创

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!