蓝桥杯单片机_DS18B20温度传感器的使用


一、DS18B20传感器相关

1.单总线温度传感器DS18B20简介

DS18B20是美国DALLAS公司生产的数字温度传感器,体积小、低功耗、抗干扰能力强。可直接将温度转化成数字信号传送给单片机处理,因而可省去传统的信号放大、A/D转换等外围电路。
DS18B20测量温度范围-55~+128℃,在-10~+ 85℃范围内,测量精度可达士0.5℃,非常适合于恶劣环境的现场温度测量,也可用于各种狭小空间内设备的测温,如环境控制、过程监测过程监测、测温类消费电子产品以及多点温度测控系统。

2.DS18B20的内部存储结构

DS18B20的内部有64位的ROM单元和9字节的高速暂存器RAM单元。64位ROM单元包含了DS18B20唯一的序列号。

9字节高速暂存器RAM单元

其中9个字节具体分布如下:
在这里插入图片描述
第1字节和第2字节是在单片机发给DS18B20温度转换命令发布后,经转换所得的温度值,以两字节补码形式存放其中。
一般情况下,用户多使用第1字节和第2字节。单片机通过单总线可读得该数据,读取时低位在前,高位在后。
第3、4字节分别是由软件写入用户报警的上下限值TH和TL。
第5个字节为配置寄存器,可对其更改DS18B20的测温分辨率。
高速暂存器的第6、7、8字节未用,为全1。
第9字节是前面所有8个字节的CRC码,用来保证正确通信。

3.DS18B20的温度数据处理

数据手册中给出的储存格式:
在这里插入图片描述
其中DS18B20以16位带符号位扩展的二进制补码形式读出。
低4位为小数部分,中间7位为整数部分。
高5位为扩展符号位,即BIT15~BIT11为00000,读出的数据为正温度,若为11111,则为负温度。在应用开发中,首先要对读出的温度数据的符号位进行判断,再根据正负温度的不同,进行相应的处理。

在这里插入图片描述
在上电复位的时候,温度寄存器中的值为0x0550,即+85摄氏度。
从输出数据与温度值的关系表中可知,DS18B20的分辨率为0.0625。
读出数据为正温度时,将LSB和MSB整合成的16位整数,直接乘以0.0625即可。

读出数据为负温度时,则需要将LSB和MSB整合成的16位整数,取反加1后,再乘以0.0625,因为温度数据是以补码形式表示的。

二、DS18B20的工作时序

DS18B20对工作时序要求严格,延时时间需准确,否则容易出错。DS18B20的工作时序包括初始化时序、写时序和读时序。

1.初始化时序:

单片机将数据线电平拉低480-960us后释放,等待15-60us,单总线器件即可输出一持续60~240us的低电平,单片机收到此应答后即可进行操作。

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12*12);
  	DQ = 0;
  	Delay_OneWire(80*12);
  	DQ = 1;
  	Delay_OneWire(10*12); 
    initflag = DQ;     
  	Delay_OneWire(5*12);
  
  	return initflag;
}

2.写时序:

当单片机将数据线电平从高拉到低时,产生写时序,有写“0”和写“1”两种时序。写时序开始后,DS18B20在15~60us期间从数据线上采样。如果采样到低电平,则向DS18B20写的是“0”;如果采样到高电平,则向DS18B20写的是“1”。这两个独立时序间至少需拉高总线电平1us时间。

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5*12);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5*12);
}

3.读时序:

当单片机从DS18B20读取数据时,产生读时序。此时单片机将数据线电平从高拉到低使读时序被初始化。如果在此后15us内,单片机在数据线上采样到低电平,则从DS18B20读的是“0”;如果在此后的15us内,单片机在数据线上采样到高电平,则从DS18B20读的是“1”。

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5*12);
	}
	return dat;
}

*关于工作时序的三个程序:程序均来自蓝桥杯比赛官方提供的代码,
因为官方例程所使用的为普通8051单片机,为12T单片机,即12个时钟周期机器做一个指令周期,
但是蓝桥杯单片机比赛所使用的芯片为STC的1T的芯片,运算速度是传统51的12倍,所以这里将官方的延时乘以12即可正常使用(组委会挖的小坑)

三、DS18B20的常用指令

在这里插入图片描述在这里插入图片描述

四、DS18B20的程序分析

微处理器读取单个DS18B20的温度数据,可参考以下步骤:
1.DS18B20复位。
2.写入字节0xCC,跳过ROM指令。
3.写入字节0x44,开始温度转换。
4.延时700~900ms。
5.DS18B20复位。
6.写入字节0xCC,跳过ROM指令。
7.写入字节0xBE,读取高速暂存器。
8.读取暂存器的第0字节,即温度数据的LSB。
9.读取暂存器的第1字节,即温度数据的MSB。
10.DS18B20复位。,表示读取数据结束。
11.将LSB和MSB整合成为一个16位数据。
12.判断读取结果的符号,进行正负温度的数据处理。

五、程序代码

main.c

//@mzw
//板载DS18B20温度传感器检测当前环境温度,并显示在数码管中
#include <reg52.h>
#include <intrins.h>
#include "onewire.h"

sbit hc138_A=P2^5;
sbit hc138_B=P2^6;
sbit hc138_C=P2^7;

unsigned char shuzi[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9
unsigned char shuzi1[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//0-9//含小数点	

#define uchar unsigned char 
	
int temp = 0x0000;	//必须为16位int型数据

void HC138(unsigned int n)
{
    switch(n)
    {
        case 4:
        hc138_A=0 ; hc138_B=0 ; hc138_C=1; break;
        case 5:
        hc138_A=1 ; hc138_B=0 ; hc138_C=1; break;
        case 6:
        hc138_A=0 ; hc138_B=1 ; hc138_C=1; break;
        case 7:
        hc138_A=1 ; hc138_B=1 ; hc138_C=1; break;
    }
}
/*****延时函数*****/
void delay(unsigned int k)
{
    while(k--);
}

/*****DS18B20初始化函数*****/
void DS18B20_work()
{
	unsigned char LSB , MSB ;

	init_ds18b20();			//DS18B20复位
	Write_DS18B20(0xcc);	//写入字节0xcc,跳过ROM指令
	Write_DS18B20(0x44);	//写入字节0x44,开始温度转换

	delay(800);		//延时700~900ms
	
	init_ds18b20();			//DS18B20复位
	Write_DS18B20(0xcc);	//写入字节0xcc,跳过ROM指令
	Write_DS18B20(0xbe);	//写入字节0xbe, 读取告诉暂存器

	LSB=Read_DS18B20();		//读取温度数据的低8位
	MSB=Read_DS18B20();		//读取温度数据的高8位

	init_ds18b20();			//DS18B20复位,表示读取数据结束
	
	temp = MSB ;
	temp = temp << 8 ;		//左移8位,使MSB中的数据变为temp的高八位,低八位补零
	temp = temp | LSB;		//将LSB并入temp低八位,将LSB和MSB整合成为一个16位的整数 整合完毕
	
	//首先通过温度数据的高5位判断采用结果是正温度还是负温度
	if((temp & 0xf800) == 0x0000)    //正温度的处理办法
	{
		temp >>= 4;         //取出温度结果的整数部分
		temp = temp*10;    //放大10倍
		temp = temp + (LSB&0x0f)*0.625;	//加上小数部分
	}			//此方法计算出的数据为实际温度的10倍,方便小数位的显示
	/*****正常情况室温都大于0*****/
//	temp = temp >>=4;		不带小数点的显示方法
}

/*****数码管显示函数*****/
void Display()
{
	char x = 0x01;
	int i = 0;
	for(i = 1;i<=8 ;i++)
	{
		HC138(6);
		P0 = x;
		x = _crol_(x,1);
		HC138(7);
		P0 = 0xff;delay(20);	//数码管消隐放到这个地方好一点
		switch (i)
		{
			case 1 :P0 = 0xff; break;
			case 2 :P0 = 0xff; break;
			case 3 :P0 = 0xff; break;
			case 4 :P0 = 0xff; break;
			case 5 :P0 = 0xff; break;
			case 6 :P0 = shuzi[temp / 100]; break;//temp的百位, 实际温度的十位
			case 7 :P0 = shuzi1[temp % 100 / 10]; break;//temp的十位,实际温度的个位
			case 8 :P0 = shuzi[temp % 10]; break;//temp的个位,实际温度的小数点后一位
		}
		delay(500);P0 = 0xff;
	}
}

void main()
{
	HC138(5);
	P0=0x00;	//蜂鸣器和继电器初始化、、全关
	HC138(4);
	P0= 0xff;	//LED小灯初始化、、全关
	while(1)
	{
		DS18B20_work();
		Display();	//数码管显示
	}
}

onewire.c

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "reg52.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	while(t--);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5*12);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5*12);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5*12);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12*12);
  	DQ = 0;
  	Delay_OneWire(80*12);
  	DQ = 1;
  	Delay_OneWire(10*12); 
    initflag = DQ;     
  	Delay_OneWire(5*12);
  
  	return initflag;
}

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

bit init_ds18b20(void);

unsigned char rd_temperature(void);  //; ;
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);  //STC89C52RC
unsigned char Read_DS18B20(void);


#endif

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值