参看:《嵌入式-STM32开发指南》第三部分 外设篇 - 第2章 温度传感器DS18B20
这篇文章讲的非常详细了。

一、简介

1、概述

DS18B20 是 DALLAS 最新单线数字温度传感器,新的"一线器件"体积更小、适用电压更宽、更经济。Dallas 半导体公司的数字化温度传感器 DS1820 是世界上第一片支持 "一线总线"接口的温度传感器。

DS18B20采用的单总线协议,也就是只需占用主机一个I/O口,无需其他外围电路,直接将环境温度转换为数字信号,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。另外,以"一线总线"的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。

2、特性

(1) 具有独特的单总线接口,与主机主需要一个线即可实现双向通信;
(2) 测温范围为-55+125℃,在-10+85℃时,精度为±0.5℃;
(3) 可编程的分辨率为 9~12 位,对应的可分辨温度分别为 0.5℃、0.25℃、0.125℃和 0.0625℃;
(4) 在9 位分辨率时,最多在93.75ms 内把温度值转换为数字,在12 位分辨率时,最多在 750ms 内把温度值转换为数字;
(5) 负压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。
(6) 工作电压范围宽,电压范围为3.0~5.5V,还可用数据线供电;
(7) 支持多点组网,多个DS18B20可以并联实现多点组网测温。值得注意的是,如果数量过多,需要解决供电问题,否则电压过低会导致信号传输不稳定;
(8) 测量结果采用数字信号输出,同时具有CRC校验,具较强的抗干扰和纠错能力。

3、外形结构

DS18B20 内部结构主要由四部分组成:64 位光刻 ROM、温度传感器、非挥发的温度报警触发器 TH 和 TL、配置寄存器。DS18B20 的管脚排列如下图所示。

其中与操作有关的有:64位光刻ROM、9个字节的RAM存储器、温度传感器、EERPOM(温度报警寄存器TH和TL、配置寄存器)

二、HAL库完整代码

/* Includes*********************************************************************/
#include "stm32f103_DS18B20.h"/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static void DS18B20_Mode_IPU(void);
static void DS18B20_Mode_Out_PP(void);
static void DS18B20_Rst(void);
static uint8_t DS18B20_Presence(void);
static uint8_t DS18B20_ReadBit(void);
static uint8_t DS18B20_ReadByte(void);
static void DS18B20_WriteByte(uint8_t dat);
static void DS18B20_SkipRom(void);
static void DS18B20_MatchRom(void);#define CPU_FREQUENCY_MHZ    72      // STM32时钟主频
void delay_us(__IO uint32_t delay)
{int last, curr, val;int temp;while (delay != 0){temp = delay > 900 ? 900 : delay;last = SysTick->VAL;curr = last - CPU_FREQUENCY_MHZ * temp;if (curr >= 0){do{val = SysTick->VAL;}while ((val < last) && (val >= curr));}else{curr += CPU_FREQUENCY_MHZ * 1000;do{val = SysTick->VAL;}while ((val <= last) || (val > curr));}delay -= temp;}
}static void delay_us_bak(uint16_t time)
{uint8_t i;while(time){    for (i = 0; i < 10; i++){}time--;}
}/*** @brief  DS18B20 初始化函数* @param  None* @retval None*/
uint8_t DS18B20_Init(void)
{DS18B20_Dout_GPIO_CLK_ENABLE();DS18B20_Mode_Out_PP();DS18B20_Dout_HIGH();DS18B20_Rst();return DS18B20_Presence ();
}/*** @brief  使DS18B20-DATA引脚变为上拉输入模式* @param  None* @retval None*/
static void DS18B20_Mode_IPU(void)
{GPIO_InitTypeDef GPIO_InitStruct;/* 串口外设功能GPIO配置 */GPIO_InitStruct.Pin   = DS18B20_Dout_PIN;GPIO_InitStruct.Mode  = GPIO_MODE_INPUT;GPIO_InitStruct.Pull  = GPIO_PULLUP;HAL_GPIO_Init(DS18B20_Dout_PORT, &GPIO_InitStruct);
}/*** @brief  使DS18B20-DATA引脚变为推挽输出模式* @param  None* @retval None*/
static void DS18B20_Mode_Out_PP(void)
{GPIO_InitTypeDef GPIO_InitStruct;/* 串口外设功能GPIO配置 */GPIO_InitStruct.Pin = DS18B20_Dout_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DS18B20_Dout_PORT, &GPIO_InitStruct);
}/*** @brief  主机给从机发送复位脉冲* @param  None* @retval None*/
static void DS18B20_Rst(void)
{/* 主机设置为推挽输出 */DS18B20_Mode_Out_PP();DS18B20_Dout_LOW();/* 主机至少产生480us的低电平复位信号 */delay_us(750);/* 主机在产生复位信号后,需将总线拉高 */DS18B20_Dout_HIGH();/*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/delay_us(15);
}/*** @brief  检测从机给主机返回的存在脉冲* @param  None* @retval 0:成功,1:失败*/
static uint8_t DS18B20_Presence(void)
{uint8_t pulse_time = 0;/* 主机设置为上拉输入 */DS18B20_Mode_IPU();/* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号 * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/while( DS18B20_Data_IN() && pulse_time<100 ){pulse_time++;delay_us(1);}   /* 经过100us后,存在脉冲都还没有到来*/if( pulse_time >=100 )return 1;elsepulse_time = 0;/* 存在脉冲到来,且存在的时间不能超过240us */while( !DS18B20_Data_IN() && pulse_time<240 ){pulse_time++;delay_us(1);}  if( pulse_time >=240 )return 1;elsereturn 0;
}/*** @brief  从DS18B20读取一个bit* @param  None* @retval 读取到的数据*/
static uint8_t DS18B20_ReadBit(void)
{uint8_t dat;/* 读0和读1的时间至少要大于60us */    DS18B20_Mode_Out_PP();/* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */DS18B20_Dout_LOW();delay_us(10);/* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */DS18B20_Mode_IPU();//Delay_us(2);if( DS18B20_Data_IN() == SET )dat = 1;elsedat = 0;/* 这个延时参数请参考时序图 */delay_us(45);return dat;
}/*** @brief  从DS18B20读一个字节,低位先行* @param  None* @retval 读取到的数据*/
static uint8_t DS18B20_ReadByte(void)
{uint8_t i, j, dat = 0;    for(i=0; i<8; i++) {j = DS18B20_ReadBit();       dat = (dat) | (j<<i);}return dat;
}/*** @brief  写一个字节到DS18B20,低位先行* @param  dat:待写入数据* @retval None*/
static void DS18B20_WriteByte(uint8_t dat)
{uint8_t i, testb;DS18B20_Mode_Out_PP();for( i=0; i<8; i++ ){testb = dat&0x01;dat = dat>>1;       /* 写0和写1的时间至少要大于60us */if (testb){          DS18B20_Dout_LOW();/* 1us < 这个延时 < 15us */delay_us(8);DS18B20_Dout_HIGH();delay_us(58);}      else{           DS18B20_Dout_LOW();/* 60us < Tx 0 < 120us */delay_us(70);DS18B20_Dout_HIGH();     /* 1us < Trec(恢复时间) < 无穷大*/delay_us(2);}}
}/*** @brief  跳过匹配 DS18B20 ROM* @param  None* @retval None*/
static void DS18B20_SkipRom ( void )
{DS18B20_Rst();     DS18B20_Presence();     DS18B20_WriteByte(0XCC);        /* 跳过 ROM */
}/*** @brief  执行匹配 DS18B20 ROM* @param  None* @retval None*/
static void DS18B20_MatchRom ( void )
{DS18B20_Rst();     DS18B20_Presence();     DS18B20_WriteByte(0X55);        /* 匹配 ROM */
}/** 存储的温度是16 位的带符号扩展的二进制补码形式* 当工作在12位分辨率时,其中5个符号位,7个整数位,4个小数位**         |---------整数----------|-----小数 分辨率 1/(2^4)=0.0625----|* 低字节  | 2^3 | 2^2 | 2^1 | 2^0 | 2^(-1) | 2^(-2) | 2^(-3) | 2^(-4) |***         |-----符号位:0->正  1->负-------|-----------整数-----------|* 高字节  |  s  |  s  |  s  |  s  |    s   |   2^6  |   2^5  |   2^4  |** * 温度 = 符号位 + 整数 + 小数*0.0625*/
/*** @brief  在跳过匹配 ROM 情况下获取 DS18B20 温度值 * @param  None* @retval 温度值*/
float DS18B20_GetTemp_SkipRom ( void )
{uint8_t tpmsb, tplsb;short s_tem;float f_tem;DS18B20_SkipRom ();DS18B20_WriteByte(0X44);               /* 开始转换 */DS18B20_SkipRom ();DS18B20_WriteByte(0XBE);               /* 读温度值 */tplsb = DS18B20_ReadByte();       tpmsb = DS18B20_ReadByte(); s_tem = tpmsb<<8;s_tem = s_tem | tplsb;if( s_tem < 0 )     /* 负温度 */f_tem = (~s_tem+1) * 0.0625; elsef_tem = s_tem * 0.0625;return f_tem;
}/*** @brief  在匹配 ROM 情况下获取 DS18B20 温度值 * @param  ds18b20_id:用于存放 DS18B20 序列号的数组的首地址* @retval None*/
void DS18B20_ReadId ( uint8_t * ds18b20_id )
{uint8_t uc;DS18B20_WriteByte(0x33);       //读取序列号for ( uc = 0; uc < 8; uc ++ )ds18b20_id [ uc ] = DS18B20_ReadByte();
}/*** @brief  在匹配 ROM 情况下获取 DS18B20 温度值 * @param  ds18b20_id:存放 DS18B20 序列号的数组的首地址* @retval 温度值*/
float DS18B20_GetTemp_MatchRom ( uint8_t * ds18b20_id )
{uint8_t tpmsb, tplsb, i;short s_tem;float f_tem;DS18B20_MatchRom ();            //匹配ROMfor(i=0;i<8;i++)DS18B20_WriteByte ( ds18b20_id [ i ] );   DS18B20_WriteByte(0X44);                /* 开始转换 */DS18B20_MatchRom ();            //匹配ROMfor(i=0;i<8;i++)DS18B20_WriteByte ( ds18b20_id [ i ] );  DS18B20_WriteByte(0XBE);                /* 读温度值 */tplsb = DS18B20_ReadByte();       tpmsb = DS18B20_ReadByte(); s_tem = tpmsb<<8;s_tem = s_tem | tplsb;if( s_tem < 0 )     /* 负温度 */f_tem = (~s_tem+1) * 0.0625; elsef_tem = s_tem * 0.0625;return f_tem;
}

STM32F4 HAL库开发 -- 温度传感器(DS18B20)相关推荐

  1. STM32F4 HAL库开发 -- 串口

    一.串口介绍 串口设置包含:开启串口时钟.设置响应的IO口模式.设置波特率.数据位长度.奇偶校验位.DMA等信息. 具体参看:STM32开发 – 串口详解 二.函数 1.串口参数初始化,并使能串口. ...

  2. STM32F4 HAL库开发 -- 独立看门狗(IWDG)

    之前讲过看门狗,参看:STM32开发 – 看门狗详解 一.HAL库配置独立看门狗步骤 1.取消寄存器写保护,设置看门狗预分频系数和重装载值. 首先我们必须取消 IWDG_PR和 IWDG_RLR寄存器 ...

  3. STM32F4 HAL库开发 -- 工程模板解读

    一.关键文件介绍 1.HAL库关键文件 stm32f4xx_hal_ppp.c/.h 基本外设的操作API,ppp代表任意外设.其中stm32f4xx_hal_cortex.c/.h比较特殊,它是一些 ...

  4. STM32F4 HAL库开发 -- DMA

    一.DMA简介 DMA之前有讲过,参看:STM32开发 – DMA详解 DMA,全称为Direct Memory Access,即直接存储器访问.DMA传输方式无需CPU直接控制传输,也没有中断处理方 ...

  5. STM32F4 HAL库开发 -- GPIO

    这种外设都之前都讲过了,专栏:stm32库开发实战指南. 但是使用STM32CubeMX该配置配置呢??接下来看一下. 一.GPIO简介 STM32F4 的 IO 可以由软件配置成如下 8 种模式中的 ...

  6. STM32F4 HAL库开发 -- STM32CubeMX

    一.STM32CubeMX 简介 STM32CubeMX 是 ST 意法半导体近几年来大力推荐的 STM32 芯片图形化配置工具, 允许用户使用图形化向导生成 C 初始化代码,可以大大减轻开发工作,时 ...

  7. STM32F4 HAL库开发 --时钟使能和配置

    在STM32F4的HAL库中,外设时钟使能操作都是在RCC相关固件库文件头文件stm32f4xx_hal_rcc.h 定义的.外设时钟使能在HAL库中都是通过宏定义标识符来实现.首先,我们来看看GPI ...

  8. STM32F4 HAL库开发 -- 再识

    之前开发都是基于STM32F105 和 STM32F429,使用的是标准库,操作系统是UCOSII操作系统的. 新入职公司,使用的是STM32F407 和 STM32F429,使用的是HAL库的,国产 ...

  9. STM32F4 HAL库开发 -- 新建基于 HAL 库的工程模板

    一.STM32CubeF4 固件包下载 下载:STM32CubeF4 MCU Firmware Package 二.新建基于 HAL 库的工程模板 1.新建文件夹 建立一个文件夹为 Template. ...

最新文章

  1. 【Xamarin挖墙脚系列:现有IPhone/IPad 设备尺寸】
  2. PCB差分走线的阻抗控制技术(一)
  3. 使用KNN对MNIST数据集进行实验
  4. oracle date类型,oracle 日期时间数据类型
  5. 正则表达式怎样匹配 不包含特定字符串的字符串
  6. nanotime java 博客园_System.nanoTime (计时工具类)
  7. 详解凸优化、贝叶斯、MCMC、GCN
  8. api.php phpcms,phpcms程序api怎么写接口
  9. Tomcat下找不到properties文件
  10. springboot系列四、配置模板引擎、配置热部署
  11. Dirichlet Process and Stick-Breaking(DP的Stick-breaking 构造)
  12. html内容超出不自动滚动,16.css: overflow使用 例: 固定div大小,不让内容超出div
  13. 神经网络的Dropout正则化
  14. XP系统无法远程桌面
  15. 我的世界java种子 要塞,《我的世界》你绝对没见过的稀奇种子,恐龙骨架出现在要塞...
  16. 【MM小贴士】SAP 批次双单位 CWM 的使用演示
  17. 机器学习笔记 - 简单了解模式识别
  18. js 数组Array的常用方法 es3 es5 es6
  19. 政策 | 辅导班的“超纲教学”凉了?教育部印发六科负面清单!
  20. 关于 Sketch 你可以知道的几个小秘密 (快捷键用法)

热门文章

  1. Fiddler抓包2-只抓APP的请求
  2. 【题解】Luogu SP1435 PT07X - Vertex Cover
  3. Hadoop-Yarn-框架原理及运作机制
  4. Modelsim se仿真Xilinx IPcore
  5. 【推荐】JS面象对象编程视频教程
  6. 快慢指针寻找循环节点
  7. java 判断exception类型_Checked Exception | Java语言设计者的失误?
  8. 【算法】交叉熵损失和KL散度
  9. 【Python】一种超简单的二维列表降维方法
  10. [云炬创业管理笔记]第一章测试1