
//**************************************************//
//课题:温度智能控制//
//实现基本功能:智能采集外界的温度并用lcd数码管显示//
//扩展的功能:温度监督报警装置,当外界温度超过27时,//
// 红色led点亮。//
//**************************************************//
#include<reg52.h>
#define uchar unsigned char
uchar xdata wei _at_ 0x0ff20; //数码管的位选
uchar xdata duan _at_ 0x0ff21; //Pbport on 8255,数码管的段选
uchar xdata ctrl _at_ 0x0ff23; //control port on 8255
sbit DQ =P3^2;//18B20数据线引脚
sbit led=P3^1;//定义led警报引脚
uchar max=26;//定义报警温度27度
uchar temp;
uchar code scan[5] = {0xdf,0xef,0xf7,0xfb,0xfd,};//数码管显示的位码表
uchar code table[20] ={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,//不带点的0-9
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,//带点的0-9
};
uchar dispbuf[5]; //数据显示缓冲区2位整数+3位小数
uchar temper[2];//存放温度的数组
/*****************************延时函数**************************/
void delay (unsigned int us)
{
while(us--);
}
/******************复位函数******************/
void reset(void) //复位
{
uchar x=0;
DQ = 1;
delay(8); //稍做延时
DQ = 0;
delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(14);
x=DQ;
delay(20);
}
/**********************从DS18B20读一字节***************/
uchar readbyte(void) //读1字节
{
uchar i=0;
uchar dat=0;
for (i=8;i>0;i--)
{
DQ = 0;
dat>>=1;
DQ = 1;
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
/***********************DS18B20写入一个字节***********************/
/*********用于对DS18B20写入控制字****************/
void writebyte(unsigned char dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
delay(4);
}
/***********************读取温度值***************************/
void readtemp(void) //读取温度
{
uchar a=0,b=0;
reset();
writebyte(0xCC); // 跳过序列号
writebyte(0x44); // 启动温度转换
reset();
writebyte(0xCC);
writebyte(0xBE); //读9个寄存器,前两个为温度
a=readbyte(); //低位
b=readbyte(); //高位
temper[0]=a&0x0f;//取小数部分
a=a>>4; //低位右移4位,舍弃小数部分
temper[1]=b<<4; //高位左移4位,舍弃符号位
temper[1]=temper[1]|a;
}
/***********************数码管显示*************************/
void disp_Scan()
{
unsigned char i,value;
for(i=0;i<=4;i++)
{
value =table[dispbuf[i]]; //取显示数据段码
//value &= 0x7f;
duan= value;
delay(200);
//duan=0xff;
wei= scan[i];//取位
delay(200); //延时50us
wei= 0xff;//关显示
}
}
/******************************温度报警**********************/
void baojing(uchar t)
{
if(t>max)
led=0;
else
led=1;
}
/*******************************主函数***********************/
void main()
{
float backbit;
ctrl=0x80;
while(1)
{
uchar wd;
disp_Scan(); //显示扫描
readtemp(); //读18B20
backbit = temper[0]; //换成浮点数
backbit = backbit * 0.0625*1000; //小数点的后三位,乘以0.0625*1000
temp = backbit; //取低3位整数部分
dispbuf[4]=temp%10; //小数点第三位
temp=temp/10;
dispbuf[3] = temp%10; //小数点第二位
temp = temp/10;
dispbuf[2] = temp%10; //小数点第一位
temp = temper[1]; //取实际温度整数部分
wd=dispbuf[1] = temp%10; //个位
dispbuf[1]+=10; //给数码管显示第二位后面加小数点
temp = temp/10;
dispbuf[0]= temp%10; //十位
wd=wd+dispbuf[0]*10;
baojing(wd);//调用温度报警子程序
}
}
