当前位置:首页 > 公众号精选 > 程序员小哈
[导读]网上DS18B20的驱动实现代码一大堆,简简单单的就能够移植成功,获得温度值,但是为什么代码这么写?为什么要延时那么长的时间?不对照手册仔细分析时序图,还真是不明白为什么。 下面我们就来详细剖析一下DS18B20的驱动函数的实现。 DS18B20 简介 DS18B20数字

网上DS18B20的驱动实现代码一大堆,简简单单的就能够移植成功,获得温度值,但是为什么代码这么写?为什么要延时那么长的时间?不对照手册仔细分析时序图,还真是不明白为什么。

下面我们就来详细剖析一下DS18B20的驱动函数的实现。

DS18B20 简介

DS18B20数字温度传感器是美国DALLAS公司生产的单总线数字温度传感器。其测温范围为-55℃~+125℃(-67℉~+257℉),64位只读存储器的片序列号。从而允许多只DS18B20同时并联在一根单线总线上;

华氏度和摄氏度换算关系:

(华氏度-32)×5÷9=摄氏度

DS18B20可以用一个微控制器的GPIO引脚去控制。器件内部高速暂存器区含有两个字节的温度寄存器,用来存储温度传感器输出的数据。

此外,高速暂存器区还有上下温度报警寄存器(TH和TL),和一个字节的配置寄存器。

配置寄存器允许用户将温度的精度设置为9~12位对应的分辨率为0.5℃、0.25℃、0.125℃、0.0625℃。上电默认为12位转换精度。

  • DS18B20存储器图

实际使用中,当只是为了测温,只需用到字节1,字节2和字节5。应用环境中如果没有强干扰,不是十分严格的话,不做校验也可以。

其中,暂存寄存器中的字节5包含着配置寄存器,配置寄存器内容如下图所示:

用户通过改变上表中R0和R1的值来配置DS18B20的分辨率。上电默认为R0=1及R1=1(12位分辨率)。

  • 温度/数据对应表:

温度转换后,温度转换的值将会保存在暂存存储器的温度寄存器中,并且DS18B20将会恢复到闲置状态。

TH,TL和配置寄存器是EEPROM,存储的数据在器件掉电时不会消失。

DS18B20的另一个功能是可以在没有外部电源供电的情况下工作。当总线处于高电平状态,DQ与上拉电阻连接通过单总线对器件供电。

同时处于高电平状态的总线信号对内部电容(Cpp)充电,在总线处于低电平状态时,该电容提供能量给器件。

这种提供能量的形式被称为“寄生电源”;

寄生电源模式时,VDD引脚必须接地。

  • “寄生电源”供电方式
  • 外部电源供电方式

原理图

外观及封装

  • TO-92封装
  • 防水型不锈钢封装

采用导热性高的密封胶灌封,保证了温度传感器的高灵敏性,极小的温度延迟。

芯片每个引脚均用热缩管隔开,防止短路,内部封胶,防水防潮。

引脚说明
红线:VCC
绿线:GND
黄线:DQ,传感器数据总线

驱动实现

INITIALIZATION TIMING

在初始化序列期间,总线控制器拉低总线并保持至少480us以发送一个复位脉冲,返回释放总线,进入接收状态(等待DS18B20应答)。

总线释放后,单总线由上拉电阻拉到高电平。

当DS18B20探测到I/O引脚上的上升沿后,等待15-60us,然后其以拉低总线60-240us的方式发出存在脉冲。至此,初始化时序完毕。

所以,初始化成功的标志就是能否读到DS18B20这个先低后高的脉冲时序,并且拉低的时间要满足60-240us。

复位DS18B20的代码如下:

//复位DS18B20void DS18B20_Rst(void) {  DS18B20_IO_OUT(); //总线设置为输出模式 DS18B20_DQ_OUT=0; //主机拉低总线 delay_us(750);  DS18B20_DQ_OUT=1; //释放总线,产生的上升沿能被DS18B20检测到 delay_us(15); //延时15us之后,等待DS18B20发送的低电平信号到达。}
//等待DS18B20的回应//返回1:未检测到DS18B20的存在//返回0:存在u8 DS18B20_Check(void) { u8 retry=0; DS18B20_IO_IN(); //总线设置为输入模式 while (DS18B20_DQ_IN&&retry<200) //等待拉低总线60-240us的低电平 { retry++; delay_us(1); };
if(retry>=200)return 1; else retry=0; while (!DS18B20_DQ_IN&&retry<240) { retry++; delay_us(1); }; if(retry>=240) return 1;
return 0;}

READ/WRITE TIME SLOT TIMING DIAGRAM

DS18B20的写时序(见下图):

主机在写时隙向DS18B20写入数据,其中分为写”0”时隙,和写”1”时隙。总线主机使用写“1”时间隙向DS18B20写入逻辑1,使用写“0”时间隙向DS18B20写入逻辑0。

所有的写时隙必须有最少60us的持续时间,相邻两个写时隙必须要有最少1us的恢复时间。两种写时隙都通过主机拉低总线产生(见下图)。

为了产生写1时隙,在拉低总线后主机必须在15μs内释放总线。在总线被释放后,由于上拉电阻将总线恢复为高电平。

为了产生写”0”时隙,在拉低总线后主机必须继续拉低总线以满足时隙持续时间的要求(至少60μs)。

在主机产生写时隙后,DS18B20会在其后的15~60us的一个时间段内采样单总线(DQ)。在采样的时间窗口内,如果总线为高电平,主机会向DS18B20写入1;如果总线为低电平,主机会向DS18B20写入0。

综上所述,所有的写时隙必须至少有60us的持续时间。相邻两个写时隙必须要有最少1us的恢复时间。所有的写时隙(写0和写1)都由拉低总线产生。

//写一个字节到DS18B20//dat:要写入的字节void DS18B20_Write_Byte(u8 dat) {  u8 j; u8 testb;  DS18B20_IO_OUT(); //设置DQ为输出模式 for (j=1;j<=8;j++)  { testb=dat&0x01; dat=dat>>1; if (testb)  { DS18B20_DQ_OUT=0;// Write 1 delay_us(2);  DS18B20_DQ_OUT=1; delay_us(60);  } else  { DS18B20_DQ_OUT=0;// Write 0 delay_us(60); // 等待DS18B20来采集信号  DS18B20_DQ_OUT=1; delay_us(2);  } }}

DS18B20的读时序(见下图):

主机发起读时序时,DS18B20仅被用来传输数据给控制器。因此,总线控制器在发出读指令后必须立刻开始读时序。

所有读时序必须最少60us,包括两个读周期间至少1us的恢复时间。

当总线控制器把数据线从高电平拉到低电平时,读时序开始,数据线必须至少保持1us,然后总线被释放。

DS18B20 通过拉高或拉低总线来传输”1”或”0”。

当传输逻辑”0”结束后,总线将被释放,通过上拉电阻回到上升沿状态。

从DS18B20输出的数据在读时序的下降沿出现后15us 内有效。因此,总线控制器在读时序开始后必须把I/O口设置为输入模式,以读取I/O口状态。

阴影部分为DS18B20释放总线的时刻,总线为空闲状态。

//从DS18B20读取一个位//返回值:1/0u8 DS18B20_Read_Bit(void) // read one bit{ u8 data; DS18B20_IO_OUT(); //设置总线为输出模式 DS18B20_DQ_OUT=0;  delay_us(2); //拉低最少1us DS18B20_DQ_OUT=1; //拉低再升高,产生读时序 DS18B20_IO_IN(); //设置总线为输入模式 delay_us(12); if(DS18B20_DQ_IN)data=1; else data=0;  delay_us(50);  return data;}
//从DS18B20读取一个字节//返回值:读到的数据u8 DS18B20_Read_Byte(void) // read one byte{ u8 i,j,dat; dat=0; for (i=1;i<=8;i++) { j=DS18B20_Read_Bit(); dat=(j<<7)|(dat>>1); } return dat;}
  • DS18B20的功能命令
  • 获取温度值

要获取温度值,我们需要发送上面功能命令0x44,然后发送读取暂存寄存器命令0xBE,然后我们只需要获得暂存器中的9个字节的前两个字节即可。

要获得DS18B20的温度值,需要按照下表中的顺序依次发送功能命令。

获取温度的具体代码实现如下:

//开始温度转换void DS18B20_Start(void)// ds18b20 start convert{  DS18B20_Rst();  DS18B20_Check();  DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0x44);// convert}
//从ds18b20得到温度值//精度:0.1C//返回值:温度值 (-550~1250) short DS18B20_Get_Temp(void){ u8 temp; u8 TL,TH; short tem; DS18B20_Start (); // ds18b20 start convert DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0xbe);// convert TL=DS18B20_Read_Byte(); // LSB TH=DS18B20_Read_Byte(); // MSB if(TH>7) { TH=~TH; TL=~TL; temp=0;//温度为负 }else temp=1;//温度为正 tem=TH; //获得高八位 tem<<=8; tem+=TL;//获得底八位 tem=(float)tem*0.625;//转换 if(temp)return tem; //返回温度值 else return -tem; }

跳过ROM序列号检测命令(0xCCH),对于单片DS18B20在线的系统,该命令允许主机跳过ROM序列号检测而直接对寄存器操作,从而节省时间,对于多片DS18B20在线系统,该命令将引起数据冲突。

如果主机只是对一个DS18B20进行操作,进而不需要读取ROM编码了,只要发送跳过ROM(0xCCH)命令,就可以进行温度转换和读取操作了。

  • 获取DS18B20内部ID序列号

因为咱们总线上只有一个DS18B20设备,所以直接发送0x33指令即可READ ROM。

DS18B20中有一个64位光刻ROM,按说明书说法,开始(最低)8位是产品类型标号,对于DS18B20来说都是(28H),接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。

光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。

读取ROM方法:先复位DS18B20,成功后执行读取ROM命令(33H),然后将这64位以8个字节的方式存入数组。

获取DS18B20内部ID序列号的具体代码实现如下:

DS18B20_Rst();DS18B20_Check();DS18B20_Write_Byte(0x33); for(i = 0; i < 8;i++){ arrDS18B20ID[i] = DS18B20_Read_Byte();} sprintf((char *)dtbuf,"DS18B20 ID is %02X %02X %02X %02X %02X %02X %02X %02X\r\n", arrDS18B20ID[0], arrDS18B20ID[1], arrDS18B20ID[2], arrDS18B20ID[3], arrDS18B20ID[4], arrDS18B20ID[5], arrDS18B20ID[6], arrDS18B20ID[7]);
printf((u8 *)dtbuf,strlen((char *)dtbuf));

我手里的两个DS18B20得到的结果如下所示:

由上可以看出,首字节都是0x28,即产品类型都是一样的。


至此,六月份的智能风扇中的温度传感器模块的已经实现了哈。


推荐阅读:
STM32单片机最小系统详解
STM32F103 串口的使用方法
STM32中精确延时函数的实现
DHT11及DHT21温湿度传感器时序图解析(STM32)
基于STM32固件库的MDK5工程建立
修改Keil工程名称并添加其他模块文件
基于单片机的智能风扇的功能点及所需要的功能模块【2020.06每月活动】

资料下载

微信公众号后台回复“温度传感器”,可以下载工程源码及DS18B20的手册。



免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在微控制器领域,MSP430与STM32无疑是两颗璀璨的明星。它们各自凭借其独特的技术特点和广泛的应用领域,在市场上占据了重要的位置。本文将深入解析MSP430与STM32之间的区别,探讨它们在不同应用场景下的优势和局限...

关键字: MSP430 STM32 单片机

STM32是由意法半导体公司(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器系列,以其高性能、低功耗、丰富的外设接口和强大的生态系统深受广大嵌入式开发者喜爱。本文将详细介绍S...

关键字: STM32 单片机

STM32与51单片机之间有什么差异呢?两者可以说是一场科技与性能的较量了。在科技飞速发展的今天,微控制器(MCU)已广泛应用于各类电子设备和系统中,发挥着举足轻重的作用。其中,STM32和51单片机作为两种常见的微控制...

关键字: STM32 51单片机 MCU

电磁铁是一种利用电流产生磁场的装置,具有快速响应、易于控制等特点,在工业自动化、电子设备、科学实验等领域有着广泛的应用。STM32是一款功能强大的微控制器,具有高性能、低功耗、易于编程等优点,是控制电磁铁的理想选择。本文...

关键字: 电磁铁 微控制器 STM32

边缘人工智能的实现涉及到三个基本 要素:安全性,连接性、自主性,而其中自主性是AI能力的体现,也是边缘AI有别于其他传统的物联网的关键。而通过ST Edge AI套件,就可以帮助各种不同类型的开发者实现覆盖全硬件平台的全...

关键字: 边缘人工智能 AI STM32

今天,小编将在这篇文章中为大家带来STM32单片机最小系统的有关报道,通过阅读这篇文章,大家可以对它具备清晰的认识,主要内容如下。

关键字: 单片机 单片机最小系统 STM32

STM32是一款由STMicroelectronics生产的微控制器系列,具有高性能、低功耗和丰富的外设资源。其中,串口通信是一种常用的通信方式,可以实现与其他设备之间的数据传输。

关键字: STM32 串口通信 微控制器

STM32是一种广泛使用的微控制器,具有丰富的通信接口。其中,串口通信是STM32与其他设备或系统进行数据交换的重要方式之一。本文将详细介绍STM32串口通信的原理、应用及常见故障。

关键字: STM32 串口通信

由于目前缺乏相应的监测技术,地下电缆线路出现异常运行状态无法被及时发现,久而久之易演变成大故障,最终只能通过更换地下电缆进行修复,耗费大量的人力、物力。鉴于此,开发了一种基于STM32的地下电缆异常状态检测系统,利用热传...

关键字: STM32 地下电缆

交通灯控制器是用于控制交通信号灯运行的设备,它可以根据交通流量、行人需求以及其他因素,动态地调整信号灯的变化时间和绿灯时长,以保证交通的流畅和安全。

关键字: 交通信号灯 STM32
关闭
关闭