012【GD32F470】 DS18B20温度传感器模块移植教程(有完整工程代码)

DS18B20温度传感器

DS18B20数字温度传感器提供9位至12位精度的温度测量,并具有非易失性用户可编程上下触发点报警功能。DS18B20通过单总线通信,根据定义,只需要一条数据线(和地线)即可与单片机通信。此外,DS18B20可以直接从数据线获得电源(“寄生电源”),消除了每个DS18B20都有一个唯一的64位串行代码,这允许多个DS18B20在同一条总线上工作。因此,使用一个微处理器来实现是很简单的。
控制分布在大面积上的许多ds18b20。可以从此功能中受益的应用包括HVAC环境控制,建筑物,设备或机械内部的温度监测系统以及过程监测和控制系统。

2.14.1 模块来源

资料下载链接:

【完整代码资料见:https://pan.quark.cn/s/942fab9bebe0

2.14.2 规格参数

工作电压:3-5.5V
工作电流:750nA~1.5mA
测量分辨率:9位到12位可编程分辨率
温度量程: -55 ~ +125 ℃
测量精度:±0.5 ℃
通信协议:单总线
管脚数量:3 Pin(2.54mm间距排针)
工作电流:750nA~1.5mA
测量分辨率:9位到12位可编程分辨率
温度量程: -55 ~ +125 ℃
测量精度:±0.5 ℃
通信协议:单总线
管脚数量:3 Pin(2.54mm间距排针)

2.14.3 移植过程

我们的目标是在梁山派GD32F470上能够实现读取温度的功能。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。

2.14.3.1 查看资料

时序说明
初始化:

  1. 将总线拉低,保存低电平至少480us。
  2. 转为输入模式,总线被上拉电阻拉高大约15~60us。
  3. 如果初始化成功则会产生一个由DS18B20所返回的低电平“0”,持续时间大约60~240us。
  4. DS18B20释放总线,将总线拉高。
    在这里插入图片描述
    读时序:
  5. 将数据线拉低至少1us。
  6. 将数据线转为输入模式,DS18B20开始采集数据,大约15us。
  7. 18B20要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平。
    注意:所有读时隙必须至少需要60us,且在两次独立的时隙之间至少需要1us的恢复时间。

在这里插入图片描述

写时序:

  1. 数据线先置低电平“0”,延时15us。
  2. 按从低位到高位的顺序发送数据(一次只发送一位)。
  3. 延时60us。
  4. 拉高数据线“1”。
  5. 穿越火线1~4步骤,直到发送完整的字节。
  6. 拉高数据线,释放总线。
    在这里插入图片描述

寄存器说明

0XCC

主机可以使用此命令同时对总线上的所有设备进行寻址,而无需发送其他的任何地址。 DS18B20通过发出0XCC命令,然后是温度转换命令[44h]来执行同步温度转换。注意,只有在总线上有一个从设备时,Read Scratchpad [BEh]命令才能跟随Skip ROM命令。在这种情况下,通过允许主服务器从从服务器读取而不发送设备的64位ROM代码可以节省时间。如果总线上有多个从设备,那么Skip ROM命令后跟Read Scratchpad命令将导致数据冲突,因为多个设备将尝试传输数据同时进行。

0X44

该命令为启动单次温度转换。转换后,产生的温度数据存储在地址为【BEh】的2字节温度寄存器中。

0XBE

该命令允许主机读取温度寄存器上的内容。数据传输从低位开始,直到读取第9个字节(bit8=CRC)。如果只需要温度数据,主机可以在任何时候发出复位以终止读取。

温度换算

温度传感器的分辨率我们可配置为9、10、11或12位,分别对应于0.5°C、0.25°C、 0.125°C和0.0625°C的增量。开机时的默认分辨率是12位。我们不进行修改,因为分辨率越高就越精准。
在这里插入图片描述

例如数据手册中的示例,如当前当前的温度是+25.0625℃,寄存器读出的高8位数据为0000 0001,低8位数据为1001 0001。将其整合得到16位数据:0000 0001 1001 0001。再转换为10进制数据为401。将读取到的数据乘以分辨率即可得到实际温度。

401 * 0.0625 = 25.0625℃

2.14.3.2 引脚选择

该模块有3个引脚,具体引脚连接见 表2.14.3.2 各引脚连接。

DS18B20立创·梁山派
VCC5V
DQPB0
GNDGND

在这里插入图片描述

2.14.3.3 移植至工程

移植步骤中的导入.c和.h文件与上一节相同,只是将.c和.h文件更改为bsp_ds18b20.c与bsp_ds18b20.h。见2.2.3.3 移植至工程。这里不再过多讲述。移植完成后面修改相关代码。
在文件bsp_ds18b20.c中,编写如下代码。

/********************************************************************************
  * 文 件 名: bsp_ds18b20.c
  * 版 本 号: 初版
  * 修改作者: LC
  * 修改日期: 2023年04月23日
  * 功能介绍:          
  ******************************************************************************
  * 注意事项:
*********************************************************************************/

#include "bsp_ds18b20.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "systick.h"


/******************************************************************
 * 函 数 名 称:bsp_ds18b20_GPIO_Init
 * 函 数 说 明:MLX90614的引脚初始化
 * 函 数 形 参:无
 * 函 数 返 回:1未检测到器件   0检测到器件
 * 作       者:LC
 * 备       注:无
******************************************************************/
char DS18B20_GPIO_Init(void)
{
    unsigned char ret = 255;
    /* 使能时钟 */
    rcu_periph_clock_enable(RCU_DQ);
        /* 配置DQ为输出模式 */
        gpio_mode_set(PORT_DQ,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_DQ);
        /* 配置为推挽输出 50MHZ */
        gpio_output_options_set(PORT_DQ,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_DQ);

    ret = DS18B20_Check();//检测器件是否存在
    return ret;
}

      

/******************************************************************
 * 函 数 名 称:DS18B20_Read_Byte
 * 函 数 说 明:从DS18B20读取一个字节
 * 函 数 形 参:无
 * 函 数 返 回:读取到的字节数据
 * 作       者:LC
 * 备       注:无
******************************************************************/
uint8_t DS18B20_Read_Byte(void)    
{        
        uint8_t i=0,dat=0;

        for (i=0;i<8;i++) 
        {
        DQ_OUT();//设置为输入模式
        DQ(0); //拉低
        delay_us(2);
        DQ(1); //释放总线
        DQ_IN();//设置为输入模式
        delay_us(12);
        dat>>=1;
        if( DQ_GET() )
        {
            dat=dat|0x80;
        }
        delay_us(50);  
     }                                                    
        return dat;
}

/******************************************************************
 * 函 数 名 称:DS18B20_Write_Byte
 * 函 数 说 明:写一个字节到DS18B20
 * 函 数 形 参:dat:要写入的字节
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void DS18B20_Write_Byte(uint8_t dat)     
{             
        uint8_t i;
        uint8_t testb;
        DQ_OUT();//设置输出模式
        for (i=0;i<8;i++) 
        {
                if ( (dat&0x01) ) //写1
                {
                        DQ(0);
                        delay_us(2);                            
                        DQ(1);
                        delay_us(60);             
                }
                else //写0
                {
                        DQ(0);//拉低60us
                        delay_us(60);             
                        DQ(1);//释放总线
                        delay_us(2);                          
                }
        dat=dat>>1;//传输下一位
        }
}


 
/******************************************************************
 * 函 数 名 称:DS18B20_Check
 * 函 数 说 明:检测DS18B20是否存在
 * 函 数 形 参:无
 * 函 数 返 回:1:未检测到DS18B20的存在  0:存在
 * 作       者:LC
 * 备       注:无
******************************************************************/
uint8_t DS18B20_Check(void)            
{   
        uint8_t timeout=0;
    //复位DS18B20
        DQ_OUT(); //设置为输出模式
        DQ(0); //拉低DQ
        delay_us(750); //拉低750us
        DQ(1); //拉高DQ 
        delay_us(15);  //15us  
    
    //设置为输入模式 
        DQ_IN();
    //等待拉低,拉低说明有应答
        while ( DQ_GET() &&timeout<200)
        {
                timeout++;//超时判断
                delay_us(1);
        };
        //设备未应答
        if(timeout>=200)
                return 1;
        else 
                timeout=0;
    
        //等待18B20释放总线
        while ( !DQ_GET() &&timeout<240)
        {
                timeout++;//超时判断
                delay_us(1);
        };
    //释放总线失败
        if(timeout>=240)
                return 1;         
        
        return 0;
}

/******************************************************************
 * 函 数 名 称:DS18B20_Start
 * 函 数 说 明:DS18B20开始温度转换
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void DS18B20_Start(void)
{                                                                  
        DS18B20_Check();                //查询是否有设备应答
        DS18B20_Write_Byte(0xcc);   //对总线上所有设备进行寻址
        DS18B20_Write_Byte(0x44);   //启动温度转换
} 

/******************************************************************
 * 函 数 名 称:DS18B20_GetTemperture
 * 函 数 说 明:从ds18b20得到温度值
 * 函 数 形 参:无
 * 函 数 返 回:温度数据
 * 作       者:LC
 * 备       注:无
******************************************************************/
float DS18B20_GetTemperture(void)
{
        uint16_t temp;
        uint8_t dataL=0,dataH=0;
        float value;
        
        DS18B20_Start();                
        DS18B20_Check();         
        DS18B20_Write_Byte(0xcc);//对总线上所有设备进行寻址
        DS18B20_Write_Byte(0xbe);// 读取数据命令 
        dataL=DS18B20_Read_Byte(); //LSB   
        dataH=DS18B20_Read_Byte(); //MSB   
        temp=(dataH<<8)+dataL;//整合数据
        
    
        if(dataH&0X80)//高位为1,说明是负温度
        {
                temp=(~temp)+1;
                value=temp*(-0.0625);
        }
        else
        {
                value=temp*0.0625;        
        }
        return value;    
}

在文件bsp_ds18b20.h中,编写如下代码。

#ifndef _BSP_DS18B20_H_
#define _BSP_DS18B20_H_

#include "gd32f4xx.h"


//端口移植
#define RCU_DQ  RCU_GPIOB
#define PORT_DQ GPIOB
#define GPIO_DQ GPIO_PIN_8


//设置DQ输出模式
#define DQ_OUT()        gpio_mode_set(PORT_DQ,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_DQ)
//设置DQ输入模式
#define DQ_IN()            gpio_mode_set(PORT_DQ,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,GPIO_DQ)
//获取DQ引脚的电平变化
#define DQ_GET()        gpio_input_bit_get(PORT_DQ,GPIO_DQ)
//DQ输出
#define DQ(x)       gpio_bit_write(PORT_DQ,GPIO_DQ, (x?SET:RESET))

void DS18B20_Reset(void);
uint8_t DS18B20_Check(void);
char DS18B20_GPIO_Init(void);
void DS18B20_Start(void);
float DS18B20_GetTemperture(void);
#endif

2.14.4 移植验证
在自己工程中的main主函数中,编写如下。

【完整代码资料见:https://pan.quark.cn/s/942fab9bebe0

移植现象:输出当前检测到的温度。
在这里插入图片描述
移植成功示例:
【完整代码资料见:https://pan.quark.cn/s/942fab9bebe0

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值