DS18B20设计1款简单的温度监测系统

DS18B20设计1款简单的温度监测系统

项目要求:

1.采集环境温度(0~99.9℃)显示在前3位数码管上。
2. 温度值T判断:
当T<25℃时, D1,D2闪烁,蜂鸣器短鸣;
当25℃<T<27℃时,D1闪烁,蜂鸣器长鸣;
当27℃<T<30℃时,只显示温度值;
当30℃<T<32℃时,D3闪烁,蜂鸣器长鸣;
当T>32℃时,D3,D4 闪烁,蜂鸣器短鸣;
3. 用串口将采集的温度数据实时发送至上位机显示。

原理图:
引用
引用
代码:

#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
bit flag;
sbit dula=P2^6;
sbit wela=P2^7;
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit ds=P2^2;
sbit buzzer=P2^3;
uint alarm1=250;
uint alarm2=270;
uint alarm3=300;
uint alarm4=320;
uchar code table_du[]=
{
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};

uint temp;
float f_temp;
void delay_us(uint t)
{
	while(t--);
}

void delay_ms(uchar t1)
{
	uint i,j;
	for(i=t1;i>0;i--)
		for(j=110;j>0;j--); 	
}

void ds_init()		//DS18B20初始化
{
	ds=1;
	delay_us(5);
	ds=0;
	delay_us(80);	//约700us
	ds=1;
	delay_us(20);	//约214us
	if(ds==0)
		flag=1;
	else
		flag=0;
	delay_us(30);	//约311us
}

bit ds_read_bit()		//读1位数据
{
	bit dat;
	ds=0;
	_nop_();		//约1us
	_nop_();
	ds=1;
	_nop_();
	dat=ds;
	delay_us(5);	//约67us
	return dat;
}

uchar ds_read_byte()	//读1字节数据
{
	uchar i,j,k;
	for(i=0;i<8;i++)
	{
		j=ds_read_bit();
		k=(j<<7)|(k>>1);	//将j的最低位移到最高位,k右移1位,然后或操作
	}					//即将j的值移入k的最高位。下一次就将这1位移入次高位
	return k;			//经过7次移位操作,将j的值完全移入k,然后返回
}

void ds_write_byte(uchar dat)	//单片机向DS18B20中写字节数据
{
	uchar i;					//用于循环计数
	for(i=0;i<8;i++)
	{
		ds=0;					//置0进行读写数据
		_nop_();				//延时使数据保持稳定
		_nop_();
		ds=dat&0x01;			//dat与0x01与完后只剩最低位,其他高位全为0	
		delay_us(6);			//延时让DS18B20用足够的时间采样
		ds=1;					//置1用于数据操作,即加工数据,右移1位
		dat=dat>>1;				//使次低位变为最低位
	}	
	delay_us(6);
}

void tempconversion(void)	//DS18B20开始获取温度并转换
{
	ds_init();			//初始化
	ds_write_byte(0xcc);//跳过ROM
	ds_write_byte(0x44);//开始温度转换命令		
}
uint read_temperature()	//单片机读取温度,这里必须用uint型
{
	uchar a,b;		//用于存放高8位和低8位数据
	ds_init();		//初始化
	ds_write_byte(0xcc);	//跳过ROM操作指令,即单片机不用提供64位ROM
	ds_write_byte(0xbe);
	a=ds_read_byte();		//温度值的低8位,例0000 0000 0101 1010
	b=ds_read_byte();		//温度值的高8位,例0000 0000 1010 0101
	temp=b;					
	temp=temp<<8;				//temp的低8位左移8位变为temp的高8位 1010 0101 0000 0000
	temp=temp|a;			//1010 0101 0000 0000|0000 0000 0101 1010
	f_temp=temp*0.0625;		//温度在寄存器中为12位,分辨率为0.0625℃
	temp=f_temp*10+0.5;	//乘以10表示小数点后面只取1位,加0.5用于四舍五入
	f_temp=f_temp+0.05;
	return temp;	
}

void display(uint temp)	//数码管显示温度程序
{						//uint可表示0~65535个数
	uchar bai, shi, ge;	//uchar只能表示0~255个数
	bai=temp/100;
	shi=temp%100/10;
	ge=temp%100%10;
	P0=table_du[bai];
	dula=1;
	dula=0;
	P0=0xfe;
	wela=1;
	wela=0;
	delay_ms(5);
	
	P0=table_du[shi]|0x80;
	dula=1;
	dula=0;
	P0=0xfd;
	wela=1;
	wela=0;
	delay_ms(5);

	P0=table_du[ge];
	dula=1;
	dula=0;
	P0=0xfb;
	wela=1;
	wela=0;
	delay_ms(5);
		
}


void alarm(uint s, uchar led)	//蜂鸣器报警,LED闪烁
{
	uchar i;
	i=s;
	buzzer=0;					//蜂鸣器响
	P1=~(led);					//控制相应的灯亮
	while(i--);				
	{
		display(read_temperature());//用温度显示函数起到延时作用
	}
	buzzer=1;					//蜂鸣器不响
	P1=0xff;					//控制相应的灯灭
	while(i--)
	{
		display(read_temperature());
	}
}

void deal(uint t2)	//温度处理函数
{
	uchar i;
	if(t2<=alarm1)			//t2<=25℃
	{
		alarm(5,0x03);		//点亮led1,蜂鸣器发出'滴'响
	}
	else if((t2>alarm1)&&(t2<=alarm2))
	{
		alarm(40,0x01);
	}
	else if((t2>=alarm3)&&(t2<alarm4))
	{
		alarm(40,0x04);
	}
	else if(t2>=alarm4)
	{
		alarm(5,0x0c);
	} 
	else	//27℃<t2<30℃,只调用显示函数延时
	{
		i=40;
		while(i--)
		{
			display(read_temperature());
		}
	}
}

void init_com(void)		//串口初始化
{
	TMOD=0x20;	//T1定时器工作方式3
	PCON=0x00;
	SCON=0x50;	//确定串行口控制
	TH1=0xfd;	//装初值,设置波特率为9600
	TL1=0xfd;
	TR1=1;
}

void comm(char *parr)	//串口数据发送函数
{
	do
	{
		SBUF=*parr++;	//发送数据
		while(!TI);		//等待发送完成标志为1
		TI=0;			//标志清0
	}
	while(*parr);		//保持循环直到字符为'\0'
}
void main()	//主函数
{
	uchar buff[4],i;
	dula=0;
	wela=0;
	init_com();
	while(1)
	{
		tempconversion();	//温度转换
		for(i=10;i>0;i--)
		{
			display(read_temperature());	//获取温度并显示
		}
		deal(temp);			//进行温度处理
		sprintf(buff,"%f",f_temp);	//将浮点型温度格式化为字符型
		for(i=10;i>0;i--)
		{
			display(read_temperature());	//温度显示
		}	
		comm(buff);					//串口发送数据
		for(i=10;i>0;i--)
		{
			display(read_temperature());//温度显示	
		}
	}	
}

参考资料
us级延时函数延时时间对照表
在这里插入图片描述
在这里插入图片描述
串口初始化设置
在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值