99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

  • 回復(fù)
  • 收藏
  • 點贊
  • 分享
  • 發(fā)新帖

求助DS18B20讀不出正確的數(shù)據(jù)

先貼上DS18B20的驅(qū)動,這個我是照著書抄的,可以確定沒抄錯,因為是初學(xué)所以想先用現(xiàn)成的。

下面的程序是DS18B20.c里的代碼,是用來驅(qū)動18B20的。我的工程包含多個文件。

#include

#define uchar unsigned char 
#define uint unsigned int

sbit DQ = P1^0;         //DS18B20的DQ腳

void Delay(int num)
{
	for (;num>0;num--);
}

void Init_DS18B20(void)           //初始化18B20
{
	unsigned char x=0;
	DQ = 1;    
	Delay(8);  
	DQ = 0;    
	Delay(80);  
	DQ = 1;    
	Delay(14);
	x=DQ;      
	Delay(20);
}

/******************************************************************************/
unsigned char ReadOneChar(void)         //從18B20讀取一個字節(jié)
{
	unsigned char i=0;
	unsigned char dat = 0;
	for (i=8;i>0;i--)
	{
		DQ = 0; 
		dat>>=1;
		DQ = 1; 
		if(DQ)
		dat|=0x80;
		Delay(4);
	}
	return(dat);
}
/******************************************************************************/
void WriteOneChar(unsigned char dat)          向18B20寫入一個字節(jié)
{
	unsigned char i=0;
	for (i=8; i>0; i--)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay(5);
		DQ = 1;
		dat>>=1;
	}
}
/******************************************************************************/
unsigned int ReadTemperature(void)                    //讀取溫度
{
	unsigned char a=0;
	unsigned char b=0;
	unsigned int t=0;
	float tt=0;
	Init_DS18B20();
	WriteOneChar(0xCC); 
	WriteOneChar(0x44); 
	Init_DS18B20();
	WriteOneChar(0xCC); 
	WriteOneChar(0xBE); 
	a=ReadOneChar();  
	b=ReadOneChar(); 
	t=b;
	t<<=8;
	t=t|a;
	tt=t*0.0625;
	t= tt*10+0.5; 
	return(t);
}

uchar printTemperature(void)
{
	unsigned int i=0;
	unsigned char a=0,b=0,c=0;
	i=ReadTemperature();
	a=i/100;
	b=i/10-a*10;
	i = a*10 + b;
	return i;		
}

下面的程序是main.c里的:

#include
#include

#define uint unsigned int
#define uchar unsigned char
extern void Init_UART(void);
extern void UART_T_CHAR(uchar);
extern void UART_T_STRING(uchar *);
extern unsigned int ReadTemperature(void);
extern uchar printTemperature(void);

uchar code string[]="Current Temperature Is:";

void delayms(uint t)
{
	uint i,j;
	for(i=t;i>0;i--)
	for(j=100;j>0;j--);
}

void Init_MCU()
{
	EX0=1;
	EA=1;
}

void main()
{
	uint tempr;       //用于存儲當前溫度
	uchar temp_char[3]="000";         //存儲當前溫度的字符數(shù)組
	Init_MCU();
	Init_UART();
	
	while(1)
	{
		tempr=ReadTemperature();
		/*tempr=tempr/10;                                         
		temp_char[1]=tempr%10+'0';
		temp_char[0]=(tempr-tempr%10)/10+'0';              
		temp_char[2]='\0';*/                                           //以上4行是將數(shù)值型溫度數(shù)據(jù)轉(zhuǎn)換為對應(yīng)的字符數(shù)組,因為現(xiàn)在在測試
		UART_T_STRING(string);                                      //這個程序,暫未使用
		//UART_T_STRING(temp_char);                           //此語句也暫未使用
		TI=1;                                                                  //從此行起到TI=0;是為了測試DS18B20的驅(qū)動是否工作正常而臨時加入的
		printf("%d\n",tempr);                                         //用printf函數(shù)將tempr的數(shù)值發(fā)送到上位機,如果DS18B20驅(qū)動正常,ze
		while(!TI);                                                           //上位機可收到數(shù)值,給18B20加溫,數(shù)值會變化。
		TI=0;
		delayms(5000);
	}
}

void ISP_Download() interrupt 0   //該中斷子程序通過使用外中斷0,在INT0腳對地短接時將軟復(fù)位MCU
{                                                   //從而實現(xiàn)不冷啟動也能下載程序
	IAP_CONTR=0x60;
}

下面的程序是UART.c里的,用來驅(qū)動串口,向上位機發(fā)送溫度數(shù)據(jù),實測以下的代碼沒有問題

#include
#include

#define uint unsigned int
#define uchar unsigned char
void Init_UART(void)		//初始化串口,12MHZ晶體,9600bps,使用定時器T1,8位自動重裝模式,串口模式1.
{
	PCON &= 0x7F;		
	SCON = 0x50;		
	AUXR |= 0x40;		
	AUXR &= 0xFE;		
	TMOD &= 0x0F;		
	TMOD |= 0x20;
	TL1 = 0xD9;		
	TH1 = 0xD9;		
	ET1 = 0;		
	TR1 = 1;
}

void UART_T_CHAR(uchar T_c)//該子程序?qū)崿F(xiàn)通過串口向上位機發(fā)送一個字符的功能
{
	SBUF=T_c;
	while(!TI);
	TI=0;
}

void UART_T_STRING(uchar *string)//該子程序?qū)崿F(xiàn)通過串口向上位機發(fā)送字符串的功能。
{
	TI=1;
	puts(string);
	while(!TI);
	TI=0;
}


程序就是以上了,因為現(xiàn)在處于測試18B20驅(qū)動是否正常的階段,一些代碼是臨時加上去的,為了測試之用。
問題就是,串口助手收到的數(shù)值是-24577,而且不隨溫度變化,弄了一天,還是不知道怎么回事,我甚至都以為自己買成三極管了。希望各路大神幫忙看一下。
順便手畫一下DS18B20與單片機的連接

IMG_20140724_183008

全部回復(fù)(3)
正序查看
倒序查看
2014-07-29 11:35
看看你的晶振,還有單片機設(shè)置的是1T工作模式還是6T  還是12T模式。
0
回復(fù)
2014-12-25 14:20
@yueyunno1
看看你的晶振,還有單片機設(shè)置的是1T工作模式還是6T 還是12T模式。
正解,你如果用89C52的片子應(yīng)該更好做
0
回復(fù)
45280
LV.4
4
2015-05-03 13:13
18B20 對時間要求比較高,應(yīng)該是延時的問題,亂糟糟的我也沒怎么看。


void Init_DS18B20(void)           //初始化18B20
{
	unsigned char x=0;
	DQ = 1;    
	Delay(8);  
	DQ = 0;    
	Delay(80);  
	DQ = 1;    
	Delay(14);
	x=DQ;      
	Delay(20);
}
這里面的變量x有什么用? 純屬吃飽了撐的,多余!
如果是要檢測初始化是否成功的話,那么就少了一句 return(x); 
還要把函數(shù)名改為 bit Init_DS18B20() 或者 unsigned char Init_DS18B20()
不需要檢測的話,那個變量x就是多余的。
下面我說下我個人的經(jīng)驗,
DS18B20 延時比較多,轉(zhuǎn)換一次需要零點幾秒,
很多空延時,效率很低。
如果寫成像書本里面那樣用在主函數(shù)里調(diào)用的話是不太穩(wěn)妥的,
因為一個稍大點完整的程序會有很多各種中斷,就好比初始化延時的時候,被中斷了,
轉(zhuǎn)去執(zhí)行中斷里面的程序,完了之后返回原來的地方,但是已經(jīng)超時了,初始化就失敗了;
如果是在發(fā)送或者接收數(shù)據(jù)的話,就會出現(xiàn)數(shù)據(jù)錯誤,如果產(chǎn)品是通過溫度來控制外部其他部件的話,就會出現(xiàn)誤動作。
其實18B20,還有另一種更為效率的程序,只不過,真正實用的東西是不會出現(xiàn)在書本上的。
再舉個例子,比如按鍵掃描,書本上都是這么寫的,while(!KEY);等待按鍵釋放。
這在實際中是不現(xiàn)實的。如果一個產(chǎn)品設(shè)計成這樣,會出現(xiàn)很多問題,如果按著按鍵不放,或者按鍵出現(xiàn)故障導(dǎo)致一直出現(xiàn)低電平,
那么程序?qū)⑦M入死循環(huán)。。  實際使用中一般不會用這種方法的。
還是那句話,真正實用的東西一般不會出現(xiàn)在書本上的,就像教科書里扶老奶奶過馬路一個吊樣,你去扶一個試試……
以上純屬個人觀點。
0
回復(fù)
發(fā)
主站蜘蛛池模板: 日韩久久精品 | 国产成人AV大片在线播放 | 日韩精品免费一区二区三区竹菊 | xxx2高清在线观看免费视频 | 亚洲精品乱码久久久久久不卡 | 久久不射2019中文字幕 | 午夜无毒不卡 | 秀人网妲己xiurenwang.cc | 麻豆精品视频在线播放 | 国产JIZZ中国JIZZ免费看 | 永久免费黄色 | 欧美精品二区中文乱码字幕高清 | 精品一二三四五区 | A片无码国产精品性BBV | 又色又爽视频 | 亚洲色图狠狠爱 | 欧美金8天国| 中文字幕无码乱码人妻系列蜜桃 | 中出国产 | 人妻系列无码专区无码专区 | 亚洲久av| 亚洲第一天堂影院 | 好男人中文资源在线观看 | 国产一区二区三区四区成男人 | 国内精品久久久久影院优 | 免费看国产一级特黄aaaa大片 | 少妇大叫又粗又大太爽A片 heyzo朝桐光一区二区 | 无码精品人妻免费 | 五十度灰2在线观看 | 好男人2019视频社区 | 一女多男两根同时进去性视频 | 伊人久久综合一区二区 | 成人性生交大片免费看中文 | 久久99精品国产麻豆婷婷小说 | 精品一区二区三区四区蜜桃 | 农田丰满艳肉妇hd | 亚洲精品免费在线观看视频 | 人人射人人 | av第一福利网站 | 操操综合网 | 黄色免费在线观看网站 |