#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds = P2^2;
sbit dula = P2^6;
sbit wela = P2^7;
sbit beep = P2^3;
uint temp;
float f_temp;
uint warn_11 = 270;
uint warn_12 = 250;
uint warn_h1 = 300;
uint warn_h2 = 320;
sbit led1 = P1^1;
sbit led2 = P1^2;
sbit led3 = P1^3;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,0x7f,0x6f,//带小数点的0~9编码
0xbf,0x86,0xdb,0xcf,
0xe6,0xed,0xfd,0x87,
0xff,0xef};//不带小数点的0~9编码
/*------延时函数------*/
void delay(uint z)
{
uint x,y;
for(x = z;x>0;x--)
for(y = 110;y>0;y--);
}
/*DS18B20复位,初始化函数----*/
void dsreset(void)
{
uint i;
ds = 0;
i = 103;
while(i>0)i--;
ds = 1;
i = 4;
while(i>0)i--;
}
/*-----读一位数据函数------*/
bit tempreadbit(void)
{
uint i;
bit dat;
ds = 0;i++;//“i++”起延时作用
ds = 1;i++;i++;
dat = ds;
i = 8;while(i>0)i--;
return(dat);
}
/*-----读一个字节数据函数------*/
uchar tempread(void)
{
uchar i,j,dat;
dat = 0;
for(i = 1;i<8;i++)
{
j = tempreadbit();
dat = (j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在dat里面
}
return (dat);
}
/*-----向DS18B20向写一个字节数据函数------*/
void tempwritebyte(uchar dat)
{
uint i;
uchar j;
bit testb;
for(j = 1;j<8;j++)
{
testb = dat&0x01;
dat = dat>>1;
if(testb)
{
ds = 0;
i++;i++; //“i++”起延时作用
ds = 1;
i = 8;while(i>0)i--;
}
else
{
ds = 0;//写0
i = 8;while(i>0)i--;
ds = 1;
i++;i++ ;
}
}
}
/*-----DS18B20开始获取温度并转换------*/
void tempchange(void)
{
dsreset();
delay(1);
tempwritebyte(0xcc);//写跳过读ROM指令
tempwritebyte(0x44);//写温度转换指令
}
/*-----读取寄存器中储存的温度数据------*/
void get_temp()
{
uchar a,b;
dsreset();
delay(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
a = tempread();//读低8位
b = tempread();//读高8位
temp = b;
temp<<= 8;//两字节组合为一个字
temp = templa;
f_temp = temp*0.0625;//温度在寄存器中为12位,分辨率为0.0625°
temp = f_temp*10+0.5;//乘以10表示小数点后面只取一位,加0.5是四舍五入
f_temp = temp+0.05;
return temp;//temp是整型
}
/*-----数据显示程序------*/
void display(uchar num,uchar dat)
{
uchar i;
dula = 0;
P0 = table[dat];//编码赋给P0口
dula = 1;
wela = 0;
i = 0xFF;
i = i&(~(0X01)<<(num));//用i来存储位选数据,只有一位为0
P0 = i;
wela = 1;
wela = 0;
delay(1);
}
/*-----显示温度数值函数t传递的是整型的温度值------*/
void dis_temp(uint t)
{
uchar i;
i = t/100; //除以100得到商,为温度的十位
display(0,i); //在第一个数码管上显示
i = t%100/10; //100取余数再除以10得到商,为温度的个位
display(1,i+100); //在第二个数码管上显示
i = t%100%10; //100取余数再用10取余,为温度的小数位
display(2,i); //在第三个数码管上显示
}
/*-----蜂鸣器报警,灯闪烁------*/
void warn(uint s,uchar led)
{
uchar i;i = s;
beep = 0;///蜂鸣器响
P1 = ~(led);
while(i--)
{
dis_temp(get_temp());//用温度显示函数起到延时作用
}
beep = 1;//蜂鸣器不响
P1 = 0XFF;//控制相应的灯灭
i = s;
while(i--)
{
dis_temp(get_temp());//用温度显示函数起到延时作用
}
}
/*-----温度处理函数-------*/
void deal(uint t)
{
uchar i;
if((t>warn_12)&&(t<=warn_11))//大于25度小于27度
{
warn(40,0x01);//第一个灯亮,蜂鸣器发出“滴”声
}
else if(t<warn_12)//小于25度
{
warn(10,0x03);//第一个和第二个灯亮,蜂鸣器发出“滴”声
}
else if((t<warn_h2)&&(t<=warn_h1))//小于32度和大于30度
{
warn(40,0x04);//第三个灯亮,蜂鸣器发出“滴”声
}
else if(t>warn_h2)//大于32度
{
warn(10,0x0c);//第三个和第四个灯亮,蜂鸣器发出“滴”声
}
else //在27度到30度之间时只是调用显示函数延时
{
i = 40;
while(i--);
{
dis_temp(get_temp());
}
}
}
/*------------串口初始化函数-----------*/
void init_com(void)
{
TMOD = 0x20;
PCON = 0X00;
SCON = 0X50;
TH1 = 0XFd;
TL1 = 0XFd;//baud9600
TR1 = 1;
}
/*------------串口数据发送函数-----------*/
void comm(char *parr)
{
do
{
SBUF = *parr++;//发送数据
while(!TI);//等待发送完成标志为1
TI = 0;//标志清零
}while(*parr);//保持循环直到字符为'\0'
}
/*-----------主函数-------------------*/
void main()
{
uchar buff[4],i;
dula = 0;
wela = 0;
init_com();
while(1)
{
tempchange();//温度转换器
for(i = 10;i>0;i--)
{
dis_temp(get_temp());//获取温度并显示
}
deal(temp);//进行温度处理
springtf(buff,"%f",f_temp);//将浮点型温度格式化为字符型
for(i = 10;i>0;i--)
{
dis_temp(get_temp());//温度并显示
}
comm(buff);//串口发送数据
for(i = 10;i>0;i--)
{
dis_temp(get_temp());//获取温度并显示
}
}
}
|