先貼上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與單片機的連接