![]() |
發(fā)布時間: 2019-4-22 11:06
正文摘要:我是用DS18B20傳感器檢測溫度的,然后用數(shù)碼管把它顯示出來,但是數(shù)碼管顯示的數(shù)值一直是00000006固定不變,數(shù)碼管代碼好像也沒啥問題,讓它顯示87654321這些固定值也可以顯示出來,請大佬幫幫忙 |
初學(xué)不要直接去寫,在開發(fā)板里小小修改一下,等熟透了再去寫,這樣才是對的。 |
直接貼程序不好嗎?還方便一些嘛。 給你一個例程: main.c #include<reg51.h> #include"DS18B20.h" #define SMG P0//數(shù)碼管IO sbit LSA=P2^2;//138譯碼器 sbit LSB=P2^3; sbit LSC=P2^4; unsigned char code ZF[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//要顯示的數(shù)字 unsigned int XS[5]={0x3f,0x3f,0x3f,0x3f,0x3f};//顯示緩存 void FZ(int temp)//給數(shù)碼管顯示緩存放入數(shù)據(jù) { float tp;//要進(jìn)行帶符號的小數(shù)運算,必須用有符號實型數(shù)據(jù),32位 if(temp< 0)//當(dāng)溫度值為負(fù)數(shù) { XS[0] = 0x40;//顯示負(fù)號- temp=temp-1;//因為讀取的溫度是實際溫度的補碼,所以減1,再取反求出原碼 temp=~temp; tp=temp; temp=tp*0.0625*100+0.5;//留兩個小數(shù)點就*100,+0.5是四舍五入,因為C語言浮點數(shù) //轉(zhuǎn)換為整型的時候把小數(shù)點后面的數(shù)自動去掉,不管是否 //大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就 //算加上.5,還是在小數(shù)點后面。 } else { XS[0] = 0x70;//正數(shù)就顯示┣ tp=temp; temp=tp*0.0625*100+0.5; } XS[1] = ZF[temp % 10000 / 1000]; XS[2] = ZF[temp % 1000 / 100] + 0x80;//顯示小數(shù)點 XS[3] = ZF[temp % 100 / 10]; XS[4] = ZF[temp % 10 / 1]; } void DISPLAY() { LSC=1;LSB=0;LSA=0;//溫度正負(fù)號 SMG=XS[0]; Delay1ms(1); SMG=0x00; LSC=0;LSB=1;LSA=1;//溫度的十位 SMG=XS[1]; Delay1ms(1); SMG=0x00; LSC=0;LSB=1;LSA=0;//溫度的個位帶小數(shù)點 SMG=XS[2]; Delay1ms(1); SMG=0x00; LSC=0;LSB=0;LSA=1;//溫度的小數(shù)點后第一位 SMG=XS[3]; Delay1ms(1); SMG=0x00; LSC=0;LSB=0;LSA=0;//溫度的小數(shù)點后第二位 SMG=XS[4]; Delay1ms(1); SMG=0x00; } void main() { while(1) { FZ(Ds18b20ReadTemp());//讀取溫度值并對顯示緩存賦值 DISPLAY();//數(shù)碼管顯示 } } DS18B20.c #include"DS18B20.h" void Delay1ms(unsigned int y)//延時yms { unsigned int x; for(y;y>0;y--) for(x=110;x>0;x--); } unsigned char Ds18b20Init()//初始化 { unsigned int i; DSPORT=0;//將總線拉低480us~960us i=70; while(i--);//延時642us DSPORT=1;//然后拉高總線,如果DS18B20做出反應(yīng)會將在15us~60us后總線拉低 i=0; while(DSPORT)//等待DS18B20拉低總線 { i++; if(i>1000)//等待>1MS { return 0;//初始化失敗 } } return 1;//初始化成功 } void Ds18b20WriteByte(unsigned char dat)//向18B20寫入一個字節(jié) { unsigned int i,j; for(j=0;j<8;j++) { DSPORT=0;//每寫入一位數(shù)據(jù)之前先把總線拉低1us i++; DSPORT=dat&0x01;//然后寫入一個數(shù)據(jù),從最低位開始 i=6; while(i--);//延時68us,持續(xù)時間最少60us DSPORT=1;//然后釋放總線,至少1us給總線恢復(fù)時間才能接著寫入第二個數(shù)值 dat>>=1; } } unsigned char Ds18b20ReadByte()//從DS18B20讀取一個字節(jié) { unsigned char byte,bi; unsigned int i,j; for(j=8;j>0;j--) { DSPORT=0;//先將總線拉低1us i++; DSPORT=1;//然后釋放總線 i++; i++;//延時6us等待數(shù)據(jù)穩(wěn)定 bi=DSPORT;//讀取數(shù)據(jù),從最低位開始讀取 byte=(byte>>1)|(bi<<7); i=4;//讀取完之后等待48us再接著讀取下一個數(shù) while(i--); } return byte; } void Ds18b20ChangTemp()//向DS18B20發(fā)送溫度轉(zhuǎn)換命令 { Ds18b20Init(); Delay1ms(1); Ds18b20WriteByte(0xcc);//跳過ROM操作命令 Ds18b20WriteByte(0x44);//溫度轉(zhuǎn)換命令 } void Ds18b20ReadTempCom()//發(fā)送讀取溫度命令 { Ds18b20Init(); Delay1ms(1); Ds18b20WriteByte(0xcc);//跳過ROM操作命令 Ds18b20WriteByte(0xbe);//發(fā)送讀取溫度命令 } int Ds18b20ReadTemp()//讀取溫度 { int temp=0; unsigned char tmh,tml; Ds18b20ChangTemp();//先寫入轉(zhuǎn)換命令 Ds18b20ReadTempCom();//然后等待轉(zhuǎn)換完后發(fā)送讀取溫度命令 tml=Ds18b20ReadByte();//讀取溫度值共16位,先讀低字節(jié) tmh=Ds18b20ReadByte();//再讀高字節(jié) temp=tmh;//把兩次得到的8位數(shù)據(jù),合并為16位實際數(shù)據(jù) temp<<=8; temp|=tml; return temp;//溫度的英文單詞temperature } DS18B20.h #ifndef __TEMP_H_ #define __TEMP_H_ #include<reg51.h> sbit DSPORT=P3^7; void Delay1ms(unsigned int ); unsigned char Ds18b20Init(); void Ds18b20WriteByte(unsigned char com); unsigned char Ds18b20ReadByte(); void Ds18b20ChangTemp(); void Ds18b20ReadTempCom(); int Ds18b20ReadTemp(); #endif 程序適用的電路: ![]() ![]() ![]() |
如果你用protues上的ds18b20,你檢查的ds18b20的時序, 之前我也存在這個問題 |
檢查下單片機讀DS18B20傳感器的時序機延時是否有問題 |
應(yīng)與顯示無關(guān),與DS18b20讀出數(shù)據(jù)有關(guān),可能沒有讀出,tp=0是初始值。 |
Powered by 單片機教程網(wǎng)