#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DQ=P2^2;//ds18b20与单片机连接口
sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P2^5;
sbit en573=P2^6;
sbit en1573=P2^7;
uchar data disdata[5];
uint tvalue,CurrentT=0;//温度值
uchar tflag;//温度正负标志
#define LCD_BUS P0
sbit SetKey= P3^4;
sbit UpKey= P3^5;
sbit DnKey= P3^6;
sbit BEEP= P2^3;
unsigned char AlarmTempLow=10,AlarmTempTop=40,Set=0,NG=0;
void delayms(uint ms) //延时xx毫秒
{
uchar i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
void command(uint com) //LCD写指令
{
RS=0; //RS为0
LCD_BUS=com; //装载指令
delayms(5); //延时5ms
EN=1; //LCD使能
delayms(5); //延时5ms
EN=0; //LCD不使能
}
void write_dat(uchar dat) //LCD写数据
{
RS=1; //RS为1
LCD_BUS=dat; //装载数据
delayms(5); //延时5ms
EN=1; //LCD使能
delayms(5); //延时5ms
EN=0; //LCD不使能
}
void writestring(uchar x,uchar y,uchar *s) //LCD 写字符串
{
if (y == 0) command(0x80 + x); //表示第一行
else command(0xC0 + x); //表示第二行
while (*s) //判断是否字符串的结尾
{
write_dat( *s); //显示当前字符
s ++; //字符串地址加1
}
}
void writeChar(uchar x,uchar y,uchar s) //LCD 写字符串
{
if (y == 0) command(0x80 + x); //表示第一行
else command(0xC0 + x); //表示第二行
{
write_dat( s); //显示当前字符
}
}
void LCD_Initial() //LCD初始化
{
EN=0; //LCD不使能
RW=0; //RW为0
command(0x38); //发送初始化指令
command(0x0c); //发送初始化指令
command(0x06); //发送初始化指令
command(0x01); //发送初始化指令
command(0x80+0x02); //发送LCD初始位置
}
/*************************DS1820程序****************************/
void delay_18B20(unsigned int i)//延时1微秒
{
while(i--);
}
void ds1820rst(void)/*ds1820复位*/
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(4); //延时
DQ = 0; //DQ拉低
delay_18B20(100); //精确延时大于480us
DQ = 1; //拉高
delay_18B20(40);
}
uchar ds1820rd(void)/*读数据*/
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; //给脉冲信号
dat>>=1;
DQ = 1; //给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(10);
}
return(dat);
}
void ds1820wr(uchar wdata)/*写数据*/
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = wdata&0x01;
delay_18B20(10);
DQ = 1;
wdata>>=1;
}
}
unsigned int Read_Temperature(void)/*读取温度值并转换*/
{
uchar a,b;
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0x44);//*启动温度转换*/
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0xbe);//*读取温度*/
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff) tflag=0;
else {tvalue=~tvalue+1;tflag=1;}
tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
CurrentT=tvalue;
return(tvalue);
}
void Display_Temperature() //显示温度
{
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,十位为0也不显示
//}
if(tflag==1)
{
writeChar(10,0,flagdat);//wr_com(0x8a);wr_dat(flagdat);//显示符号位
writeChar(11,0,disdata[0]);//wr_com(0x8b);wr_dat(disdata[0]);//显示百位
writeChar(12,0,disdata[1]);//wr_com(0x8c);wr_dat(disdata[1]);//显示十位
writeChar(13,0,disdata[2]);//wr_com(0x8d);wr_dat(disdata[2]);//显示个位
writeChar(14,0,0X2E);//wr_com(0x8e);wr_dat(0x2e);//显示小数点
writeChar(15,0,disdata[3]);//wr_com(0x8f); wr_dat(disdata[3]);//显示小数位
}
else
{
writeChar(10,0,disdata[0]);//wr_com(0x8a);wr_dat(disdata[0]);//显示百位
writeChar(11,0,disdata[1]);//wr_com(0x8b);wr_dat(disdata[1]);//显示十位
writeChar(12,0,disdata[2]);//wr_com(0x8c);wr_dat(disdata[2]);//显示个位
writeChar(13,0,0X2e);//wr_com(0x8d);wr_dat(0x2e);//显示小数点
writeChar(14,0,disdata[3]);//wr_com(0x8e);wr_dat(disdata[3]);//显示小数位
}
}
void SetFun(void)
{
unsigned char i1=0,i2=0,i3=0,i4=0,i5=0,i6=0;
if(SetKey==0)
{
delayms(20);
if(SetKey==0)
{
if(Set<2) Set++;
else Set=0;
}
switch(Set)
{
case 0: writestring(0,1," ");writestring(8,1," ");break;
case 1: writestring(0,1,">");writestring(8,1," ");break;
case 2: writestring(0,1," ");writestring(8,1,">");break;
}
while(SetKey==0);
}
if((UpKey==0)&&(Set!=0))
{
delayms(20);
if(UpKey==0)
{
switch(Set)
{
case 1: if(AlarmTempLow<99) AlarmTempLow++;else AlarmTempLow=99; break;
case 2: if(AlarmTempTop<99) AlarmTempTop++;else AlarmTempTop=99; break;
}
i1 = AlarmTempLow/100; //获得温度值的百位
i2 = AlarmTempLow%100/10; //获得温度值的十位
i3 = AlarmTempLow%10; //获得温度值的个位
i4 = AlarmTempTop/100; //获得温度值的百位
i5 = AlarmTempTop%100/10; //获得温度值的十位
i6 = AlarmTempTop%10; //获得温度值的个位
writestring(5,1," ");
writestring(13,1," ");
if(i1!=0) writeChar(5,1,i1+'0');
if((i1==0)&&(i2!=0)) writeChar(5,1,i2+'0');
if(i1!=0) writeChar(6,1,i2+'0');
if((i1==0)&&(i2==0)) writeChar(5,1,i3+'0');
else if((i1==0)&&(i2!=0)) writeChar(6,1,i3+'0');
if((i1!=0)) writeChar(7,1,i3+'0');
if(i4!=0) writeChar(13,1,i4+'0');
if((i4==0)&&(i5!=0)) writeChar(13,1,i5+'0');
if(i4!=0) writeChar(14,1,i5+'0');
if((i4==0)&&(i5==0)) writeChar(13,1,i6+'0');
else if((i4==0)&&(i5!=0)) writeChar(14,1,i6+'0');
if((i4!=0)) writeChar(15,1,i6+'0');
while(UpKey==0);
}
}
if((DnKey==0)&&(Set!=0))
{
delayms(20);
if(DnKey==0)
{
switch(Set)
{
case 1: if(AlarmTempLow>0) AlarmTempLow--;else AlarmTempLow=0; break;
case 2: if(AlarmTempTop>0) AlarmTempTop--;else AlarmTempTop=0; break;
}
i1 = AlarmTempLow/100; //获得温度值的百位
i2 = AlarmTempLow%100/10; //获得温度值的十位
i3 = AlarmTempLow%10; //获得温度值的个位
i4 = AlarmTempTop/100; //获得温度值的百位
i5 = AlarmTempTop%100/10; //获得温度值的十位
i6 = AlarmTempTop%10; //获得温度值的个位
writestring(5,1," ");
writestring(13,1," ");
if(i1!=0) writeChar(5,1,i1+'0');
if((i1==0)&&(i2!=0)) writeChar(5,1,i2+'0');
if(i1!=0) writeChar(6,1,i2+'0');
if((i1==0)&&(i2==0)) writeChar(5,1,i3+'0');
else if((i1==0)&&(i2!=0)) writeChar(6,1,i3+'0');
if((i1!=0)) writeChar(7,1,i3+'0');
if(i4!=0) writeChar(13,1,i4+'0');
if((i4==0)&&(i5!=0)) writeChar(13,1,i5+'0');
if(i4!=0) writeChar(14,1,i5+'0');
if((i4==0)&&(i5==0)) writeChar(13,1,i6+'0');
else if((i4==0)&&(i5!=0)) writeChar(14,1,i6+'0');
if((i4!=0)) writeChar(15,1,i6+'0');
/*writeChar(4,1,i1+'0');
writeChar(5,1,i2+'0');
writeChar(6,1,i3+'0');
writeChar(12,1,i4+'0');
writeChar(13,1,i5+'0');
writeChar(14,1,i6+'0');*/
while(DnKey==0);
}
}
}
void main(void)
{
unsigned char i=0; //P3=0xef;
P2=0xef;BEEP=1;
LCD_Initial(); //LCD 初始化
P0=0x00;
en573=1;
en573=0;
P0=0x00;
en1573=1;
en1573=0;
Read_Temperature(); //读取温度值
writestring(1,0,"DS18B20 Alarmer"); //显示“DS18B20 Alarmer”
delayms(1000); //延时1S
writestring(0,0,"Current T= "); //显示“Current T= ”
writestring(0,1," Low=10 Top=40 "); //显示“ Low=10 Top=40 ”
NG=0;
while(1)
{
Read_Temperature(); // //读取温度值
Display_Temperature(); //显示温度值
SetFun();
if((CurrentT<(AlarmTempTop*10))&&(CurrentT>(AlarmTempLow*10)))
{
BEEP=1;
}
else if((CurrentT>(AlarmTempTop*10)))
{
while(1)
{
BEEP=0;
delayms(200);
BEEP=1;
delayms(200);
}
}
else if((CurrentT<(AlarmTempLow*10))||(tflag==1))
{
while(1)
{
BEEP=0;
delayms(1000);
BEEP=1;
delayms(1000);
}
}
}
}