2路DS18B20控制
扫描二维码
随时随地手机看文章
最近了解了一下DS18B20的控制原理...就制作了一个二路的可调温度控制器...
本来想在一根IO上实现这个温度的读取,但是那样时间太长了...就利用二个IO接二个18B20...对二个同时进行读写操作...经过实践是可行的...
这里面用按键+1820+LCD1602完成一个二路的温度控制...并且可以利用程序对P26 P27的负载进行控制,在这里用来控制二个LED...大家也可以加上三极管扩上继电器...
下面是这个的原理图...
本文中程序可以直接调用,单片机为STC89C52,晶振为11.0592M...
本文的程序太长了,所以只发18B20的部分...其它的部分大家可以自己去实现...
//////////////////////////////////////////////////////DS18B20.h
#ifndef __DS18B20_H__
#define __DS18B20_H__
#include
#include"Mytype.h"
#include
#include "Display_KEY_Out.H"
#define nop() _nop_()
#define READ_ROM 0x33 //读ROM
#define MATCH_ROM 0x55 //匹配ROM
#define SKIP_ROM 0xCC //跳过ROM
#define SEARCH_ROM 0xF0 //搜索ROM
#define ALARM_ROM 0xEC //警告ROM
#define WRITE_SCRATCHPAD 0x4E //写暂存器
#define READ_SCRATCHPAD 0xBE //读暂存器
#define COPY_SCRATCHPAD 0x48 //复制暂存器
#define COVERTT 0x44 //温度转换开始
#define RECALLE2 0xB8 //重调用E2存储器
#define READ_P_SUPPLY 0xB4 //读供电方式
#define Bit_12 0x7F //12位精度
#define Bit_11 0x5F //11位精度
#define Bit_10 0x3F //10位精度
#define Bit_9 0x1F //9位精度
sbit DS_IO1 = P1^6; //DS18B20接口;
sbit DS_IO2 = P3^3;
extern int8 Temp1;
extern int8 Temp2;
bit Init_DS18B20(void);
void Write_DS_8Bit(uint8 Value);
void Read_DS_8Bit(void);
void Read_DS_Data(void);
void Delay_Us(uint8 Value);
void SetStep(uint8 Value);
#endif
//////////////////////////////////////////////////////DS18B20.C
#include "DS18B20.h"
bit DS18B20_TRUE1 = 0;
bit DS18B20_TRUE2 = 0;
bit Temp_Z1 = 0;
bit Temp_Z2 = 0;
uint8 T_Value1 = 0;
uint8 T_Value2 = 0;
////////////////////////////////////////////////////////////////////////////////
//函数名:PD_DS18B20(void)
//功能描述:检测DS18B20是否接于总线上;
//函数说明:
//调用函数:无;
//全局变量:无;
//输入:无;
//返回:无;
//修改者:
//创建日期:2009-07-15
//版本:v1.0
////////////////////////////////////////////////////////////////////////////////
bit Init_DS18B20(void)
{
uint8 i = 250;
bit Value1 = 0;
bit Value2 = 0;
EA = 0;
DS_IO1 = 1;
DS_IO2 = 1;
DS_IO1 = 0;
DS_IO2 = 0;
Delay_Us(250); //延时600US;
DS_IO1 = 1; //松开总线;
DS_IO2 = 1; //松开总线;
while(((DS_IO1 == 1) || (DS_IO2 == 1)) && ( --i)); //等侍DS18B20反馈信号;
Value1 = DS_IO1; //读取返回信号;
Value2 = DS_IO2;
DS_IO1 = 1; //松开总线;
DS_IO2 = 1; //松开总线;
if((Value1 && Value2) == 0) //如果检测到DS18B20;
{
if(Value1 == 0)
{
DS18B20_TRUE1 = 1;
}
else
{
DS18B20_TRUE1 = 0;
}
if(Value2 == 0)
{
DS18B20_TRUE2 = 1;
}
else
{
DS18B20_TRUE2 = 0;
}
Delay_Us(100); //延时240US;
}
EA = 1;
return (Value1 && Value2); //返回DS18B20有无信号;有则返回0,无则返回1;
}
////////////////////////////////////////////////////////////////////////////////
//函数名:void Write_DS_8Bit(uint8 Value)
//功能描述:向DS18B20写入8位数据,先写最低位;
//函数说明:
//调用函数:无;
//全局变量:无;
//输入:VALUE数据为8位;
//返回:无;
//创建日期:2009-07-15
//版本:v1.0
////////////////////////////////////////////////////////////////////////////////
void Write_DS_8Bit(uint8 Value) //向DS18B20内部写入数据;
{
uint8 i = 0;
EA = 0;
for(i = 0;i < 8; i ++) //写8位数据;
{
DS_IO1 = 0; //先置IO为0;
DS_IO2 = 0; //先置IO为0;
Delay_Us(1); //延时15US;
DS_IO1 = Value & 0x01; //把数据送到18B20端口;
DS_IO2 = Value & 0x01; //把数据送到18B20端口;
Delay_Us(15); //延时40US
DS_IO1 = 1; //把IO口置1;
DS_IO2 = 1; //把IO口置1;
Value >>= 1;
} //数据送完,IO口置1;
EA = 1;
}
////////////////////////////////////////////////////////////////////////////////
//函数名:uint8 Read_DS_8Bit(void)
//功能描述:读出DS18B20内部数据,先读低位.读完后并返回数据;
//函数说明:
//调用函数:无;
//全局变量:无;
//输入:无
//返回:读出的8位数据;
//修改者:
//创建日期:2009-07-15
//版本:v1.0
////////////////////////////////////////////////////////////////////////////////
void Read_DS_8Bit(void) //读取DS18B20数据;
{
bit V1 = 0;
bit V2 = 0;
uint8 i = 0;
T_Value1 = 0;
T_Value2 = 0;
EA = 0;
for(i = 0; i < 8; i ++) //读8位数据;
{
DS_IO1 = 0; //IO口置0;
DS_IO2 = 0; //IO口置0;
Delay_Us(1); //延时10US;
DS_IO1 = 1; //IO口置1;
DS_IO2 = 1; //IO口置1;
V1 = DS_IO1;
V2 = DS_IO2;
if(V1 == 1)
{
T_Value1 |= (0x01 << i); //读取数据;
}
if(V2 == 1)
{
T_Value2 |= (0x01 << i); //读取数据;
}
Delay_Us(15); //延时30US;
DS_IO1 = 1; //IO口置1;
nop(); //短延时;
V1 = 0;
V2 = 0;
}
EA = 1;
}
////////////////////////////////////////////////////////////////////////////////
//函数名:void Read_DS_Data(void)
//功能描述:读出DS18B20内部数据,先读低位.读完后并返回数据;
//函数说明:
//调用函数:Init_DS18B20();复位DS18B20函数;
//调用函数:Write_DS_8Bit();写入数据函数;
//调用函数:Read_DS_8Bit();读取数据函数;
//全局变量:Temp1 温度变量1;
//全局变量:Temp2 温度变量2;
//输入:无
//返回:读出温度数据;
//修改者:
//创建日期:2009-07-15
//版本:v1.0
////////////////////////////////////////////////////////////////////////////////
void Read_DS_Data(void) //读取温度数据;
{
uint8 Data_H1 = 0; //温度数据高位保存变量;
uint8 Data_L1 = 0; //温度数据低位保存变量;
uint16 Temp_1 = 0;
uint8 Data_H2 = 0; //温度数据高位保存变量;
uint8 Data_L2 = 0; //温度数据低位保存变量;
uint16 Temp_2 = 0;
Init_DS18B20(); //判断DS18B20是否正常;
Write_DS_8Bit(SKIP_ROM); //写入跳过ROM;
Write_DS_8Bit(COVERTT); //温度转换开始;
Init_DS18B20(); //传感器复位;
Write_DS_8Bit(SKIP_ROM); //跳过ROM;
Write_DS_8Bit(READ_SCRATCHPAD); //读取温度值;
Read_DS_8Bit(); //读取温度低8位数据;
Data_L1 = T_Value1; //陬第一个传感器低8位数据;
Data_L2 = T_Value2; //取第二个传感器低8位数据;
Read_DS_8Bit(); //读取温度;
Data_H1 = T_Value1; //陬第一个传感器高8位数据;
Data_H2 = T_Value2; //取第二个传感器高8位数据;
Temp_1 = ((Temp_1 | Data_H1)<<8) | Data_L1; //取出温度值,合成一个16位数据;
Temp_Z1 = Temp_1 & 0x8000; //判断温度正负;
Temp1 = Temp_1 >> 4; //只取整数,移除小数位;
if(Temp_Z1 == 1) //判断温度的正负;
{
Temp1 *= -1; //温度为负在然来基础上乘-1;
}
Temp_2 = ((Temp_2 | Data_H2)<<8) | Data_L2; //取出温度值,合成一个16位数据;
Temp_Z2 = Temp_2 & 0x8000; //判断温度正负;
Temp2 = Temp_2 >> 4; //只取整数,移除小数位;
if(Temp_Z2 == 1) //判断温度的正负;
{
Temp2*= -1; //温度为负在然来基础上乘-1;
}
T_Value1 = 0; //清除临时变量;
T_Value2 = 0;
}
////////////////////////////////////////////////////////////////////////////////
//函数名:SetStep
//功能描述:18B20精度设置程序
//函数说明:可以输入1-7F来设置9-12位精度;
//调用函数:Init_DS18B20(); 1820初始化
//调用函数:Write_DS_8Bit(); 1820写数据
//调用函数:Read_DS_8Bit(); 1820读数据
//调用函数:Delay_Us(100); US级延时程序
//全局变量:无;
//输入: 精度设置十六进制数;
//返回:无;
//修改者:
//创建日期:2009-08-18
//版本:v1.0
////////////////////////////////////////////////////////////////////////////////
void SetStep(uint8 Value)
{
Init_DS18B20();
Write_DS_8Bit(SKIP_ROM);
Write_DS_8Bit(WRITE_SCRATCHPAD);
Write_DS_8Bit(0x15);
Write_DS_8Bit(0x00);
Write_DS_8Bit(Value);
Init_DS18B20();
Write_DS_8Bit(SKIP_ROM);
Write_DS_8Bit(READ_SCRATCHPAD);
Read_DS_8Bit();
Init_DS18B20();
Write_DS_8Bit(SKIP_ROM);
Write_DS_8Bit(COPY_SCRATCHPAD);
Delay_Us(100);
DS_IO1 = 1;
DS_IO2 = 1;
}
////////////////////////////////////////////////////////////////////////////////
//函数名:Delay_Us
//功能描述:US级延时程序;
//函数说明:12M晶振下默认的状态是10US.如果参数加1;
///////////////则延时再加上2uS
//调用函数:无;
//全局变量:无;
//输入:无;
//返回:无;
//创建日期:2009-08-18
//版本:v1.0
////////////////////////////////////////////////////////////////////////////////
void Delay_Us(uint8 Value)
{
while(-- Value);
}