一、DS18B20温度传感器
DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。
主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
二、DS18B20常见封装
图1 DS18B20常见封装
图2 DS18B20不锈钢防水型实物图
其中,图1所示的是DS18B20常见的芯片图,可根据此图来判断模块引脚,而本项目中所使用的则是图2所示的温度传感器,以方便对加热装置进行检测。
三、DS18B20的驱动程序
1. 头文件
#ifndef _DS18B20_H_
#define _DS18B20_H_
#include <STC15F2K60S2.H>
#include <intrins.h>
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
/************18b20*************/
sbit DQ=P4^5;
extern uchar TPH,TPL,temp; //温度值及中间变量的变量声明
void DelayXus(uchar n);
void DS18B20_Reset();
uchar DS18B20_ReadByte();
void DS18B20_WriteByte(uchar dat1);
void DS18B20(); //使用时调用该函数即可
#endif
2. 主程序
#include "DS18B20.h"
void DelayXus(uchar n) //延时函数要根据单片机的时间周期来改写,一般控制在1-2us
{
while (n--);
{
_nop_();
_nop_();
}
}
/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
CY = 1;
while (CY)
{
DQ = 0; //送出低电平复位信号
DelayXus(240); //延时至少480us
DelayXus(240);
DQ = 1; //释放数据线
DelayXus(60); //等待60us
CY = DQ; //检测存在脉冲
DelayXus(240); //等待设备释放数据线
DelayXus(180);
}
}
/**************************************
从DS18B20读1字节数据
**************************************/
uchar DS18B20_ReadByte()
{
uchar i;
uchar dat1 = 0;
for (i=0; i<8; i++) //8位计数器
{
dat1 >>= 1;
DQ = 0; //开始时间片
DelayXus(1); //延时等待
DQ = 1; //准备接收
DelayXus(1); //接收延时
if (DQ) dat1 |= 0x80; //读取数据
DelayXus(60); //等待时间片结束
}
return dat1;
}
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(uchar dat1)
{
char i;
for (i=0; i<8; i++) //8位计数器
{
DQ = 0; //开始时间片
DelayXus(1); //延时等待
dat1 >>= 1; //送出数据
DQ = CY;
DelayXus(60); //等待时间片结束
DQ = 1; //恢复数据线
DelayXus(1); //恢复延时
}
}
/**************************************
向DS18B20读取温度数据并转换
**************************************/
void DS18B20()
{
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0x44); //开始转换命令
while (!DQ); //等待转换完成
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0xBE); //读暂存存储器命令
TPL = DS18B20_ReadByte(); //读温度低字节
TPH = DS18B20_ReadByte(); //读温度高字节
temp=(TPL+TPH*256)*0.0625;
}
3. 使用说明
该程序基于STC15F2K60S2单片机,如果需要在其他的单片机上使用,需要将引用的头文件、引脚定义以及延时函数进行更改即可。若有其他需求,自行修改。
四、温度值传送到USART HMI上显示
1.前期准备
首先要做好USART HMI的显示界面,本项目的显示界面如图3所示。所用到的控件为右边当前温度值,该控件对应的是文本框t6,发送的指令格式为:
字符串+结束符:t6.txt=”温度值” FF FF FF (三个FF的十六进制数)
例如发送温度值50℃,发送的指令为:t6.txt=”50”FFFFFF
图3 USART HMI显示界面
2.部分程序
(1)数据发送程序
uchar a=0,b=0,c=0,d=0,e=0,f=0;
/**********显示温度**********/
a = CODE[temp/10]; //温度十位数值
b = CODE[temp%10]; //温度个位数值
c = CODE[temp_target/10]; //目标温度十位数值
d = CODE[temp_target%10]; //目标温度个位数值
write_txt("t6.txt="); //发送文本
write_COM(34); //双引号
write_COM(a);
write_COM(b);
write_COM(34); //双引号
write_END(); //结束符
(2)单片机串口通信部分程序
①头文件
#ifndef _UART_H_
#define _UART_H_
#include <STC15F2K60S2.H>
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
extern uchar pageflag1; //返回页面ID的标志1
extern uchar pageflag2; //返回页面ID的标志2
extern uchar pageflag_ID; //返回页面ID的标志3
extern uchar page_end; //页面结束数据检测,满3代表结束
extern uchar pageID; //页面ID号
void write_COM(uchar COM);
void write_txt(char *s);
void write_END(void);
void UART_Init();
#endif
②主程序
#include "UART.h"
/*********串口送数据**********/
void write_COM(uchar COM)
{
SBUF=COM;
while(!TI);
TI=0;
}
/*********发送文本串**********/
void write_txt(char *s)
{
int i=0;
while(s[i]!=0)
{
write_COM(s[i]);
i++;
}
}
/*********发送结束符**********/
void write_END(void)
{
write_COM(0xFF);
write_COM(0xFF);
write_COM(0xFF);
}
/*********串口初始化**********/
void UART_Init()
{
//串口1 初始化
SCON = 0x50;
// P_SW1 &= 0x7f;
// P_SW1 |= 0x40;//uart1切换到P3^6\P3^7
AUXR &= 0xBE;
AUXR |= 0x00;
TMOD &= 0x0F;
TMOD |= 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1; //定时器1启动
ES = 1; //开放串口中断
EA = 1;
// //串口2 初始化
// S2CON = 0x10;
// T2L = 0xE8;
// T2H = 0xFF;
// AUXR &= 0xE3;
// AUXR |= 0x10;
// IE2 &= 0xFE;
// IE2 |= 0x01;
}
/************UART1 中断服务程序*******************/
void Uart1(void) interrupt 4
{
uchar dataflag=0;//返回的十六进制数据的第一位
ES = 0; //暂时关闭串口中断
if(RI) //如果是接收中断
{
RI=0;
dataflag = SBUF; //将接收缓冲区的数据保存到dataflag变量中
/***********页面接收**********/
if(dataflag == 0x66) pageflag1 = 1; //正在接收页面ID数据
if(pageflag1 == 1)
{
pageflag2++;
if(pageflag2 == 2)
{
pageflag_ID = dataflag;//接收页面ID号
}
if(dataflag == 0xff) //开始接收结束符
{
page_end++;
if(page_end == 3) //接收3个结束符,数据接收完成
{
pageID = pageflag_ID;
pageflag1 = 0;
pageflag2 = 0;
pageflag_ID = 0;
page_end = 0;
}
}
}
}
else //如果是发送中断,将TI清0
TI = 0;
ES = 1; //打开串口中断
}
注:串口中断函数里对页面ID的程序接收还存在一些问题,后期修改完毕再对此进行更正。