一、程序设计
编程思路:首先单片机通过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;
}
}