精品国产一区在线_av无码中文字幕无码王_天海翼三点刺激高潮不停_好硬好大好爽视频_欧美高清一区三区在线专区_香蕉黄色片

  • 回復
  • 收藏
  • 點贊
  • 分享
  • 發新帖

求助DS18B20讀不出正確的數據

先貼上DS18B20的驅動,這個我是照著書抄的,可以確定沒抄錯,因為是初學所以想先用現成的。

下面的程序是DS18B20.c里的代碼,是用來驅動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讀取一個字節
{
	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寫入一個字節
{
	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";         //存儲當前溫度的字符數組
	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行是將數值型溫度數據轉換為對應的字符數組,因為現在在測試
		UART_T_STRING(string);                                      //這個程序,暫未使用
		//UART_T_STRING(temp_char);                           //此語句也暫未使用
		TI=1;                                                                  //從此行起到TI=0;是為了測試DS18B20的驅動是否工作正常而臨時加入的
		printf("%d\n",tempr);                                         //用printf函數將tempr的數值發送到上位機,如果DS18B20驅動正常,ze
		while(!TI);                                                           //上位機可收到數值,給18B20加溫,數值會變化。
		TI=0;
		delayms(5000);
	}
}

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

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

#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)//該子程序實現通過串口向上位機發送一個字符的功能
{
	SBUF=T_c;
	while(!TI);
	TI=0;
}

void UART_T_STRING(uchar *string)//該子程序實現通過串口向上位機發送字符串的功能。
{
	TI=1;
	puts(string);
	while(!TI);
	TI=0;
}


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

IMG_20140724_183008

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


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); 
還要把函數名改為 bit Init_DS18B20() 或者 unsigned char Init_DS18B20()
不需要檢測的話,那個變量x就是多余的。
下面我說下我個人的經驗,
DS18B20 延時比較多,轉換一次需要零點幾秒,
很多空延時,效率很低。
如果寫成像書本里面那樣用在主函數里調用的話是不太穩妥的,
因為一個稍大點完整的程序會有很多各種中斷,就好比初始化延時的時候,被中斷了,
轉去執行中斷里面的程序,完了之后返回原來的地方,但是已經超時了,初始化就失敗了;
如果是在發送或者接收數據的話,就會出現數據錯誤,如果產品是通過溫度來控制外部其他部件的話,就會出現誤動作。
其實18B20,還有另一種更為效率的程序,只不過,真正實用的東西是不會出現在書本上的。
再舉個例子,比如按鍵掃描,書本上都是這么寫的,while(!KEY);等待按鍵釋放。
這在實際中是不現實的。如果一個產品設計成這樣,會出現很多問題,如果按著按鍵不放,或者按鍵出現故障導致一直出現低電平,
那么程序將進入死循環。。  實際使用中一般不會用這種方法的。
還是那句話,真正實用的東西一般不會出現在書本上的,就像教科書里扶老奶奶過馬路一個吊樣,你去扶一個試試……
以上純屬個人觀點。
0
回復
主站蜘蛛池模板: 亚洲精品免费网站 | 日韩成人黄色av | 欧美精品三级 | 亚洲一二在线 | 一区二区三区精品在线视频 | 办公室吃秘书奶水 | 国产精品国产自线拍免费软件 | 歪歪羞羞嘿咻汗汗av禁漫天堂 | 国产视频一区二区欧美日韩 | 精品国产va久久久久久久 | av免费播放一区二区三区 | 中文字幕日韩欧美一区二区三区 | 亚洲一区二区三区四区在线字幕 | 无码精品A∨在线观看无广告 | 脱了内裤猛烈进入A片费 | 成人AV片无码免费天天看 | 影视大全在线观看免费观看高清版 | 男女做性免费网站 | 国产一区二区精品久久岳 | 小片片在线免费观看 | 91一区二区三区视频 | 国产精品资源一区二区三区 | 再灬再灬再灬深一点舒服视频 | 欧美一级视频在线观看 | 国产精品淫片 | 人人妻人人添人人爽欧美一区 | 色婷婷久久一区二区三区麻豆 | 亚洲操比| 亚洲乱码国产 | 亚洲av日韩av永久无码不卡 | 免费观看男女性高视频 | 国产精品嫩草影院ccm | 精品免费视频一区二区 | 真人作爱视频免费 | 国产盗摄一区二区三区在线 | 白丝美女被操黄色视频国产免费 | 国产精品线路一 | 污视频在线免费观看网站 | 人妻熟妇AV水蜜桃一区二区三区 | 国产下药迷倒白嫩丰满美女j9 | 久久婷婷一级淫片aaa谢语彤 |