//程序適合單個DS18B20和MCS-51單片機的連接,晶振為12MHz
//測量的溫度范圍-55℃~+99℃,溫度精確到小數點后一位
#include <REG52.H>
#define uchar unsigned char
#define uint unsigned int
sbit DQ =P1^0; //定義端口
sbit RS=P1^7;
sbit RW=P1^6;
sbit EN=P1^5;
union{
uchar c[2];
uint x;
}temp;
uchar flag;//flag為溫度值的正負號標志單元, "1"表示為負值,"0"時表示為正值。
uint cc,cc2;//變量cc中保存讀出的溫度值
float cc1;
uchar buff1[13]={"temperature:"};
uchar buff2[6]={"+00.0"};
//檢查忙函數
void fbusy()
{
P2 = 0xff;
RS = 0;
RW = 1;
EN = 1;
EN = 0;
while((P2 & 0x80))
{
EN = 0;
EN = 1;
}
}
//寫命令函數
void wc51r(uchar j)
{
fbusy();
EN = 0;
RS = 0;
RW = 0;
EN = 1;
P2 = j;
EN = 0;
}
//寫數據函數
void wc51ddr(uchar j)
{
fbusy(); //讀狀態;
EN = 0;
RS = 1;
RW = 0;
EN = 1;
P2 = j;
EN = 0;
}
void init()
{
wc51r(0x01); //清屏
wc51r(0x38); //使用8位數據,顯示兩行,使用5*7的字型
wc51r(0x0c); //顯示器開,光標開,字符不閃爍
wc51r(0x06); //字符不動,光標自動右移一格
}
void delay(uint useconds) //延時程序
{
for(;useconds>0;useconds--);
}
uchar ow_reset(void) //復位
{
uchar presence;
DQ = 0; // DQ 低電平
delay(50); // 480ms
DQ = 1; // DQ 高電平
delay(3); // 等待
presence = DQ; // presence 信號
delay(25);
return(presence); // 0允許, 1禁止
}
uchar read_byte(void) //從單總線上讀取一個字節
{
uchar i;
uchar value = 0;
for (i=8;i>0;i--)
{
value>>=1;
DQ = 0;
DQ = 1;
delay(1);
if(DQ)value|=0x80;
delay(6);
}
return(value);
}
void write_byte(uchar val) //向單總線上寫一個字節
{
uchar i;
for (i=8; i>0; i--) // 一次寫一字節
{
DQ = 0;
DQ = val&0x01;
delay(5);
DQ = 1;
val=val/2;
}
delay(5);
}
void Read_Temperature(void) //讀取溫度
{
ow_reset();
write_byte(0xCC); // 跳過 ROM
write_byte(0xBE); // 讀
temp.c[1]=read_byte();
temp.c[0]=read_byte();
ow_reset();
write_byte(0xCC);
write_byte(0x44); // 開始
return;
}
void main() //主程序
{
uchar k;
delay(10);
EA=0;
flag=0;
init();
wc51r(0x80); //寫入顯示緩沖區起始地址為第1行第1列
for (k=0;k<13;k++) //第一行顯示提示信息"current temp is:"
{ wc51ddr(buff1[k]);}
while(1)
{
delay(10000);
Read_Temperature(); //讀取雙字節溫度
cc=temp.c[0]*256.0+temp.c[1];
if (temp.c[0]>0xf8) {flag=1;cc=~cc+1;}else flag=0;
cc1=cc*0.0625; //計算出溫度值
cc2=cc1*100; //放大100倍,放在整型變量中便于取數字
buff2[1]=cc2/1000+0x30;if ( buff2[1]==0x30) buff2[1]=0x20;//取出十位,轉換成字符,如果十位是0不顯示。
buff2[2]=cc2/100-(cc2/1000)*10+0x30;//取出個位,轉換成字符
buff2[4]=cc2/10-(cc2/100)*10+0x30;//取出小數點后一位,轉換成字符
if (flag==1) buff2[0]='-';else buff2[0]='+';
wc51r(0xc5); //寫入顯示緩沖區起始地址為第2行第6列
for (k=0;k<6;k++) //第二行顯示溫度
{ wc51ddr(buff2[k]);}
}
}
|