天天看点

DS18B20设计1个温度监测系统

DS18B20设计1个温度监测系统

项目要求

采集环境温度(0~99.9℃)显示在前3位数码管上。

原理图

DS18B20设计1个温度监测系统
DS18B20设计1个温度监测系统

代码编写

#include <reg52.h>
#include <intrins.h>	//包含函数库,用于调用_nop_()函数
#define uchar unsigned char 
#define uint unsigned int
bit flag;				//定义标志位,返回值作为是否存在的标志
sbit ds=P2^2;
sbit dula=P2^6;
sbit wela=P2^7;
uint temp;		//16位变量
uchar code table_du[]=
{
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
void delayus(uint t)	//us级延时函数
{
	while(t--);
}

void delay_ms(uchar z)	//ms级延时
{
	uchar i,j;
	for(i=z;i>0;i--)
		for(j=110;j>0;j--);
}
void ds_reset()	//复位初始化程序
{
	ds=1;		//先将数据线置高电平1
	delayus(5);	//如果11.0592M,大约为66us
	ds=0;		//数据线拉低到低电平0
	delayus(80);	//延时约700us
	ds=1;			//数据线拉到高电平1
	delayus(14);	//延时约154us
	if(ds==0)
		flag=1;		//标志位,表示18B20存在
	else
		flag=0;
	delayus(20);	//约200us
}

bit ds_read_bit()	//读取1位时序,用于下面读字节
{
	bit dat;		//定义一个位变量,作为返回值
	ds=0;			//拉低总线到0
	_nop_();		//一个机器周期,大约1us
	_nop_();		//延时约1us,加上上面的总计约2us
	ds=1;			//主机采样
	_nop_();		//延时用于稳定数据
	dat=ds;			//ds的电平的高低即为数据
	delayus(10);	//约100us
	return dat;		//这里之所以有返回值是因为单片机从DS18B20读出数据时,DS18B20要返回数据给到单片机。
}					//写操作里是因为单片机直接写数据到DS18B20,不需要DS18B20返回值。

uchar ds_read_byte()	//读1个字节,即单片机从DS18B20读数据,需要DS18B20返回数据
{
	uchar i,j,k;
	for(i=0;i<8;i++)	//1个字节由8位组成,将读的位数据一位一位的移入,
	{					//移入8位就组成1字节
		j=ds_read_bit();	//例如:j=1010 0101
		k=(j<<7)|(k>>1);	//Ex: j=1010 0101|k=0000 0000=1010 0101		
	}						
	return k;				//循环8次返回的值为j=1010 0101
}

void ds_write_byte(uchar dat)	//写1个字节,dat即为单片机向DS18B20中写的数据
{
	uchar i;
	for(i=0;i<8;i++)
	{
		ds=0;			//数据线先置低电平
		_nop_();		//约1us
		_nop_();
		ds=dat&0x01;	//每次只能写1位,即dat的最低位,数据读写均按照从低位到高位
		delayus(6);		//延时约70us	
		ds=1;			//将数据线拉到高电平1,准备下次的写入
		dat=dat>>1;		//右移1位
	}
	delayus(6);			//约70us
}

uint read_temperature()	//单片机读取DS18B20温度值
{
	uchar a,b;
	ds_reset();		//初始化
	ds_write_byte(0xcc);	//ROM操作指令,跳过ROM
	ds_write_byte(0xbe);	//存储器操作指令,读取温度指令
	a=ds_read_byte();		//执行/数据,低8位,a为8位变量。例a=0101 1010
	b=ds_read_byte();		//高8位, b为8位变量。例b=1010 0101
	temp=b;					//16位变量存放温度值(高8位+低8位)将b的值赋给temp。由于temp为16位变量,所以高位补0。temp=0000 0000 1010 0101
	temp=temp<<8;			//temp<<8为1010 0101 0000 0000
	temp=temp|a;			//temp|a为1010 0101 0101 1010
	temp=temp*0.0625*10+0.5;//按照固定公式进行转换运算,加0.5是用于四舍五入
	return temp;			//返回温度值
}

void display(uint temp)		//数码管显示程序
{							//将温度值得每位分开进行单独显示
	P0=table_du[temp/100];	//显示十位
	dula=1;
	dula=0;
	P0=0xfe;				//点亮第一个数码管
	wela=1;
	wela=0;
	delay_ms(10);

	P0=table_du[temp%100/10]|0x80;//添加小数点,使dp=1.即dp g f e d c b a =1000 0000
	dula=1;
	dula=0;
	P0=0xfd;
	wela=1;
	wela=0;
	delay_ms(10);

	P0=table_du[temp%100%10];	
	dula=1;
	dula=0;
	P0=0xfb;
	wela=1;
	wela=0;
	delay_ms(10);		
}

void main()
{
	while(1)
	{
		ds_reset();	//初始化
		ds_write_byte(0xcc);	//跳过ROM
		ds_write_byte(0x44);		//启动温度转换
		display(read_temperature());
	}
}

           
DS18B20设计1个温度监测系统
DS18B20设计1个温度监测系统
DS18B20设计1个温度监测系统

继续阅读