整体布图
此温度报警系统具体为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);
}
}
//-----------------------------------------------
延时设置原因具体参考数据手册
百度均能获得
作者为初学者如有错误,欢迎大家指正提出。
此文章为作者原创
来源:CSDN
作者:我不是fai5
链接:https://blog.csdn.net/qq_41570616/article/details/104063908