蓝桥杯 — DS18B20温度传感器的使用

目录

1、DS18B20原理图

2、获取温度的操作步骤

3、温度传感器显示(法一)

4、温度传感器显示(法二)


1、DS18B20原理图

DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。

其中P14与DQ数据线连接。

\blacktriangle  初始化操作:

(1) 先将数据线置高电平"1"。

(2) 延时(该时间要求的不是很严格,但是尽可能的短一点)

(3) 数据线拉到低电平"0"。

(4) 延时750微秒(该时间的时间范围可以从480到960微秒)。

(5) 数据线拉到高电平"1"。

(6) 延时等待(如果初始化成功则在15到60微秒时间之内产生一个由DS18B20所返回的低电平"0"。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。

(7) 若CPU读到了数据线上的低电平"0"后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480秒。

(8) 将数据线再次拉高到高电平"1"后结束。

\blacktriangle  写操作:

(1) 数据线先置低电平"0"。

(2) 延时确定的时间为15微秒。

(3) 按从低位到高位的顺序发送字节(一次只发送一位)。

(4) 延时时间为45微秒。

(5) 将数据线拉到高电平。

(6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。

(7) 最后将数据线拉高。

\blacktriangle  读操作:

(1)将数据线拉高"1"。

(2)延时2微秒。

(3)将数据线拉低"0"。

(4)延时3微秒。

(5)将数据线拉高"1"。

(6)延时5微秒。

(7)读数据线的状态得到1个状态位,并进行数据处理。

(8)延时60微秒。

上述操作代码部分不需要自己写,官方会给出驱动文件,里面有单总线延时函数、初始化操作、写操作、读操作。

 官方驱动文件:

#include "onewire.h"

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

//DS18B20芯片初始化
bit Init_DS18B20(void)
{
	bit initflag = 0;
	DQ = 1;
	Delay_OneWire(12);
	DQ = 0;
	Delay_OneWire(80); 
	DQ = 1;
	Delay_OneWire(10); 
	initflag = DQ;    
	Delay_OneWire(5);
  
	return initflag;
}

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

//从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);
	}
	return dat;
}

2、获取温度的操作步骤

\blacksquare  重要的操作指令

   \bullet CCH:跳过ROM指令,忽略64位ROM地址,直接向DS18B20发起各种温度转换指令。
   \bullet 44H:温度转换指令,启动DS18B20进行温度转换,转换时间最长为500ms(典型值为200ms),结果保存在高速RAM中。
   \bullet BEH:读暂存器指令,读取高速暂存存储器9个字节的内容。

\blacksquare  具体步骤

   STEP1:DS18B20复位操作                              init_ds18b20();

   STEP2:跳过ROM操作指令                              Write_DS18B20(0xCC);

   STEP3:延时,等待温度装换完成                    Write_DS18B20(0x44); 

   STEP4:复位,开始下一轮操作                        init_ds18b20();

   STEP5:跳过ROM操作指令                              Write_DS18B20(0xCC);

   STEP6:读取暂存器中的数据                            Write_DS18B20(0xBE);

   STEP7:读取温度数据低与高8位字节               low = Read_DS18B20();       high = Read_DS18B20(); 
\blacksquare   获取温度的代码


uchar temperature(void){
     uchar low,high;
     char temp;
     init_ds18b20();
     Write_DS18B20(0XCC);
     Write_DS18B20(0X44);
     Delay500us();	
     Delay500us();	
     init_ds18b20();
     Write_DS18B20(0XCC);
     Write_DS18B20(0XBE);

     low=Read_DS18B20();
     high=Read_DS18B20();

     temp=high<<4;
     temp|=(low>>4);

     return temp;
}

对于获取温度的函数需要自己写,上述代码获取温度精确度为1,一般来说都是整数温度,如果有精确度要求可以自行修改温度获取函数来完成竞赛题目要求。

3、温度传感器显示(法一)

下面的代码是结合给出的驱动文件,部分修改得出的如下(整数温度值),这个是把驱动结合后形成的一个.c文件。

#include<stc15f2k60s2.h>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int

sbit DQ=P1^4;

uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar f1,f2,f3,f4,f5,f6,f7,f8;

void delay();
void allinit();
void display12(uchar f1,uchar f2);
void display34(uchar f3,uchar f4);
void display56(uchar f5,uchar f6);
void display78(uchar f7,uchar f8);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
uchar temperature(void);
void init_ds18b20(void);
void Delay100us();
void Delay500us();	
	
void main(){
uchar T1;
allinit();
f1=11;f2=11;f3=11,f4=11,f5=11,f6=0,f7=0,f8=0;
while(1){
T1=temperature();
f6=T1/100;
f7=T1%100/10;
f8=T1%10;

display12(f1,f2);
display34(f3,f4);
display56(f5,f6);
display78(f7,f8);
}
}

void Delay100us()	
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 2;
	j = 15;
	do
	{
		while (--j);
	} while (--i);
}

void Delay500us()	
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 6;
	j = 93;
	do
	{
		while (--j);
	} while (--i);
}

void delay(){
int i,j;
for(i=0;i<1;i++)
for(j=0;j<400;j++);
}

void allinit(){
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}

void display12(uchar f1,uchar f2){
P2=0XC0;P0=0X01;P2=0XFF;P0=tab[f1];
delay();
P2=0XC0;P0=0X02;P2=0XFF;P0=tab[f2];
delay();
}

void display34(uchar f3,uchar f4){
P2=0XC0;P0=0X04;P2=0XFF;P0=tab[f3];
delay();
P2=0XC0;P0=0X08;P2=0XFF;P0=tab[f4];
delay();
}

void display56(uchar f5,uchar f6){
P2=0XC0;P0=0X10;P2=0XFF;P0=tab[f5];
delay();
P2=0XC0;P0=0X20;P2=0XFF;P0=tab[f6];
delay();
}

void display78(uchar f7,uchar f8){
P2=0XC0;P0=0X40;P2=0XFF;P0=tab[f7];
delay();
P2=0XC0;P0=0X80;P2=0XFF;P0=tab[f8];
delay();
}

void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay100us();	

		DQ = 1;
		dat >>= 1;
	}
        Delay100us();
}


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==1)
		{
			dat |= 0x80;
		}	    
	 Delay100us();	

	}
	return dat;
}


void init_ds18b20(void)
{
  	DQ=0;
	Delay500us();
	DQ=1;
	Delay500us();
} 

uchar temperature(void){
uchar low,high;
char temp;
init_ds18b20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
Delay500us();	
Delay500us();	
init_ds18b20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);

low=Read_DS18B20();
high=Read_DS18B20();

temp=high<<4;
temp|=(low>>4);

return temp;
}

 

最后,对于温度传感器来说,只要明白获取温度的函数,记着重要的操作指令、步骤,这一部分大致就这些内容。

4、温度传感器显示(法二)

对于官方给出的驱动,可以分模块实现功能,下面给出分模块实现温度显示:

 onewire.c

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台
  日    期: 2011-8-9
*/

#include "onewire.h"

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

//DS18B20芯片初始化
bit Init_DS18B20(void)
{
	bit initflag = 0;
	DQ = 1;
	Delay_OneWire(12);
	DQ = 0;
	Delay_OneWire(80); 
	DQ = 1;
	Delay_OneWire(10); 
	initflag = DQ;    
	Delay_OneWire(5);
  
	return initflag;
}

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

//从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);
	}
	return dat;
}

unsigned char Get_wendu(){
unsigned char high,low;
unsigned char temp;
Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
Delay_OneWire(200);
Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);

low=Read_DS18B20();
high=Read_DS18B20();
temp=(low>>4)|(high<<4);

return temp;
}


 onewire.h

#ifndef _ONEWIRE_H
#define _ONEWIRE_H

#include "stc15f2k60s2.h"

#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe

//IC引脚定义
sbit DQ = P1^4;

//函数声明
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
unsigned char Get_wendu();
#endif

 text.c

#include<stc15f2k60s2.h>
#include"onewire.h"
#define uchar unsigned char
uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar tem;
uchar f1,f2,f3,f4,f5,f6,f7,f8;

void delay();
void allinit();
void display12(uchar f1,uchar f2);
void display34(uchar f3,uchar f4);
void display56(uchar f5,uchar f6);
void display78(uchar f7,uchar f8);

void main(){
allinit();
while(1){
tem=Get_wendu();
f1=11;f2=11;f3=11;f4=11;f5=11;f6=11;
f7=tem/10;
f8=tem%10;

display12(f1,f2);
display34(f3,f4);
display56(f5,f6);
display78(f7,f8);

}
}

void delay(){
unsigned char i,j;
for(i=0;i<2;i++)
for(j=0;j<200;j++);
}

void allinit(){
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}

void display12(uchar f1,uchar f2){
P2=0XC0;P0=0X01;P2=0XFF;P0=tab[f1];
delay();
P2=0XC0;P0=0X02;P2=0XFF;P0=tab[f2];
delay();
}

void display34(uchar f3,uchar f4){
P2=0XC0;P0=0X04;P2=0XFF;P0=tab[f3];
delay();
P2=0XC0;P0=0X08;P2=0XFF;P0=tab[f4];
delay();
}

void display56(uchar f5,uchar f6){
P2=0XC0;P0=0X10;P2=0XFF;P0=tab[f5];
delay();
P2=0XC0;P0=0X20;P2=0XFF;P0=tab[f6];
delay();
}

void display78(uchar f7,uchar f8){
P2=0XC0;P0=0X40;P2=0XFF;P0=tab[f7];
delay();
P2=0XC0;P0=0X80;P2=0XFF;P0=tab[f8];
delay();
}

 结果与体会:

 对于onewire.c文件来说,增加了一个温度获取函数,又对延时函数进行放大。

 对于onewire.h文件来说,增加了温度获取函数的说明。

发布了64 篇原创文章 · 获赞 70 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/fanjufei123456/article/details/104443872