/* 开机时第一行会显示一个数据,此数据不会控制小灯,当通过按键设定温度上限
和下限的时候,如果检测温度高于设定的温度上限就会报警LED1亮,
如果检测温度低于设定的温度下限也会报警LED2亮。如果在正常温度
的话,报警指示灯不会亮。第二行显示检测温度数据
S1~S10设定数据0~9;S11,S12温度上限设定开始,温度下限设定开始
S13,S14温度上限下限设定结束(要按着两个按键才会报警产生)
S15,设定温度清空;S16,小数点设置 */
#include
typedef unsigned char uint8;
typedef unsigned int uint16;
sbit rs=P2^6;
sbit rw=P2^5;
sbit e=P2^7;
sbit dq=P3^7;
sbit led1=P3^5;//高温报警指示灯
sbit led2=P3^6;//低温报警指示灯
uint8 num[10]="0123456789";
uint8 a,x,temp;
float temp1,temp2;//保存设置温度上、下限的数据
uint8 k=0;
uint8 key;
uint8 hbuf[3];//保存设置温度上限的数据
uint8 lbuf[3];//保存设置温度下限的数据
uint8 hdat[6]="H:38.3";
uint8 ldat[6]="L:10.5"; //初始显示,不起控制作用,只为显示
uint8 seth,setl;
void delay(uint16 i)
{
while(i--);
}
void wrc(uint8 c)
{
delay(1000);
rs=0;
rw=0;
e=0;
P0=c;
e=1;
delay(10);
e=0;
}
void wrd(uint8 dat)
{
delay(1000);
rs=1;
rw=0;
e=0;
P0=dat;
e=1;
delay(10);
e=0;
rs=0;
}
void lcdinit()
{
delay(1000);
wrc(0x38);
wrc(0x38);
wrc(0x38);
wrc(0x06);
wrc(0x0c);
wrc(0x01);
}
uint8 keyscan() //键盘扫描
{
uint8 h,l,value;
P1=0x0f; //列置0
h=P1&0X0F; //判断哪一行按下
if(h!=0x0f) //判断是否按下
{
delay(1000); //消抖
if(h!=0x0f)
{
l=P1|0xf0; //把列置1
P1=l; //把列状态给P1口
l=P1&0xf0; //判断那一列按下
h=P1&0X0F; //判断哪一行按下
value=h+l; //组合起来到底是那个按键按下
}
return value;
}
}
void keypros() //按键处理
{
uint8 KEY=0;
KEY=keyscan();
switch(KEY)
{
case 0xee: key=0;break;
case 0xde: key=1;break;
case 0xbe: key=2;break;
case 0x7e: key=3;break;
case 0xed: key=4;break;
case 0xdd: key=5;break;
case 0xbd: key=6;break;
case 0x7d: key=7;break;
case 0xeb: key=8;break;
case 0xdb: key=9;break;
case 0xbb: key=10;break;//设置温度上限开始按键
case 0x7b: key=11;break;//设置温度下限开始按键
case 0xe7: key=12;break;//设置温度上限结束按键
case 0xd7: key=13;break;//设置温度下限结束按键
case 0xb7: key=14;break;//清除设定的温度数据
case 0x77: key=15;break;//小数点
default : break;
}
}
void datapros()
{
uint8 c,d;
if(key==10) //设置温度上限开始按键
{
do
{
P1=0xf0;
if(P1!=0xf0)
{
keypros();
P1=0xf0;
while(P1!=0xf0);//等待按键松开
if(key>=0&&key<=9)
{
hbuf[c]=key;
wrc(0x02+c+0x80);
wrd(hbuf[c]+0x30);
c++;
}
if(key==15)
{
wrc(0x02+c+0x80);
wrd('.');
c++;
}
}
}
while(c<4);
if(c==4)
{
c=0;
}
}
if(key==11) //设置温度下限开始按键
{
do
{
P1=0xf0;
if(P1!=0xf0)
{
keypros();
P1=0xf0;
while(P1!=0xf0);//等待按键松开
if(key>=0&&key<=9)
{
lbuf[d]=key;
wrc(0x0b+d+0x80);
wrd(lbuf[d]+0x30);
d++;
}
if(key==15)
{
wrc(0x02+d+0x80);
wrd('.');
d++;
}
}
}
while(d<4);
if(d==4)
{
d=0;
}
}
if(key==12) //设置温度上限结束按键
{
temp1=hbuf[0]*10+hbuf[1]+hbuf[2]*0.1;
seth=1;
}
if(key==13) //设置温度下限结束按键
{
temp2=lbuf[0]*10+lbuf[1]+lbuf[2]*0.1;
setl=1;
}
if(key==14) //清空设置区
{
temp1=0;
temp2=0;
key=0;
led1=0;
led2=0;
seth=0;
setl=0;
wrc(0x02+0x80);
wrd(' ');
wrd(' ');
wrd(' ');
wrd(' ');
wrc(0x0b+0x80);
wrd(' ');
wrd(' ');
wrd(' ');
wrd(' ');
wrd(' ');
}
}
void ds18b20init() //18b20的初始化
{
dq=1;
delay(1);
dq=0;
delay(80);
dq=1;
delay(5);
dq=0;
delay(20);
dq=1;
delay(35);
}
void ds18b20wr(uint8 dat) //18b20写数据
{
uint8 i;
for(i=0;i<8;i++)
{
dq=0;
dq=dat&0x01;
dat>>=1;
delay(8);//在时序上只有这一块对时序要求最准确,他的时间必须大于15us
dq=1;
delay(1);
}
}
uint8 ds18b20rd() //18b20读数据
{
uint8 value,i;
for(i=0;i<8;i++)
{
dq=0;
value>>=1;
dq=1;
if(dq==1)value|=0x80;
delay(8);//在这一块也对时间要求特别准确,整段程序必须大于60us
}
return value;
}
uint8 readtemp() //读取温度内需要复位的
{
uint8 b;
ds18b20init(); //初始化
ds18b20wr(0xcc); //发送忽略ROM指令
ds18b20wr(0x44); //发送温度转换指令
delay(100);
ds18b20init(); //初始化
ds18b20wr(0xcc); //发送忽略ROM指令
ds18b20wr(0xbe); //发读暂存器指令
a=ds18b20rd(); //温度的低八位
b=ds18b20rd(); //温度的高八位
b<<=4; //ssss s***;s为标志位s=0表示温度值为正数,s=1温度值为负数
x=b&0x80; //温度正负标志位确认
b+=(a&0xf0)>>4;
a=a&0x0f; //温度的小数部分
return b;
}
void display()
{
uint16 p;
float dio;
dio=a*0.0625;
p=dio*10000;//取小数点后两位有效数字
wrc(0x06+0x80);
wrd(' ');
wrd(' ');
wrd(' ');
wrc(0x0f+0x80);
wrd(' ');
wrc(0x80+0x43);
if(x==0x80) //读取到负温度即为补码,要将其转换成源码
{
wrd('-');
temp=temp-1;
temp=(~temp)|0x80;//负数的补码即为反码+1;而负数的反码为其源码取反,除了符号位;正数的补码等于正数的反码等于正数的源码
}
else
{
wrd('+');
temp=(temp);
}
wrd(num[temp/100]);
wrd(num[temp%100/10]);
wrd(num[temp%100%10]);
wrd('.');
wrd(num[p/1000]);
wrd(num[p%1000/100]);
wrd(0xdf);
wrd('C');
}
void time0init()
{
TMOD=0X01;
TH0=0XFC;
TL0=0X18; //1ms
TR0=1;
EA=1;
ET0=1;
}
void tim0() interrupt 1
{
static uint8 j;
TH0=0XFC;
TL0=0X18;
j++;
if(j==100) //定时100ms
{
j=0;
keypros();
datapros();
if(seth==1&&setl==1)
{
if(temp
{
led1=0;
}
else
led1=1;
if(temp>temp2)
{
led2=0;
}
else
led2=1;
}
}
}
void main()
{
uint8 i;
lcdinit();
time0init();
led1=0;
led2=0;
wrc(0x00+0x80);
for(i=0;i<6;i++)
{
wrd(hdat[i]);
}
wrc(0x09+0x80);
for(i=0;i<6;i++)
{
wrd(ldat[i]);
}
while(1)
{
temp=readtemp();
display();
/*
if(seth==1&&setl==1)
{
if(temp
{
led1=0;
}
else
led1=1;
if(temp>temp2)
{
led2=0;
}
else
led2=1;
}*/
}
}