|
|
昨天自己寫了一個DS18B20的程序,能正常運行,發到51黑論壇上分享給和我一樣的新手朋友們。
通過DS18B20采集環境溫度,并在開發板的數碼管模塊上的左三位顯示(帶1位小數)。
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}; //無小數點
unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //有小數點
unsigned int temp;
void Delay(unsigned int x) //延時一定時間
{
unsigned int i;
while(x)
{
i=200;
while(i>0)
{
i--;
}
x--;
}
}
void DS18B20_init() //DS18B20初始化
{
unsigned int i;
DS=0; //MCU拉低電平最少480us,產生復位脈沖,然后釋放總線
i=103; //延時480us~960us
while(i>0)
{
i--;
}
DS=1; //釋放總線
i=4; //等待15~60us,然后DS18B20拉低電平60~240us表示應答
while(i>0)
{
i--;
}
while(DS);
}
bit Read_bit() //讀取1比特的數據;“讀”時序最少需要60us
{
unsigned int i;
bit dat;
DS=0;
i++; //拉低電平最少1us,然后再釋放總線
DS=1;
i++; //等待一定時間后,再讀取電平狀態
i++;
dat=DS;
i=8;
while(i>0)
{
i--; //等待最少60us
}
return dat;
}
unsigned char Read_byte() //讀取1字節的數據
{
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字節的數據
{
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內拉高電平
i++;
i++;
DS=1; //“寫”時序起始后的15~60us內,DS18B20處于采樣狀態,在此期間,若總線為高電平,則表示“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) //溫度轉換,即測量溫度
{
DS18B20_init();
Delay(1);
Write_byte(0xcc); //“跳過ROM”操作
Write_byte(0x44); //“溫度轉換”操作
}
unsigned int GET() //獲取溫度數據
{
float x;
unsigned char a,b;
DS18B20_init();
Delay(1);
Write_byte(0xcc);
Write_byte(0xbe); //讀取DS18B20內的RAM的內容
a=Read_byte(); //讀取溫度值的低8位
b=Read_byte(); //讀取溫度值的高8位
temp=b;
temp<<=8;
temp=temp|a;
x=temp*0.0625; //DS18B20默認設置為12位分辨率,即表示分辨率為0.0625攝氏度
temp=x*10+0.5;
return temp;
}
void OUTPUT(unsigned int temp) //數碼管顯示
{
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]; //顯示溫度值的個位
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());
}
}
|
評分
-
查看全部評分
|