單片機常用芯片系列(二)——DS18B20詳解(2)——寄生電源供電(包括調試中遇到的問題,編程思路)

我在藍橋杯的板子上看到,他的是寄生電源供電,也就是沒有外接電源,靠總線高電平供電,低電平電容放電。編程之處略有不同。

網上很多資料,我還是隻說最難懂的點

一、注意事項

1.在這裏插入圖片描述溫度轉換命令【44h】後面要加延時,而且總線要置1,提供上拉電流。

send(0xcc);
send(0x44);
DAT = 1;
delay1s();

2.在這裏插入圖片描述在這裏插入圖片描述
爲了提高可移植性,可以這樣寫

uchar way;
send(0xcc);
send(0xb4);
way = read();//讀取溫度狀態
DAT = 1; //釋放總線


if(way == 1)
{
	#define waibu
}

#ifdef waibu
......
#else
......
#endif
......

3.在這裏插入圖片描述注意:
每次命令都得初始化

常用命令
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
初始化時序:
總線拉低500微秒,再釋放總線(拉高)。然後進入接收模式。如果設備正常會發送應答信號,也就是低電平把總線拉低200微秒。

uchar i = 0;
DAT = 1;
DAT = 0;
delay600us();
DAT = 1;
dealay100us();
while(DAT == 1)
{
	if(i == 5)
	{
		return 0;
	}
	i++
}
return 1;

寫時序:
1.總線置一
2.總線置零
3.等5微秒
4.總線保持60微妙(寫0)
總線拉高,保持60微秒(寫1)
5.總線置1保持1微秒以上

DAT = 1;
DAT = 0;
delay5us();
DAT = 0;
//DAT = 1;  寫1
delay60us();
DAT = 1;

在這裏插入圖片描述
讀時序:
1.總線置一
2.總線置零
3.等4微秒
4.總線置一(釋放總線)
5.等

讀一個位:

DAT = 1;
DAT = 0;
delay();
DAT = 1;
delay();

uchar dat;
dat = DAT;

DAT = 1;

讀一個字節:

uchar readByte()
{
	uchar i,dat=0;
	uchar da=0;
	
	for(i=0;i<8;i++)
	{
		DATA=0;
		_nop_();
		DATA=1;
		delay4us();
		da=DATA;
		da<<=7;
		dat=(dat>>1)|da;
		delay60us();
	}
	return dat;
}

溫度換算是負溫度減一取反乘精度
正溫度直接乘精度

注意:在上電覆位的時候,溫度寄存器中的值爲0x0550,即+85攝氏度。所以在應用開發中,有些朋友一直讀到的數據都是85.5攝氏度,就說明DS18B20根本沒有進行溫度轉換,你讀到的是上電覆位的初始值。

——————————————分割線————————————————

乾貨來了!!!!!!!!!!!!!!!!!!!!正式開始編程!

首先,先測試一下能不能用
那麼就是初始化一下看看返回值是不是0

經過兩天的測試,檢測不到這個玩意。。
全文完

大家自己做,應該是可以的。代碼沒問題,

後來檢測到了,大家繼續往後看

#include "ds18b20.h"

////單總線延時函數
void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}

void Delay_OneWire1(unsigned int t)  
{
	while(t--);
}

void Delay_us(void)
{
	unsigned char i;

	i = 30;
	while (--i);
}

//通過單總線向DS18B20寫一個字節
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);

}

//從DS18B20讀取一個字節
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
//	unsigned char index = 0;
  	   	
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1; 
	   	Delay_us();

		if(DQ)  
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}


//DS18B20初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;

  	Delay_OneWire(80); // 延時大於480us
  	DQ = 1;
  	Delay_OneWire(5);  // 14
  	initflag = DQ;     // initflag等於1初始化失敗
  	Delay_OneWire(50);
  
  	return initflag;
}

————————分割線————————————————

更新於2020.3.29

服了,又可以了。我腦子瓦特了

在這裏插入圖片描述
箭頭這裏是電阻上拉的意思。所以不能等時間太久,不然就等不到,所以才顯示的檢測不到硬件。
在這裏插入圖片描述這裏原來是50,我改成5了,立馬就檢測到了
返回值是0

然後我們檢測一下供電方式。這裏也是一個大坑,無力吐槽藍橋杯這個板子的奇葩設計。。

uchar rd_temperature(void)
{
	uchar dq;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xb4);
	Delay_OneWire(5); 
	dq = DQ;
	return dq;
}

在這裏插入圖片描述看起來是寄生電源供電,實際上是外部電源供電。。。
因爲寄生電源供電的話,vdd和gnd都接地,這個不是
所以這段代碼的返回值是1。。。
在這裏插入圖片描述我都是用串口檢測的

下一步開始測溫度

int rd_temperature(void)
{
	uchar LOW = 0,HIGH = 0;
	int temp = 0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay1000ms() ;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	LOW = Read_DS18B20();
	HIGH = Read_DS18B20();
	
	temp = (HIGH << 8) | (LOW);
	return temp;
}

主函數這裏數據處理一下

	int GOODORNOT = 0;
	Init();
	uartInit();
	
	while(1)
	{	
		GOODORNOT = rd_temperature();
		GOODORNOT = GOODORNOT*0.0625+0.5;
		uartSendByte((uchar)(GOODORNOT/10)+'0');
		uartSendByte((uchar)(GOODORNOT%10)+'0');
		delay(50000);
	}

在這裏插入圖片描述成功

全文完

有問題的可以留言評論

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章