一、程序設計
編程思路:首先單片機通過I/O口調用初始化函數Init_DS18B20()對DS18B20按照初始化時序進行初始化,啟動溫度的轉換,再將轉換后的數字傳給單片機,單片機通過計算將數字溫度轉換成實際的溫度值,通過數碼管顯示出來,數碼管顯示采取在定時器0中動態顯示,P0端驅動共陽七段數碼管,P20~P25端通過非門接共陽數碼管的公共端,應用程序清單如下:
/*****************************************************************
程序描述:溫度超過35度,繼電器吸合
P0端驅動共陽七段數碼管,P2端接共陽數碼管的公共端
******************************************************************/
#include<reg51.h>
#defineuchar unsigned char
#defineuint unsigned int
sbitDQ = P1^0; //DS18B20的DQ和單片機的P10腳連接
sbitjdq = P2^6; //繼電器的控制端和單片機的P26腳連接
code uchar seven_seg[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
code uchar seven_bit[] = {0xfe,0xfd,0xfb,0x7f};
uchara,b,c,d,i,T;
/*******************延遲函數***************/
voiddelay(uint x)
{
while(x)
x--;
}
/**************初始化DS18B20函數***********/
Init_DS18B20(void)
{
unsigned char x = 0;
DQ = 1; //DQ復位
delay(8); //稍做延時
DQ = 0; //單片機將DQ拉低
delay(80); //精確延時 大于 480us
DQ = 1; //拉高總線
delay(14);
x = DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
delay(20);
}
/*******************從18B20中讀一個字節***************/
uchar read_OneChar(void)
{
uchar i = 0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat >>= 1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|= 0x80;
delay(4);
}
return(dat);
}
/**********************向18B20中寫一個字節**************/
void write_OneChar(uchar dat)
{
uchar i = 0;
for (i = 8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat >> =1;
}
delay(4);
}
/***********************讀取溫度*************************/
ucharRead_Temperature(void)
{
uchar i = 0,t = 0;
Init_DS18B20();
Write_OneChar(0xcc); // 跳過讀序號列號的操作
Write_OneChar(0x44); // 啟動溫度轉換
Init_DS18B20();
Write_OneChar(0xcc); //跳過讀序號列號的操作
Write_OneChar(0xbe); //讀取溫度寄存器等(共可讀9個寄存器)前兩個就是溫度
i =Read_OneChar(); //讀取溫度值低位
t =Read_OneChar(); //讀取溫度值高位
a = i & 0x0f;
b = t;
i = i >> 4; //低位右移4位,舍棄小數部分
t = t << 4; //高位左移4位,舍棄符號位
t = t | i;
return(t);
}
/*******************T0初始化函數***************/
voidtimer0_init(void)
{
TMOD = 0x01;
TH0 = (65536-5000)/256; //0xec;
TL0 = (65536-5000)%256; //0x78;
TR0 = 1;
EA = 1;
ET0 = 1;
}
/*****************中斷函數**********************/
voidtimer0_isr(void) interrupt 1
{
uchar j;
TR0 = 0;
EA = 0;
TH0 = 0xec;
TL0 = 0x78;
TR0 = 1;
EA = 1;
i++;
if(i == 200) //剛好1秒
{
T =Read_Temperature();
i = 0;
}
switch(j)
{
case 0:P0 =seven_seg[a*10/16];break;
case 1:P0 = 0x7f & seven_seg[T%10];break;
case 2:P0 = seven_seg[T/10];break;
case 3:if(b & 0x80 == 0x80)P0 =0xbf;break;
}
P2 = seven_bit[j];
j++;
if(j == 3) j=0;
}
voidmain(void)
{
Init_DS18B20();
timer0_init();
while(1)
{
if(T >= 35)jdq = 0;
else jdq = 1;
}
}