天天看點

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個溫度監測系統

繼續閱讀