基于STM32F103——DS18B20温度采集+串口打印

发布者:码字奇才最新更新时间:2022-09-23 来源: csdn关键字:STM32F103  DS18B20  温度采集  串口打印 手机看文章 扫描二维码
随时随地手机看文章

DS18B20相关介绍

DS18B20特性

1.独特的单总线接口,就需一条线则可实现双向通信(测温)

2.测温范围:-55℃~+125℃,可通过编程设定9—12位分辨率,对应分辨温度分别为0.5、0.25、0.125、0.0625℃。

3.支持多点组网(可连接多个DS18B20温度传感器),多个DS18B20可以并联(3或2线)实现多个组网测温,但注意超过8个要解决好供电问题,否则电压过低会导致传输不稳定,从而数据不准确。

4.工作电压:3.0~5.5V (寄生电源方式下可由数据线供电)

5.在使用过程中不需要外围电路,全部传感元件及转换电路都在芯片内了。(上拉电阻

6.测温结果直接是数字量输出,单总线串行传送方式,同时可传送CRC校验码(校验数据采集是否正确),具有极强的抗干扰和纠错能力。

7.在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字。

8.负压特性:电源极性接反时,芯片不会因发热而烧毁, 但不能正常工作。


封装形式与引脚说明


在这里插入图片描述

供电方式(外部电源供电、寄生电源供电、寄生电源强上拉)

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

在这里插入图片描述

内部结构

DS18B20内部结构如图所示,其中与操作有关的是:64位光刻ROM、温度传感器、9个字节的RAM存储器、EEPROM(温度报警寄存器TH和TL、配置寄存器)。

在这里插入图片描述

光刻ROM中64位序列号是出厂前就光刻好的,相当地址序列号。排列是低位开始,低8位(产品类型标号),接着48位(自身序列号,)相当于身份证号、最高8位(前面56位的循环亢余校验码)。

如果一条总线挂接多个DS18B20需要MCU(微控制器)通过单总线对多个DS18B20进行寻址。

在这里插入图片描述

在这里插入图片描述

温度存储格式及配置寄存器(模式和分辨率)

DS18B20温度传感器进行测温,测温是以16位的二进制形式提供。

存放格式:

在这里插入图片描述

16位中 低4位是温度的小数部分、最高5位是温度的正负(全为0为正,全为1为负),中间的7位则是温度的整数部分。小数部分十进制等于16进制乘0.0625。


例子:

在这里插入图片描述

注意:如果是负数温度,那么得按位取反+1。

下面是数据处理例子


  温度数据的处理

比如我接收temp数据:十进制:64656  16进制:0XFC90    

二进制:1111 1100 1001 0000 


首先先看高5位 是1哦 好  那温度就是负数 (是0就是正数 不用取反+1)

我们得得取反+1  temp = ~temp + 1;

1111 1100 1001 0000 

取反后       0000 0011 0110 1111

+1结果      0000 0011 0111 0000


此时结果为:0000 0011 0111 0000

整数温度等于 温度整数 = temp >> 4; 把小数部分(低四位扔掉就行了)

二进制:0011 0111

10进制:5516进制: 0X37

小数温度等于 温度小数 = temp & 0x0f;就要低四位 低四位是小数部分

二进制:0000 0000

10进制: 0 16进制: 0X00


所以 温度就是 -55.0°C   

如果看得比较绕 就直接往下看吧 看下面的代码。。。。。。    


配置寄存器


TMR1R011111

TM:测试模式位,用于设置是在工作方式还是测试模式。在DS18B20出厂时该位设为0,用户不要改动。

R1 R0:分辨率设置

image.png

需要修改精度的 往下看 下面有写


DS18B20指令(ROM指令操作)

image.png

image.png

指令的使用

多个DS18B20情况: 对某一个操作时,主机先逐个与DS18B20挂接-搜索ROM——(F0H),发出匹配ROM指令(55H),紧接着提供64位序列号,之后操作就是针对DS18B20的了。


单个DS18B20情况: 不需要搜索ROM指令,读ROM指令以及匹配ROM等操作,直接跳过ROM指令(CCH),温度转换(44H),读温度操作(8EH)。


注意事项

一、 DS18B20硬件是简单,但软件就比较复杂,特别是时序要求。

二、 连接DS18B20线长限制:部分资料显示:

采用普通信号电缆传输超50m时,测温数据不稳定。

采用带屏蔽层双绞线电缆,正常通讯距离可达到150m。

采用每米绞合次数更多的带屏蔽层双绞线电缆时,通讯距离进一步加长。

三、 距离长了测温要考虑总线分布电容和阻抗匹配问题。

在测温程序设计中,一般如果硬件没什么问题,可以采用延时来跳过检测,但是如果要检测是否有应答要注意不要进入了死循环。


时序图

查看 DS18B20 状态 函数

在这里插入图片描述

/******************************************************************

描述: DS18B20 查看状态 函数

返回: 0:应答1:不应答

*******************************************************************/

uint8_t ds18b20_check(void)

{

uint8_t ack = 0;

DS18B20_SET_OUT;//设置输出模式

DS18B20_HIGH;//起始拉高电平

DS18B20_LOW;//拉低电平

delay_us(480);//维持480us

DS18B20_HIGH;//释放总线 

DS18B20_SET_IN;//设置输入模式

delay_us(25);//维持15~60us 最好是25us以上 25以下测试不够时间  

if( GPIO_ReadInputDataBit(DS18B20_PORT, DS18B20_PIN) == SET)

{

ack = 1;//没应答

}

DS18B20_HIGH;//释放总线

delay_us(240);//保证时序完整

return ack;

}


写时序 DS18B20写一字节函数

在这里插入图片描述

/******************************************************************

描述: DS18B20 写一字节指令 函数

参数: cmd: 要写入的指令

*******************************************************************/

void ds18b20_write_cmd(uint8_t cmd)

{

uint8_t i;

DS18B20_SET_OUT;//设置输出模式

for(i=0; i<8; i++)

{

DS18B20_LOW;//拉低总线

delay_us(1);//至少1us

if(cmd & 0x01)

{

DS18B20_HIGH;

}

else

{

DS18B20_LOW;

}

delay_us(60);//继续维持至少60us 最多120us 电平

DS18B20_HIGH;//释放总线

cmd >>= 1;//右移一位

}

}


读时序 DS18B20读取一字节函数

在这里插入图片描述

/******************************************************************

描述: DS18B20 读取一字节数据 函数

返回: 返回读取到的数据

*******************************************************************/

uint8_t ds18b20_read_data(void)

{

uint8_t i;

uint8_t data = 0;

for(i=0; i<8; i++)

{

DS18B20_SET_OUT;//设置输出模式

DS18B20_LOW;//拉低总线

DS18B20_SET_IN; //设置输入模式

data >>= 1;

if( GPIO_ReadInputDataBit(DS18B20_PORT, DS18B20_PIN) == 1)

{

data |= 0x80;

}

delay_us(45);

DS18B20_HIGH;//释放总线

}

return data;

}


程序代码(部分)

由于代码多 我这里就不一一贴出来了 需要可以 留言

由于代码多 我这里就不一一贴出来了 需要可以 留言


每一次进行写ROM相关命令都记得初始化。

对于单个DS18B20我们可以直接跳过ROM指令 直接温度转换。读取温度


步骤:

1.初始化

2.跳过ROM指令

3.启动温度转换(转换出来需要时间)

4.延时(等待温度转换)加不加都行

5.初始化 (记得每写ROM相关命令记得需要从初始化开始)

6.读取温度


DS18B20 相关代码

DS18B20 修改精度函数

修改精度 需要用到一个指令 写暂存器 0X4E

写暂存器: 在该写暂存器指令后向DS18B20的暂存器TH.TL以及配置寄存器中写入数据。(不了解可以看看上面的结构图)

所以我们一次得写入3个参数 代码如下:


/*******************************************************************************

描述: DS18B20 设置低温限值、高温限值、精度 函数

参数: temp_low:  写高速缓存器TL低温限值 temp_high:写高速缓存器TH高温限值

  accuracy: 精度设置 9/10/11/12 (默认12位)

********************************************************************************/

static uint8_t ds18b20_set_accuracy(uint8_t temp_low,uint8_t temp_high,uint8_t accuracy)

{

if(ds18b20_check() == 1)

{

return 1;

}

ds18b20_write_cmd(WRITE_MEMORY);//写暂存器指令4E

ds18b20_write_cmd(temp_high);//写高速缓存器TH高温限值 temp_high 度

ds18b20_write_cmd(temp_low);//写高速缓存器TL低温限值 temp_low  度

ds18b20_write_cmd(accuracy);//精度设置 

return 0;

}


DS18B20初始化函数

#define DS18B20_SET_OUT ds18b20_set_output_mode()//设置输出模式


/******************************************************************

描述: DS18B20 设置成输出模式 函数

*******************************************************************/

void ds18b20_set_output_mode(void)

{

GPIO_InitTypeDef DS18B20_Struction;//定义结构体成员

RCC_APB2PeriphClockCmd(DS18B20_RCC, ENABLE);//打开时钟

DS18B20_Struction.GPIO_Pin  = DS18B20_PIN;//引脚

DS18B20_Struction.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出

DS18B20_Struction.GPIO_Speed = GPIO_Speed_50MHz;//速率


GPIO_Init(DS18B20_PORT,&DS18B20_Struction);//对成员进行初始化

}


/******************************************************************

描述: DS18B20 配置函数

参数: accuracy: 精度

默认是 12位分辨率转换时间750ms

9位分辨率 0x1f : 0.5   °C  转换时间需要93.75ms

10位分辨率0x3f : 0.25  °C  转换时间需要187.5ms

11位分辨率0x5f : 0.125 °C  转换时间需要375ms

12位分辨率0x7f : 0.0625°C  转换时间需要750ms

返回: 0:成功 1:失败

*******************************************************************/

uint8_t ds18b20_init(uint8_t accuracy)

{

uint8_t status;

DS18B20_SET_OUT;//设置成输出模式

status = ds18b20_set_accuracy(0,70,accuracy);//设置转换精度

return status;

}


DS18B20读取温度函数


/******************************************************************

描述: DS18B20 读取温度 函数

返回: 读取成功:DS18B20_READ_SUCCESS  读取失败:DS18B20_READ_FAILURE

*******************************************************************/

uint8_t ds18b20_read_temperature(void)

{

uint8_t low,high;

uint16_t temp = 0;

if(ds18b20_check() == 1) //DS18B20 初始化

{

return DS18B20_READ_FAILURE;//读取失败

}

ds18b20_write_cmd(SKIP_ROM);//跳过ROM

ds18b20_write_cmd(TEMP_SWITCH); //启动温度转换


ds18b20_check();//DS18B20 初始化

ds18b20_write_cmd(SKIP_ROM);//跳过ROM

ds18b20_write_cmd(READ_MEMORY);//发送读暂存存储器指令

//D15 D14 D13 D12 D11    D10 D9 D8   D7 D6 D5 D4    D3 D2 D1 D0   16位数据 说明 

//** 温度正负标志 **     **  温度整数部分 **        **小数部分**

low  = ds18b20_read_data();//低字节

high = ds18b20_read_data();//高字节 高5位是正负标志 全为1 负 全为0 正

temp = ((uint8_t)high<<8) | low;

if(temp & 0x8000)

{

ds18b20_temp_symbol = 1;//负温度

temp = ~temp + 1;

}

else

{

ds18b20_temp_symbol = 0;//正温度

}

ds18b20_temp_integer = temp >> 4;//整数部分

ds18b20_temp_decimal = temp & 0x0f; //小数部分


if(ds18b20_temp_integer >= 100)

{

ds18b20_temp_integer = 99;//保持在2位数

}

return DS18B20_READ_SUCCESS;//读取成功

}


串口 相关代码

如果 对 串口 不熟悉的 可以参考 我之前写的 文章STM32串口通信介绍


串口初始化 函数

/* 配置串口1 函数*/

void usart1_init(uint32_t baudRate)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开GPIOA时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//打开串口1时钟

GPIO_InitTypeDef GPIO_initStruction;

USART_InitTypeDef USART_initStruction;


/*配置GPIOA  TX */

GPIO_initStruction.GPIO_Pin = USART1_TX; // TX

GPIO_initStruction.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

GPIO_initStruction.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_initStruction);

/*配置GPIOA RX */

GPIO_initStruction.GPIO_Pin = USART1_RX; // RX

GPIO_initStruction.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入

GPIO_Init(GPIOA, &GPIO_initStruction);

/*配置USART1 TX和RX */

USART_initStruction.USART_BaudRate = baudRate;//波特率

USART_initStruction.USART_WordLength = USART_WordLength_8b; //8位有效数据位

USART_initStruction.USART_StopBits = USART_StopBits_1;//1个停止位

USART_initStruction.USART_Parity = USART_Parity_No;//无奇偶校验位

USART_initStruction.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //不硬件控制流

USART_initStruction.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //发送 和 接收

USART_Init(USART1, &USART_initStruction);

NVIC_USART1_configuration();//串口1中断优先级配置

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能接收中断

USART_Cmd(USART1, ENABLE); //使能串口1

}


串口 发送一字节 函数

/*串口 发送1字节 函数*/

void usart_sendByte(USART_TypeDef* USARTx,uint8_t data)

{

USART_SendData(USARTx, data);

while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); //等待发送寄存器为空 证明发送完

}


串口 发送字符串 函数

/*串口 发送字符串 函数*/

void usart_sendString(USART_TypeDef* USARTx,char *str)

{

while(*str != '')

{

usart_sendByte(USARTx,*str);

str++;

}

while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET); //发送完成标志位

}


主程序 main

main.c(主函数)

#include "stm32f10x.h"

#include "ds18b20.h"

#include "usart.h"

#include "delay.h"

#include "stdio.h"

int  main()

{

char ds18b20_str[10] = {0};

usart1_init(9600);//串口1初始化 波特率9600

while(ds18b20_init(0x5f))//DS18B20初始化 11位分辨率 0.125

usart_sendString(USART1,"DS18B20 error!rn");

usart_sendString(USART1,"DS18B20 success!rn");

while(1)

{

delay_ms(500);

if(ds18b20_read_temperature() == DS18B20_READ_SUCCESS)

{

//将温度转换成字符串

sprintf(ds18b20_str,"%2u.%1u%1u%1urn",(uint32_t)ds18b20_temp_integer,((uint32_t)ds18b20_temp_decimal*10/16),

((uint32_t)ds18b20_temp_decimal*100/16%10),((uint32_t)ds18b20_temp_decimal*1000/16%10));

usart_sendString(USART1,ds18b20_str);//通过串口发送出去

}

else

{

usart_sendString(USART1,"DS18B20 error!rn");

}

}  

}


项目展示

在这里插入图片描述

关键字:STM32F103  DS18B20  温度采集  串口打印 引用地址:基于STM32F103——DS18B20温度采集+串口打印

上一篇:基于STM32F103——DS1302日期时间+串口打印
下一篇:基于STM32F103入门3——外部中断

推荐阅读最新更新时间:2024-11-07 20:03

stm32f103按键中断实现方法
#include stm32f10x.h void LED_GPIO_Config() { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; /*开启GPIOB的外设时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /*选择要控制的GPIOB引脚*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; /*设置引脚模式为通用推挽输出*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode
[单片机]
STM32F103V 4串口电路
最近做东西,需要用到4个串口,就用了STM32F103V,画了个电路 原理图: PCB: 实物图: 串口中断相关的程序段: void GPIO_Configuration(void) { RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE);
[单片机]
<font color='red'>STM32F103</font>V 4<font color='red'>串口</font>电路
基于单片机的温度采集及无线发送系统
  0 引言   随着数字化脚步的加快,越来越多的数字化产品取代了原有的机械式仪表,从而大大提高了数据的准确率。然而,多数情况下,温度的采集过程只在现场实时显示,在增加了工作量的同时,也可能会造成很多不便,如进入危险区域。因此,将无线网络应用在工业生产中,不仅能大大提高工作效率,同时也在一定程度上降低了劳动强度。   本设计基于以上两点,将工业生产中常用到的温度进行数字化,并通过无线模块将数据发送出去,在接收方利用无线接收设备接收实时的数据,从而大大降低劳动强度。   1 系统组成   系统由单片机、温度传感器、串口通信模块和无线传输模块等几部分组成。测温系统将测得的温度通过单片机在数码管上实时显示,同时,通过串口通信部分
[单片机]
基于单片机的<font color='red'>温度采集</font>及无线发送系统
太阳能热水器温度采集系统与实验研究
太阳能热水器以其安全、经济、适用、无污染等特点逐渐被城乡居民所接受,而其温度采集系统又是设计的关键。常用的温度传感器包括:热电偶、热敏电阻、集成式温度传感器,热电阻等。由于铂电阻在氧化介质和高温下的物理化学性能极其稳定,而且太阳能热水器置于室外,工作环境恶劣,所以本设计采用铂电阻作为太阳能热水器的温度传感器。 1 系统工作原理 由于太阳能热水器的工作环境限制,将下位机(PIC16F877)置于集热现场,主要实现温度采集功能,温差循环控制功能,即控制循环泵、上水阀、辅助电加热器、伴热带的启停,并与上位机(PIC16F877)进行485通信,将采集的温度水位信息送到上位机去显示。 系统的整体框图如图1所示。 2 硬件
[测试测量]
太阳能热水器<font color='red'>温度采集</font>系统与实验研究
ZDS2022示波器百集实操视频之77:DS18B20协议触发
大家好,上期视频我们与大家分享了DS18B20协议的解码操作,其中提到触发模式包括开始段触发与指令触发,本期视频我们就来详细地演示下如何对DS18B20的触发模式进行设置。 您一旦在解码模块中开启协议触发,按下【Trigger】键,触发类型就自动变成了已解码的DS18B20协议,此时协议的触发参数设置既可以在解码模块中协议参数中的触发设置中进行,也可以在触发模块中协议参数中的触发设置中进行操作,触发源选择通道1,触发模式选择指令触发,然后设置ROM指令和RAM指令,其中ROM指令包括6种,RAM指令包括7种设置,我们设置ROM指令为Read(33),RAM指令设为Write(4E),调整水平偏移,使屏幕上出现一个完整的帧,此时
[测试测量]
ZDS2022示波器百集实操视频之77:<font color='red'>DS18B20</font>协议触发
STM32F103标准库开发---精准延时delay---SysTick使用
一、SysTick使用详解 1. SysTick简介 SysTick是一个24bit的倒计数定时器,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都有一个SysTick定时器,从而获得一定的时间间隔。 2. SysTick相关寄存器 状态寄存器-CTRL STCLK外部时钟源:AHB总线时钟的 1/8 FCLK 内部时钟:AHB总线时钟——STM32F103是72MHz 重装载数值寄存器-LOAD 当前值寄存器-VAL 校准寄存器-CALIB 二、编写精准延时——delay 1. 非中断式精准延时 void delay_us(uint16_t us)//uS微秒级延时程序(参考值即是延时
[单片机]
<font color='red'>STM32F103</font>标准库开发---精准延时delay---SysTick使用
基于nRF24L01的无线温度采集系统设计
1 引言 温度采集系统所采集的温度通常通过RS485、CAN总线通信方式传输至上位机,但这种方式维护较困难,不利于工业现场生产;而无线通信GPRS技术传输距离长,通信可靠稳定,但设计复杂、成本昂贵。这里采用工业级内置硬件链路层协议的低成本单芯片nRF24L01型无线收发器件实现系统间的无线通信,完成无线信号的接收、显示及报警功能。 2 nRF24L01简介 nRF24L01是一款工业级内置硬件链路层协议的低成本无线收发器。该器件工作于2.4 GHz全球开放ISM频段,内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块,并融合增强型ShockBurst技术,其输出功率和通信频道可通过程序配置。拥有ShockBurst和
[测试测量]
基于nRF24L01的无线<font color='red'>温度采集</font>系统设计
温度测控系统之硬件模块设计
  1 温度检测模块   该系统温度测量部分采用DALLAS公司生产的一线式数字温度传感器DS18B20,它具有微型化、低功耗、高性能抗干扰能力、测量范围广、强易配处理器等优点,DS18B20可直接将温度转化成串行数字信号给单片机处理,它具有三引脚TO-92小体积封装形式,温度测量的范围为-55~+125℃,测温分辨率可达到0.062 5℃。   2 4×4行列式按键模块   该系统采用4×4行列式矩阵按键输入,其中除了0~9这10个相应数字温度按键外,还设计了温度重设按键、确定按键、零下温度选择按键和小数点按键等用来控制温度。该系统采用的是非编码式键盘,按键的识别采用的是全局扫描法。   3 主控模块   该设计采用A
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved