一、环境介绍

编程软件: keil5

操作系统: win10

MCU型号: STM32F103C8T6

STM32编程方式: 寄存器开发 (方便程序移植到其他单片机)

温度传感器: DS1820

DS18B20是一个数字温度传感器,采用的是单总线时序与主机通信,只需要一根线就可以完成温度数据读取;

DS18B20内置了64位产品序列号,方便识别身份,在一根线上可以挂接多个DS18B20传感器,通过64位身份验证,可以分别读取来至不同传感器采集的温度信息。

二、DS18B20介绍

2.1 DS18B20 的主要特征

1. 全数字温度转换及输出。

2. 先进的单总线数据通信。

3. 最高 12 位分辨率,精度可达土 0.5 摄氏度。

4. 12 位分辨率时的最大工作周期为 750 毫秒。

5. 可选择寄生工作方式。

6. 检测温度范围为–55° C ~+125° C (–67° F ~+257° F)

7. 内置 EEPROM,限温报警功能。

8. 64位光刻 ROM,内置产品序列号,方便多机挂接。

9. 多样封装形式,适应不同硬件系统。

2.2 DS18B20 引脚功能

GND 电压地

DQ 单数据总线

VDD 电源电压

NC 空引脚

2.3 DS18B20 工作原理及应用

DS18B20 的温度检测与数字数据输出全集成于一个芯片之上,从而抗干扰力更强。其一个工作周期可分为两个部分,即温度检测和数据处理。

18B20 共有三种形态的存储器资源,它们分别是:ROM 只读存储器,用于存放 DS18B20ID 编码,其前 8 位是单线系列编码(DS18B20 的编码是19H),后面 48 位是芯片唯一的序列号,最后 8 位是以上 56 的位的 CRC 码(冗余校验)。数据在出产时设置不由用户更改,DS18B20 一共有 64 位 ROM。

RAM 数据暂存器,用于内部计算和数据存取,数据在掉电后丢失, DS18B20 共 9 个字节 RAM,每个字节为 8 位。第 1、 2 个字节是温度转换后的数据值信息,第 3、 4 个字节是用户 EEPROM(常用于温度报警值储存)的镜像。在上电复位时其值将被刷新。第 5 个字节则是用户第 3 个 EEPROM的镜像。第 6、 7、 8 个字节为计数寄存器,是为了让用户得到更高的温度分辨率而设计的,同样也是内部温度转换、计算的暂存单元。第 9 个字节为前 8 个字节的 CRC 码。 EEPROM 非易失性记忆体,用于存放长期需要保存的数据,上下限温度报警值和校验数据,DS18B20 共 3 位 EEPROM,并在 RAM 都存在镜像,以方便用户操作。

DS18B20默认工作在12位分辨率模式,转换后得到的12位数据,存储在DS18B20的两个8比特的RAM中(最前面的两个字节),二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。或者使用位运算方式提取温度:  小数位是占用的是低4位,高位是整数位(不考虑负数情况)。

2.4 DS18B20 芯片 ROM 指令表

1.    Read ROM(读 ROM) [33H] (方括号中的为 16 进制的命令字)
这个命令允许总线控制器读到 DS18B20 的 64 位 ROM。只有当总线上只存在一个 DS18B20 的时候才可以使用此指令,如果挂接不只一个,当通信时将会发生数据冲突

2.    atch ROM(指定匹配芯片) [55H]
这个指令后面紧跟着由控制器发出了 64 位序列号,当总线上有多只 DS18B20 时,只有与控制发出的序列号相同的芯片才可以做出反应,其它芯片将等待下一次复位。这条指令适应单芯片和多芯片挂接。

3.    Skip ROM(跳跃 ROM 指令) [CCH]
这条指令使芯片不对 ROM 编码做出反应,在单总线的情况之下,为了节省时间则可以选用此指令。如果在多芯片挂接时使用此指令将会出现数据冲突,导致错误出现。

4.    Search ROM(搜索芯片) [F0H]
在芯片初始化后,搜索指令允许总线上挂接多芯片时用排除法识别所有器件的 64 位 ROM。

5.    Alarm Search(报警芯片搜索) [ECH]
在多芯片挂接的情况下,报警芯片搜索指令只对附合温度高于 TH 或小于 TL 报警条件的芯片做出反应。只要芯片不掉电,报警状态将被保持,直到再一次测得温度什达不到报警条件为止。

6.    Write Scratchpad (向 RAM 中写数据) [4EH]
这是向 RAM 中写入数据的指令,随后写入的两个字节的数据将会被存到地址 2(报警 RAM 之 TH)和地址 3(报警 RAM 之 TL)。写入过程中可以用复位信号中止写入。

7.    Read Scratchpad (从 RAM 中读数据) [BEH]
此指令将从 RAM 中读数据,读地址从地址 0 开始,一直可以读到地址 9,完成整个 RAM 数据的读出。芯片允许在读过程中用复位信号中止读取,即可以不读后面不需要的字节以减少读取时间。

8.    Copy Scratchpad (将 RAM 数据复制到 EEPROM 中) [48H]
此指令将 RAM 中的数据存入 EEPROM 中,以使数据掉电不丢失。此后由于芯片忙于 EEPROM 储存处理,当控制器发一个读时间隙时,总线上输出“0”,当储存工作完成时,总线将输出“1”。
在寄生工作方式时必须在发出此指令后立刻超用强上拉并至少保持 10MS,来维持芯片工作。

9.    Convert T(温度转换) [44H]
收到此指令后芯片将进行一次温度转换,将转换的温度值放入 RAM 的第 1、 2 地址。此后由于芯片忙于温度转换处理,当控制器发一个读时间隙时,总线上输出“0”,当储存工作完成时,总线将输出“1”。在寄生工作方式时必须在发出此指令后立刻超用强上拉并至少保持 500MS,来维持芯片工作。

10.    Recall EEPROM(将 EEPROM 中的报警值复制到 RAM) [B8H]
此指令将 EEPROM 中的报警值复制到 RAM 中的第 3、 4 个字节里。由于芯片忙于复制处理,当控制器发一个读时间隙时,总线上输出“0”,当储存工作完成时,总线将输出“1”。另外,此指令将在芯片上电复位时将被自动执行。这样 RAM 中的两个报警字节位将始终为 EEPROM 中数据的镜像。

11.    Read Power Supply(工作方式切换) [B4H]
此指令发出后发出读时间隙,芯片会返回它的电源状态字,“0”为寄生电源状态,“1”为外部电源状态。

2.5 DS18B20时序图

2.5.1 DS18B20 复位及应答关系示意图

每一次通信之前必须进行复位,复位的时间、等待时间、回应时间应严格按时序编程。

DS18B20 读写时间隙:DS18B20的数据读写是通过时间隙处理位和命令字来确认信息交换的。

2.5.2  向DS18B20写数据0和数据1

在写数据时间隙的前 15uS 总线需要是被控制器拉置低电平,而后则将是芯片对总线数据的采样时间,采样时间在 15~60uS,采样时间内如果控制器将总线拉高则表示写“1”,如果控制器将总线拉低则表示写“0”。

每一位的发送都应该有一个至少 15uS的低电平起始位,随后的数据“0”或“1”应该在 45uS 内完成。

整个位的发送时间应该保持在 60~120uS,否则不能保证通信的正常。

注意:  DS18B20读写数据都是从低位开始传输。

2.5.3 从DS18B20读数据0和数据1

读时间隙时控制时的采样时间应该更加的精确才行,读时间隙时也是必须先由主机产生至少1uS的低电平,表示读时间的起始。随后在总线被释放后的 15uS 中 DS18B20 会发送内部数据位,这时控制如果发现总线为高电平表示读出“1”,如果总线为低电平则表示读出数据“0”。每一位的读取之前都由控制器加一个起始信号。

注意:必须在读间隙开始的 15uS 内读取数据位才可以保证通信的正确。

在通信时是以 8 位“0”或“1”为一个字节,字节的读或写是从低位开始的。

2.5.4  读取一次温度的顺序(总线上只有单个DS18B20情况)

1. 发送复位信号

2. 检测回应信号

3. 发送0xCC

4. 发送0x44

5. 发送复位信号

6. 检测回应信号

7. 写0xcc

8. 写0xbe

9. 循环8次读取温度低字节

10. 循环8次读取温度高字节

11. 合成16位温度数据,处理

三、驱动代码

3.1 DS18B20.c

#include "ds18b20.h"/*
函数功能: DS18B20初始化
硬件连接: PB15
*/
void DS18B20_Init(void)
{RCC->APB2ENR|=1<<3; //PBGPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0x30000000;GPIOB->ODR|=1<<15; //上拉
}/*
函数功能: 检测DS18B20设备是否存在
返回值  : 1表示设备不存在 0表示设备正常
*/
u8 DS18B20_CheckDevice(void)  //包含了复位脉冲、检测存在脉冲
{DS18B20_OUTPUT_MODE();//初始化为输出模式DS18B20_OUT=0;        //产生复位脉冲DelayUs(750);         //产生750us的低电平DS18B20_OUT=1;        //释放总线DelayUs(15);          //等待DS18B20回应if(DS18B20_CleckAck())//检测存在脉冲{return 1;}return 0;
}/*
函数功能: 检测DS18B20设备的存在脉冲
返回值  : 1表示错误 0表示正常
*/
u8 DS18B20_CleckAck(void)
{u8 cnt=0;DS18B20_INPUT_MODE();//初始化为输入模式while(DS18B20_IN&&cnt<200) //等待DS18B20响应存在脉冲{DelayUs(1);cnt++;}if(cnt>=200)return 1; //错误cnt=0;while((!DS18B20_IN)&&cnt<240) //等待DS18B20释放总线{DelayUs(1);cnt++;}if(cnt>=240)return 1; //错误return 0;
}/*
函数功能: 写一个字节
首先学会如何写一个位。
*/
void DS18B20_WriteByte(u8 cmd)
{u8 i;DS18B20_OUTPUT_MODE(); //初始化为输出模式for(i=0;i<8;i++){DS18B20_OUT=0;  //产生写时间间隙(写开始)DelayUs(2);DS18B20_OUT=cmd&0x01; //发送实际的数据位DelayUs(60);    //等待写完成DS18B20_OUT=1;  //释放总线,准备下一次发送cmd>>=1;        //继续发送下一位数据}
}/*
函数功能: 读一个字节
首先学会如何读一个位。
*/
u8 DS18B20_ReadByte(void)
{u8 i,data=0;  for(i=0;i<8;i++){DS18B20_OUTPUT_MODE(); //初始化为输出模式DS18B20_OUT=0;  //产生读时间间隙(读开始)DelayUs(2);DS18B20_OUT=1;  //释放总线DS18B20_INPUT_MODE(); //初始化为输入模式DelayUs(8);    //等待DS18B20的数据输出data>>=1;      //高位补0,默认以0为准if(DS18B20_IN) data|=0x80;DelayUs(60);DS18B20_OUT=1;  //释放总线,等待读取下一位数据}return data;
}/*
函数功能: 读取一次DS18B20的温度数据
返 回 值: 读取的温度数据
考虑的情况:  总线上只是接了一个DS18B20的情况
*/
u16 DS18B20_ReadTemp(void)
{u16 temp=0;u8 temp_H,temp_L;DS18B20_CheckDevice();   //发送复位脉冲、检测存在脉冲DS18B20_WriteByte(0xCC); //跳过ROM序列检测DS18B20_WriteByte(0x44); //启动一次温度转换//等待温度转换完成while(DS18B20_ReadByte()!=0xFF){}DS18B20_CheckDevice();   //发送复位脉冲、检测存在脉冲DS18B20_WriteByte(0xCC); //跳过ROM序列检测DS18B20_WriteByte(0xBE); //读取温度temp_L=DS18B20_ReadByte(); //读取的温度低位数据temp_H=DS18B20_ReadByte(); //读取的温度高位数据temp=temp_L|(temp_H<<8);   //合成温度return temp;
}

3.2 DS18B20.h

#ifndef DS18B20_H
#define DS18B20_H
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "ds18b20.h"
#include "usart.h"/*封装接口*///初始化DS18B20为输入模式
#define DS18B20_INPUT_MODE() {GPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0x80000000;}//初始化DS18B20为输出模式
#define DS18B20_OUTPUT_MODE(){GPIOB->CRH&=0x0FFFFFFF;GPIOB->CRH|=0x30000000;}//DS18B20 IO口输出
#define DS18B20_OUT PBout(15)//DS18B20 IO口输入
#define DS18B20_IN PBin(15) //函数声明
u8 DS18B20_CleckAck(void);
u8 DS18B20_CheckDevice(void);
void DS18B20_Init(void);
u16 DS18B20_ReadTemp(void);
u8 DS18B20_ReadByte(void);
void DS18B20_WriteByte(u8 cmd);
#endif

3.3 延时函数

/*
函数功能: 延时us单位
*/
void DelayUs(int us)
{
#ifdef  _SYSTICK_IRQ_int i,j;for(i=0;i<us;i++)for(j=0;j<72;j++);
#elseu32 tmp;SysTick->VAL=0;         //CNT计数器值  SysTick->LOAD=9*us;     //9表示1usSysTick->CTRL|=1<<0;    //开启定时器   do{tmp=SysTick->CTRL; //读取状态}while((!(tmp&1<<16))&&(tmp&1<<0));SysTick->VAL=0;         //CNT计数器值    SysTick->CTRL&=~(1<<0); //关闭定时器
#endif
}

3.4 main.c 调用DS18B20读取温度打印到串口

#include "stm32f10x.h"
#include "ds18b20.h"u8 DS18B20_ROM[8]; //存放DS18B20的64为ROM编码int main(void)
{u16 temp;USARTx_Init(USART1,72,115200);//串口1的初始化DS18B20_Init();   //DS18B20初始化/*1. 读取DS18B20的64位ROM编码*///发送复位脉冲、检测存在脉冲while(DS18B20_CheckDevice()) {printf("DS18B20设备不存在!\n");DelayMs(500);}//发送读取64为ROM编码的命令DS18B20_WriteByte(0x33);//循环读取64位ROM编码for(i=0;i<8;i++){DS18B20_ROM[i]=   DS18B20_ReadByte();printf("DS18B20_ROM[%d]=0x%X\n",i,DS18B20_ROM[i]);}while(1){/*2. 同时操作总线上所有的DS18B20开始转换温度*/DS18B20_CheckDevice();   //发送复位脉冲、检测存在脉冲DS18B20_WriteByte(0xCC); //跳过ROM序列检测DS18B20_WriteByte(0x44); //启动一次温度转换(让总线上所有的DS18B20都转换温度)DelayMs(500);  //等待线上所有的DS18B20温度转换完成/*3. 单个针对性读取每个DS18B20的温度*/DS18B20_CheckDevice();   //发送复位脉冲、检测存在脉冲DS18B20_WriteByte(0x55); //发送匹配ROM的命令for(i=0;i<8;i++)         //发送64位编码{DS18B20_WriteByte(DS18B20_ROM[i]); }DS18B20_WriteByte(0xBE);      //读取温度temp=DS18B20_ReadByte();      //读取的温度低位数据temp|=DS18B20_ReadByte()<<8;  //读取的温度高位数据printf("temp1=%d.%d\n",temp>>4,temp&0xF);printf("temp2=%f\n",temp*0.0625);DelayMs(500);}
}

下面公众号里有全套QT、51单片机、Python、C++、Linux基础教程,欢迎关注: 

STM32入门开发: 编写DS18B20温度传感器驱动(读取环境温度、支持级联)相关推荐

  1. STM32入门开发: 制作红外线遥控器(智能居家-万能遥控器)

    一.环境介绍 MCU: STM32F103ZET6 编程软件环境: keil5 红外线传输协议:  NEC协议---38KHZ载波:.NEC协议是红外遥控协议中常见的一种. 编码发送思路:  延时函数 ...

  2. STM32入门开发工具整理总结

    本文介绍一下STM32开发都有什么工具,资料需要到什么地方下载. 一.STM32资料 ST对于其新的32bit MCU平台的重视程度可从其提供的应用笔记的数量和相应的参考代码上可见一斑. STM32的 ...

  3. ds18b20温度传感器驱动编写

    协议 DS18B20的一线工作协议流程是:初始化→ROM操作指令→存储器操作指令→数据传输,其工作时序包括:初始化时序.写时序.读时序. 黑色部分表示单片机操作,蓝色部分表示18b20操作,每次主机操 ...

  4. DS18B20温度传感器驱动文件

    1.DS18B20.h 文件.主要进行函数声明,和管脚定义. #ifndef _DS18B20_H_ #define _DS18B20_H_#include <intrins.h> #in ...

  5. STM32入门开发--LED模块实现跑马灯

    1.案例描述 利用STM32F103ZE开发板实现控制LED灯实现跑马灯现象. 正在不断学习嵌入式开发中,博客还会持续更新,敬请关注! 2.开发环境 keil 5.14 + Windows 10 + ...

  6. stm32入门开发板选野火还是正点原子好,哪个的视频讲到好一点?

    学习交流可以添加 微信读者交流①群 (添加微信:coderAllen,备注加群) 程序员技术交流①群:736386324 这个比较有发言权,因为全部都研究过,要是对于学习,谁的都可以,因为都是很有系统 ...

  7. 51单片机DS18B20温度驱动

    51单片机DS18B20温度传感器驱动,仅有.h文件,无.c文件. /***************************************************************** ...

  8. 外设驱动库开发笔记13:MLX90614红外温度传感器驱动

    红外温度传感器一般用于非接触式的温度检测.在我们的系统中经常会有这样的需求.所以我们将其设计为通用的驱动库以备复用.这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现. 1.功能概述 ML ...

  9. 如何用c语言编写stm32的程序吗,STM32入门C语言详解

    <STM32入门C语言详解>由会员分享,可在线阅读,更多相关<STM32入门C语言详解(6页珍藏版)>请在人人文库网上搜索. 1.最新 料推荐阅读 flash : 芯片内部存储 ...

最新文章

  1. Windows Vista Beta 1试用体会
  2. Post/Redirect/Get模式防止表单重复提交
  3. Daily Scrum02 12.04
  4. 判断DataRow中某列是否为空的方法
  5. php 判斷數據庫表是否存在,phpl判斷mysq數據庫中的某個數據表是否存在的方法總結...
  6. AFNetWorking 之 网络请求的基本知识
  7. 在建立与服务器的连接时出错。provider: TCP 提供程序, error: 0 - 由于目标机器积极拒绝,无法连接。)...
  8. 阶段3 2.Spring_09.JdbcTemplate的基本使用_5 JdbcTemplate在spring的ioc中使用
  9. 为什么录像总是很暗_为什么拍出的的照片总是很暗?看下是不是这2个原因造成的...
  10. vsftp服务日志不能显示中文临时解决(crontab五秒更新)
  11. 【opencv450】Vibe算法进行前景检测
  12. 【IP SSL】内网IP SSL证书Nginx部署
  13. 形状的度量Measures of Shape
  14. git和Github
  15. 电力系统非线性控制_电力系统保护与控制2020年第13期目录
  16. jcp jsr_JCP专家组成员拒绝社交媒体API引发了关于创新的辩论
  17. 干货!最全的AI速查表|神经网络,机器学习,深度学习
  18. 51单片机:数码管动态显示
  19. MLCC电容和电介质材料类别X5R,X7R,Y5V,COG等一些资料
  20. P2380 狗哥采矿 (二维dp)

热门文章

  1. CST2018学习笔记:一、软件启动与新项目的建立
  2. 【华为机试真题二星题目 python】欢乐的周末_03
  3. 揭秘:智邦国际ERP系统核心价值
  4. 【latex】sci论文写作总结
  5. 苹果设计组件库_建立设计系统和组件库
  6. 我的电脑锁定计算机怎么没有,笔记本电脑屏幕锁住了按键盘没有反应 笔记本电脑屏幕锁住了按键盘没有反应怎么办...
  7. 论文学习笔记1——《机器学习的理论局限与因果革命的7大火花》(因果推理必将带来现有人工智能领域研究的再一次巨大突破)
  8. R5F1006CASP#X0 16位微控制器MCU RL78 / G13 MCU低功耗 通用应用RENESAS
  9. ElectronVite2MacUI 超精美仿macOS桌面UI管理框架|vue3+electron桌面后台
  10. 项目的敏捷开发方法(转自MBAlib)