#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit dq=P1^3;
sbit wela=P2^7;
sbit dula=P2^6;
//定義整型的溫度數據
//float f_temp;//定義浮點型型的溫度數據
uchar code table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar shi,ge;
uchar temp;
void delay(uint k)
{
uint x,y;
for(x=k;x>0;x--)
for(y=110;y>0;y--);
}
void init_ds()//ds18b20復位,初始化函數
{
uchar dat;
uchar k;
dq=1;
k=2;
while(k>0)k--;
dq=0;//將數據線拉低
k=80;//延時范圍在480~960us之間
while(k>0)k--;
dq=1;//再次拉高
k=2; //15~60us后接收60~240us的存在脈沖
while(k>0)k--;
dat=dq;//如果dq=0則說明有期間響應即溫度傳感器是好的,dq=1則說明溫度傳感器是壞的
k=1;//稍作延時返回
while(k>0)k--;
}
uchar readonechar(void)//讀一個字節
{
uchar k;
uchar j;
uchar dat;
dq=1;
k=2;
while(k>0)k--;
for(j=8;j>0;j--)//一個字節分八位讀取
{
dq=0;//拉低dq總線開始讀取時序
dat>>=1;//右移一位后的值
dq=1;//拉高,為單片機檢測ds18b20的輸出電平做準備
k=2; //使主機在15us中采樣
while(k>0)k--;
if(dq)//讀取一位數據 即采樣
dat=dat|0x80;//如果讀到的數據是1,則將1存入dat,如果是0則保持原數據不變
k=1; //兩個讀時序之前必須有大于1us的恢復期
while(k>0)k--;
}
return (dat);
}
void writeonechar(uchar dat)//寫一個字節
{
uchar k;
uchar j;
for(j=8;j>0;j--)//一個字節分八位讀取
{
dq=0;//將數據從高拉低時即啟動寫時序
dq=dat&0x01;//判定1或0
k=8;//寫0時序時,單總線要被拉低至少60us
while(k>0)k--;
dq=1;
dat>>=1;//將dat數據中的各二進制位數據右移1位
}
k=2;
while(k>0)k--;
}
uchar read_temperature(void)//讀取溫度
{
uchar k;
uchar a=0;
uchar b=0;
uchar t=0;
uchar tt;
init_ds();
writeonechar(0xcc);//跳過讀序號列號的操作
writeonechar(0x44);//啟動溫度轉換
k=10;
while(k>0)k--;
init_ds();
writeonechar(0xcc);//跳過讀序號列號的操作
writeonechar(0xbe);//讀取溫度寄存器(共可讀九個寄存器)前兩個分別是溫度的高位和低位
k=10;
while(k>0)k--;
a=readonechar();//讀取溫度值低位
b=readonechar();//讀取溫度值高位
t=b;
t<<=4;
t|=(a&0xf0)>>4;
tt=t*0.0625;
t=tt*10+0.5;
return tt;//將數據都放b里面
}
void display_ds(void)
{
dula=1;
P0=table[temp/10];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(5);
dula=1;
P0=table[temp%10];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(5);
}
void init()
{
TMOD|=0x20;// 初始化定時器1為8位自動重裝模式
SCON=0x50;// 配置串口工作模式,使能了串口接收中斷
TH1=0xfd;// 配置波特率
TL1=0xfd;
TR1=1;// 啟動定時器1
ES=1;// 打開串口中斷允許
TI=1;
}
void main()
{
init();
while(1)
{
temp=read_temperature();
display_ds();
}
}
|