0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何利用DS18B20传感器通过PIC微控制器获得温度

科技观察员 来源:circuitdigest 作者:苏拉夫·古普塔 2022-11-16 16:06 次阅读

通常,LM35温度传感器微控制器一起使用以测量温度,因为它便宜且易于获得。但是 LM35 给出了模拟值,我们需要使用 ADC模数转换器)将它们转换为数字值。但今天我们使用DS18B20温度传感器,不需要ADC转换即可获得温度。在这里,我们将使用带有DS18B20的PIC微控制器来测量温度。

因此,在这里,我们使用微芯片的PIC16F877A微控制器单元构建具有以下规格的温度计。

它将显示从 -55 度到 +125 度的全温度范围。

仅当温度变化 + / - .2 度时,它才会显示温度。

所需组件:-

Pic16F877A – PDIP40 封装

面包板

皮基特-3

5V 适配器

液晶显示器 JHD162A

DS18b20 温度传感器

用于连接外围设备的电线。

4.7k 电阻器 – 2 个

10k锅

20mHz 晶体

2 个 33pF 陶瓷电容器

DS18B20温度传感器:

DS18B20是一款出色的传感器,可准确检测温度。该传感器提供 9 位至 12 位的温度检测分辨率。该传感器仅与一根导线通信,不需要任何ADC即可获取模拟温度并将其转换为数字温度。

传感器的规格是:-

测量温度范围为 -55°C 至 +125°C(-67°F 至 +257°F)

-10°C 至 +85°C 范围内精度为 ±0.5°C

编程分辨率从 9 位到 12 位

无需外部组件

传感器采用1-Wire®接口

poYBAGN0mfeAZLWkAAA6uFPLWtY999.png

如果我们查看数据表中的上述引脚排列图像,我们可以看到传感器看起来与 BC547 或 BC557 封装 TO-92 完全相同。第一个引脚是接地,第二个引脚是DQ或数据,第三个引脚是VCC。

以下是数据表中的电气规格,这是我们设计所需的。传感器的额定电源电压为+3.0V至+5.5V。它还需要上拉电源电压,该电压与上述电源电压相同。

pYYBAGN0mfqAJUPqAABrNfcc0ys308.png

此外,对于 -10 摄氏度到 +10 摄氏度的范围,精度裕度为 +-0.5 摄氏度,全范围裕度的精度会发生变化,对于 -55 度到 +125 度范围,精度裕度为 +-2 度。

如果我们再次查看数据表,我们将看到传感器的连接规格。我们可以在需要两根电线(DATA 和 GND)的寄生电源模式下连接传感器,或者可以使用外部电源连接传感器,其中需要三根单独的电线。我们将使用第二种配置。

pYYBAGN0mfyAABPaAAAl5taa1-c939.png

由于我们现在熟悉传感器和连接相关区域的额定功率,我们现在可以专注于制作原理图。

电路图:-

poYBAGN0mkaANw-4AAEdEFLrgHQ712.png

如果我们看到电路图,我们将看到:-

16x2字符LCD通过PIC16F877A微控制器连接,其中RB0,RB1,RB2连接到LCD引脚RS,R/W和E。RB4、RB5、RB6 和 RB7 通过 LCD 的 4 针 D4、D5、D6、D7 连接。液晶屏以4位模式或半字节模式连接。

一个 20MHz 晶体振荡器和两个 33pF 陶瓷电容器连接在 OSC1 和 OSC2 引脚上。它将为微控制器提供恒定的20Mhz时钟频率。

DS18B20也按照引脚配置连接,如前所述,采用4.7k上拉电阻连接。我已经在面包板上连接了所有这些。

如果您不熟悉 PIC 微控制器,请按照我们的 PIC 微控制器教程进行操作,说明 PIC 微控制器入门。

步骤或代码流:-

设置微控制器的配置,包括振荡器配置。

设置LCD的所需端口,包括TRIS寄存器

使用ds18b20传感器的每个周期都以复位开始,因此我们将复位ds18b20并等待存在脉冲。

编写暂存器并将传感器的分辨率设置为 12 位。

跳过ROM读取,然后跳过复位脉冲。

提交转换温度命令。

从暂存器读取温度。

检查温度值是负值还是正值。

在 16x2 LCD 上打印温度。

等待温度变化 +/-.20 摄氏度。

pYYBAGN0mgKAC973AAEFi64GyM4994.jpg

代码说明:

本教程末尾提供了此数字温度计的完整代码,并附有演示视频。您将需要一些头文件来运行该程序,可以从此处下载

首先,我们需要在 pic 微控制器中设置配置位,然后从 void main 函数开始。

然后下面四行用于包括库头文件,lcd.h和ds18b20.h。 xc.h 用于微控制器头文件。

#include
#include
#include "supporting c files/ds18b20.h"
#include "supporting c files/lcd.h"
这些定义用于向温度传感器发送命令。这些命令列在传感器的数据表中。

#define skip_rom 0xCC
#define convert_temp 0x44
#define write_scratchpad 0x4E
#define resolution_12bit 0x7F
#define read_scratchpad 0xBE

poYBAGN0mgSATwpKAAB9IC2Q42k470.png

传感器数据表中的表 3 显示了使用宏发送相应命令的所有命令。

仅当温度变化 +/- .20 度时,温度才会显示在屏幕上。我们可以从这个temp_gap宏观上改变这个温差。通过更改此宏中的值,规范将更改。

另外两个浮点变量用于存储显示的温度数据,并用温差区分它们

#define temp_gap 20
float pre_val=0, aft_val=0;
.

在void main()函数中,lcd_init();是一个初始化LCD的函数。此 lcd_init() 函数是从 lcd.h 库中调用的。

TRIS 寄存器用于选择 I/O 引脚作为输入或输出。两个无符号短变量 TempL 和 TempH 用于存储来自温度传感器的 12 位分辨率数据。

void main(void) {
TRISD = 0xFF;
TRISA = 0x00;
TRISB = 0x00;
//TRISDbits_t.TRISD6 = 1;
unsigned short TempL, TempH;
unsigned int t, t2;
float difference1=0, difference2=0;
lcd_init();
让我们看看 while 循环,这里我们将 while(1) 循环分解成小块。

这些线用于检测温度传感器是否连接。

while(ow_reset()){
lcd_com(0x80);
lcd_puts ("Please Connect ");
lcd_com (0xC0);
lcd_puts("Temp-Sense Probe");
}
通过使用这段代码,我们初始化传感器并发送命令来转换温度。

lcd_puts (" ");
ow_reset();
write_byte(write_scratchpad);
write_byte(0);
write_byte(0);
write_byte(resolution_12bit); // 12bit resolution
ow_reset();
write_byte(skip_rom);
write_byte(convert_temp);
此代码用于将 12 位温度数据存储在两个无符号短变量中。

while (read_byte()==0xff);
__delay_ms(500);
ow_reset();
write_byte(skip_rom);
write_byte(read_scratchpad);
TempL = read_byte();
TempH = read_byte();
然后,如果您检查下面的完整代码,我们将创建if-else条件来找出温度符号是正数还是负数。

通过使用 If 语句代码,我们操作数据并查看温度是否为负,并确定温度变化是否在 +/- .20 度范围内。在其他地方,我们检查温度是否为正和温度变化检测。

从DS18B20温度传感器获取数据:

让我们看看1-Wire®接口的时差。我们正在使用20Mhz晶体。如果我们查看 ds18b20.c 文件,我们会看到

#define _XTAL_FREQ 20000000

此定义用于 XC8 编译器延迟例程。20Mhz设置为晶体频率。

我们制作了五个功能

ow_reset

read_bit

read_byte

write_bit

write_byte

1-Wire协议需要严格的时序相关插槽进行通信。在数据表中,我们将获得完美的时隙相关信息。®

pYYBAGN0mgWAauHGAABBgpiNS1Y726.png

在下面的函数中,我们创建了确切的时间段。为保持和释放创建确切的延迟并控制相应传感器端口的TRIS位非常重要。

unsigned char ow_reset(void)
{
DQ_TRIS = 0; // Tris = 0 (output)
DQ = 0; // set pin# to low (0)
__delay_us(480); // 1 wire require time delay
DQ_TRIS = 1; // Tris = 1 (input)
__delay_us(60); // 1 wire require time delay

if (DQ == 0) // if there is a presence pluse
{
__delay_us(480);
return 0; // return 0 ( 1-wire is presence)
}
else
{
__delay_us(480);
return 1; // return 1 ( 1-wire is NOT presence)
}
} // 0=presence, 1 = no part

现在,根据以下读取和写入中使用的时隙描述,我们分别创建了读取和写入函数。

poYBAGN0mgmATbbjAAB6Ph233Uc517.png

unsigned char read_bit(void)
{
unsigned char i;
DQ_TRIS = 1;
DQ = 0; // pull DQ low to start timeslot
DQ_TRIS = 1;
DQ = 1; // then return high
for (i=0; i<3; i++); // delay 15us from start of timeslot
return(DQ); // return value of DQ line
}

void write_bit(char bitval)
{
DQ_TRIS = 0;
DQ = 0; // pull DQ low to start timeslot
if(bitval==1) DQ =1; // return DQ high if write 1
__delay_us(5); // hold value for remainder of timeslot
DQ_TRIS = 1;
DQ = 1;
}// Delay provides 16us per loop, plus 24us. Therefore delay(5) = 104us

这就是我们如何利用DS18B20传感器通过PIC微控制器获得温度。

/*

* File: main.c

* Author: Sourav Gupta

*

* Created on 11 April 2018, 17:57

*/



/*

* Configuration Related settings. Specific for microcontroller unit.

*/

#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)

#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)

#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)

#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)

#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)

#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)

#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)

#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000

/*

* System Header files inclusions

*/



#include

#include

#include "supporting c files/ds18b20.h"

#include "supporting c files/lcd.h"



/*

* Ds18b20 related definition

*/



#define skip_rom 0xCC

#define convert_temp 0x44

#define write_scratchpad 0x4E

#define resolution_12bit 0x7F

#define read_scratchpad 0xBE



/*

* User interface related definitions

*/



#define temp_gap 20



float pre_val=0, aft_val=0;



/*

* Program flow related functions

*/



void sw_delayms(unsigned int d);



/* Main function / single Thread*/

void main(void) {

TRISD = 0xFF;

TRISA = 0x00;

TRISB = 0x00;

//TRISDbits_t.TRISD6 = 1;

unsigned short TempL, TempH;

unsigned int t, t2;

float difference1=0, difference2=0;

lcd_init();

while(1){

float i=0;

/* This is for presence detection of temp-sensing probe*/

while(ow_reset()){

lcd_com(0x80);

lcd_puts ("Please Connect ");

lcd_com (0xC0);

lcd_puts("Temp-Sense Probe");

}

/*------------------------------------------------------*/



lcd_puts (" ");

ow_reset();

write_byte(write_scratchpad);

write_byte(0);

write_byte(0);

write_byte(resolution_12bit); // 12bit resolution

ow_reset();

write_byte(skip_rom);

write_byte(convert_temp);



while (read_byte()==0xff);

__delay_ms(500);

ow_reset();



write_byte(skip_rom);

write_byte(read_scratchpad);



TempL = read_byte();

TempH = read_byte();



/*This is for Negative temperature*/



/*If result (TempH [Bitwise and] 1000 0000) = not 0

*then this condition get true.

case1. -0.5 degree value = 1111 1111. [1111 1111 & 1000 0000 = 1000 0000 which is not 0.]

case2. -55 degree value = 1111 1100. [1111 1100 & 1000 0000 = 1000 0000 which is not 0]

0x80 = 1000 0000

Test Case -10.125 output 1111 1111 0101 1110*/



if((TempH & 0x80)!=0){ // If condition will execute as TempH = 1111 1111 & 1000 0000 = 1000 0000.

t=TempH;// Store tempH value in t = 1111 1111 .

t<<=8;//after bitwise left shift 8 times value in t will be 1111 1111 0000 0000.   

t=t|TempL;// t = 1111 1111 0000 0000 | 0101 1110 [ result t = 1111 1111 0101 1110]

t=t-1;//t = t-1 in this case t = 1111 1111 0101 1101.

t=~t;// t = 0000 0000 1010 0010.

t>>=4;// t = 0000 0000 0000 1010.

t=t*100;// t = 10 * 100 = 1000.

t2=TempL; //Store tempL value = 0101 1110.

t2=t2-1;// t2= 0101 1101

t2=~t2;//t2 = 1010 0010

t2=t2&0x0f;// t2 = 1010 0010 | 0000 1111 = 0000 0010

t2=t2 * 6.25; // 0000 00010 = 2 x 6.25 = 12.50

i=((unsigned int)t ) + (unsigned int)t2; //put both value in one variable 1000 + 12.5 = 1012.5



/*This if-else condition done because LCD would not refresh till temperature change -.20 or +.20 degree*/



pre_val=aft_val;



difference1 = pre_val - i;

difference2 = i - pre_val;



if(difference1 > temp_gap || difference2 > temp_gap){

aft_val = i;

lcd_com (0x80);

lcd_puts ("Circuit Digest");

lcd_com (0xc0);

lcd_puts("-");

lcd_bcd (5,aft_val);

lcd_data(223);

lcd_puts("C ");

}

else{

lcd_com (0x80);

lcd_puts ("Circuit Digest");

lcd_com (0xc0);

lcd_puts("-");

lcd_bcd (5,pre_val);

lcd_data(223);

lcd_puts("C ");





}

}

/*This is for positive Temperature*/

else {

i=((unsigned int)TempH << 8 ) + (unsigned int)TempL; //put both value in one variable 

i = i * 6.25; //calculations used from the table provided in the data sheet of ds18b20



/*This if-else condition done because LCD would not refresh till temperature change -.20 or +.20 degree*/

pre_val=aft_val;



difference1 = pre_val - i;

difference2 = i - pre_val;



if(difference1 > temp_gap || difference2 > temp_gap){

aft_val = i;

lcd_com (0x80);

lcd_puts ("Circuit Digest");

lcd_com (0xc0);

lcd_bcd (5,aft_val);

lcd_data(223);

lcd_puts("C ");



}

else{

lcd_com (0x80);

lcd_puts ("Circuit Digest");

lcd_com (0xc0);

lcd_bcd (5,pre_val);

lcd_data(223);

lcd_puts("C ");

}

}

}

return;

}



void sw_delayms(unsigned int d){

int x, y;

for(x=0;x

for(y=0;y<=1275;y++); 

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 温度传感器
    +关注

    关注

    48

    文章

    2650

    浏览量

    154298
  • adc
    adc
    +关注

    关注

    95

    文章

    5651

    浏览量

    539474
  • PIC
    PIC
    +关注

    关注

    8

    文章

    507

    浏览量

    86748
  • DS18B20
    +关注

    关注

    10

    文章

    765

    浏览量

    80096
收藏 人收藏

    评论

    相关推荐

    DS18B20温度传感器工作原理及其应用电路图

    本帖最后由 gk320830 于 2015-3-5 08:38 编辑   摘要:本文通过介绍DS18B20温度传感器工作原理并结合DS18B2
    发表于 02-21 14:43

    详解DS18B20温度传感器的用法

    DS18B20与Arduino的用法。(1)一路温度测量硬件连接图将DS18B20温度传感器的VCC和GND分别连接至Arduino Un
    发表于 09-06 17:12

    基于单总线数字温度传感器DS18B20的测温系统方案

    主程序、DS18B20驱动程序的设计;最后进行了系统Proteus仿真,提高了系统开发效率,并获得了良好的仿真实验结果。  关键词:温度传感器DS
    发表于 11-06 15:18

    基于DS18B20数字温度传感器的设计方案

    DS18B20温度传感器通信,控制温度的采集过程和进行数据通信;  (2)提供DS18B20
    发表于 11-12 16:30

    DS18B20温度传感器是什么

    的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。 继“一线总线”的早期产品后,DS1820开辟了温度传感器技术的新概念。
    发表于 04-27 08:14

    一文读懂DS18B20温度传感器及编程

    一文读懂DS18B20温度传感器及编程对于新手而言,DS18B20基本概念仅做了解,最重要的是利用单片机对
    发表于 07-06 07:10

    DS18B20温度传感器学习笔记 精选资料推荐

    DS18B20温度传感器DS18B20是DALLAS公司的1-Wire(单总线)数字温度计芯片,温度
    发表于 07-14 06:19

    DS18B20温度传感器简介

    DS18B20温度传感器1. DS18B20简介2. 硬件设计3. 软件设计3.1 STM32CubeMX设置3.2 MDK-ARM编程4. 下载验证
    发表于 08-12 07:32

    DS18B20温度传感器实验

    STM32学习记录:DS18B20温度传感器实验(HAL库)实验摘要DS18B20简述STMCubeMX引脚配置芯片选型引脚和时钟配置生成ARM-MDK工程编写
    发表于 08-18 07:44

    利用DS18B20温度传感器设计智能恒温宠物箱装置

    本课题在设计中力求人性化的智能控制,以中央芯片STC89C52为核心,它是一款高性能、低功耗、高性能CMOS8位微控制器,单片机启动程序控制智能恒温宠物箱。再加上利用
    发表于 12-02 06:37

    DS18B20温度传感器的相关资料分享

    DS18B20温度传感器1. 简介DS18B20数字温度传感器提供9-12位摄氏度
    发表于 12-08 06:38

    DS18B20数字温度传感器概述

    的1-Wire即单总线通信方式,即仅采用一个数据线与微控制器进行通信。该传感器温度监测范围为-55℃至+125℃,并且在温度超过-10℃至85℃之外时还具有+-0.5℃的精度。此外,
    发表于 12-08 06:34

    利用数字温度传感器DS18B20测量温度信号

    DS18B20一、实验目的二、实验内容三、实验步骤四、C代码如下五、实验结果六、实验体会一、实验目的本次的设计主要是利用了数字温度传感器DS18B2
    发表于 12-13 07:37

    DS18B20温度传感器简介

    文章目录DS18B20 简介硬件设计软件设计下载验证DS18B20 简介DS18B20 是由 DALLAS 半导体公司推出的一种的“一线总线”接口的温度
    发表于 12-17 07:47

    如何调试DS18B20温度传感器

    关于调试DS18B20温度传感器-记录叙述元器件要点步骤其它问题结尾代码链接叙述最近,调试DS18B20这个数字传感器,关于如何调试
    发表于 01-17 07:03