#include <reg52.h>
#include <at24c02.c>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2; //定义温度传感开关
uchar c; //温度赋值变量
uchar k; //温度上限值
sbit dula=P2^6;
sbit wela=P2^7;
sbit key2=P3^6; //独立键盘s4
sbit key3=P3^7; //独立键盘s5
sbit kai=P1^1; //继电器开关
sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit beem=P2^3;
uchar code table2[]={"H:"};
uchar code table1[]={0x04,0x15,0x0E,0x1F,0x01,0x1F,0x01,0x1F, // 当
0x05,0x1F,0x00,0x0E,0x0A,0x0A,0x0E,0x16, // 前
0x00,0x18,0x04,0x14,0x14,0x14,0x0C,0x04, //
0x00,0x00,0x18,0x18,0x00,0x00,0x18,0x18, //:
0x19,0x1A,0x04,0x08,0x08,0x08,0x04,0x02, // `c
0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}; //点
/*DS18B20*/
void dsreset(void)
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit
{
uint i;
bit dat;
DS=0;i++; //i++ for delay
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void)
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tmpwritebyte(uchar dat)
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void)
{
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0x44);
}
uint tmp()
{
float tt;
int temp;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread(); //接收低8位
b=tmpread(); //接收高八位
temp=b;
temp<<=8;
temp=temp|a;
tt=temp*0.0625;
temp=tt*10+0.5;
return temp;
}
/*1602液晶显示屏*/
void writecome(uchar com)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void writedata(uchar date)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init1()
{
wela=0;
dula=0;
lcden=0;
writecome(0x38);
writecome(0x0c);
writecome(0x06);
writecome(0x01);
}
/*扫描 显示*/
uchar scan()
{
if(key2==0)
{
delay(5);
if(key2==0)
{
while(!key2);
k+=1;
writeadd(2,k);
}
}
else if(key3==0)
{
delay(5);
if(key3==0)
{
while(!key3);
k-=1;
writeadd(2,k);
}
}
return k;
}
void display(uint temp) //显示程序 temp有百、十、个位;百位为十度位
{
uchar A,B,C,x,f;
f=temp/10; //温度取值
A=temp/100;
B=temp%100/10;
C=temp%10;
writecome(0x40); //字码入库
for(x=0;x<50;x++) //x尽量比规定的大一点,避免乱码
{
writedata(table1[x]);
}
writecome(0x80);
writedata(0); //当
writecome(0x81);
writedata(1);
writecome(0x82);
writedata(2); //前
writecome(0x83);
writedata(3); //:
writecome(0x87);
writedata(5); //.
writecome(0x89); //·c
writedata(4);
writecome(0x85);
writedata(0x30+A); //十
writecome(0x86);
writedata(0x30+B); //个
writecome(0x88);
writedata(0x30+C); //小数点后
writecome(0x80+0x0c);
writedata(table2[0]);
writecome(0x80+0x0d);
writedata(table2[1]);
c=scan();
//每显示一次,则将值给C
writecome(0x80+0x0e); //指针指向位置,依次写入
writedata(0x30+c/10);
writedata(0x30+c%10);
if(f>=c) //继电器,蜂鸣器开关
{
kai=1;
beem=0;
delay(100);
}
else
kai=0;
beem=1;
if(f<=(c-15)) //低于15时报警
beem=0;
else
beem=1;
}
/*主函数*/
void main()
{
uchar a;
k=30;
init1();
delay(20);
k=readadd(2); //读取断电前的温度上限值
while(1)
{
dsreset();
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
tmpchange();
for(a=10;a>0;a--)
{
display(tmp());
}
}
}