|
昨天自己寫了一個(gè)DS18B20的程序,能正常運(yùn)行,發(fā)到51黑論壇上分享給和我一樣的新手朋友們。
通過DS18B20采集環(huán)境溫度,并在開發(fā)板的數(shù)碼管模塊上的左三位顯示(帶1位小數(shù))。
MCU:AT89S52
源碼:
#include <reg52.h>
sbit DS=P2^2;
sbit DU=P2^6;
sbit WE=P2^7;
unsigned char table0[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //無小數(shù)點(diǎn)
unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //有小數(shù)點(diǎn)
unsigned int temp;
void Delay(unsigned int x) //延時(shí)一定時(shí)間
{
unsigned int i;
while(x)
{
i=200;
while(i>0)
{
i--;
}
x--;
}
}
void DS18B20_init() //DS18B20初始化
{
unsigned int i;
DS=0; //MCU拉低電平最少480us,產(chǎn)生復(fù)位脈沖,然后釋放總線
i=103; //延時(shí)480us~960us
while(i>0)
{
i--;
}
DS=1; //釋放總線
i=4; //等待15~60us,然后DS18B20拉低電平60~240us表示應(yīng)答
while(i>0)
{
i--;
}
while(DS);
}
bit Read_bit() //讀取1比特的數(shù)據(jù);“讀”時(shí)序最少需要60us
{
unsigned int i;
bit dat;
DS=0;
i++; //拉低電平最少1us,然后再釋放總線
DS=1;
i++; //等待一定時(shí)間后,再讀取電平狀態(tài)
i++;
dat=DS;
i=8;
while(i>0)
{
i--; //等待最少60us
}
return dat;
}
unsigned char Read_byte() //讀取1字節(jié)的數(shù)據(jù)
{
unsigned char i,j;
unsigned char dat=0;
for(i=1;i<=8;i++)
{
j=Read_bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
void Write_byte(unsigned char dat) //往DS18B20中寫入1字節(jié)的數(shù)據(jù)
{
unsigned int i;
unsigned char j;
bit x;
for(j=1;j<=8;j++)
{
x=dat&0x01; //依次將dat的每一位賦值給x
dat=dat>>1;
if(x) //寫入“1”
{
DS=0; //拉低電平大于1us,在15us內(nèi)拉高電平
i++;
i++;
DS=1; //“寫”時(shí)序起始后的15~60us內(nèi),DS18B20處于采樣狀態(tài),在此期間,若總線為高電平,則表示“1”
i=8;
while(i>0)
{
i--; //等待最少60us
}
}
else //寫入“0”;拉低電平60~120us,然后釋放總線
{
DS=0;
i=8;
while(i>0) //最少60us
{
i--;
}
DS=1;
}
}
}
void Change(void) //溫度轉(zhuǎn)換,即測(cè)量溫度
{
DS18B20_init();
Delay(1);
Write_byte(0xcc); //“跳過ROM”操作
Write_byte(0x44); //“溫度轉(zhuǎn)換”操作
}
unsigned int GET() //獲取溫度數(shù)據(jù)
{
float x;
unsigned char a,b;
DS18B20_init();
Delay(1);
Write_byte(0xcc);
Write_byte(0xbe); //讀取DS18B20內(nèi)的RAM的內(nèi)容
a=Read_byte(); //讀取溫度值的低8位
b=Read_byte(); //讀取溫度值的高8位
temp=b;
temp<<=8;
temp=temp|a;
x=temp*0.0625; //DS18B20默認(rèn)設(shè)置為12位分辨率,即表示分辨率為0.0625攝氏度
temp=x*10+0.5;
return temp;
}
void OUTPUT(unsigned int temp) //數(shù)碼管顯示
{
unsigned char x0,x1,y,x2;
x0=temp/100;
y=temp%100;
x1=y/10;
x2=y%10;
DU=0;
P0=table0[x0]; //顯示溫度值的十位
DU=1;
DU=0;
WE=0;
P0=0xfe;
WE=1;
WE=0;
Delay(1);
DU=0;
P0=table1[x1]; //顯示溫度值的個(gè)位
DU=1;
DU=0;
WE=0;
P0=0xfd;
WE=1;
WE=0;
Delay(1);
P0=table0[x2]; //顯示溫度值的十分位
DU=1;
DU=0;
P0=0xfb;
WE=1;
WE=0;
Delay(1);
}
void main()
{
while(1)
{
Change();
OUTPUT(GET());
}
}
|
評(píng)分
-
查看全部評(píng)分
|