Clion开发Stm32之温湿度传感器(DS18B20)驱动编写和测试

这篇具有很好参考价值的文章主要介绍了Clion开发Stm32之温湿度传感器(DS18B20)驱动编写和测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

涵盖之前文章:

  1. Clion开发STM32之HAL库GPIO宏定义封装(最新版)
  2. Clion开发stm32之微妙延迟(采用nop指令实现)
  3. Clion开发STM32之日志模块(参考RT-Thread)

DSP18B20驱动文件

头文件

/*******************************************************************************
 Copyright (c) [scl]。保留所有权利。
 * 存储的温度是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
 ******************************************************************************/
#ifndef F1XX_TEMPLATE_MODULE_DS18B20_H
#define F1XX_TEMPLATE_MODULE_DS18B20_H

#include "sys_core.h"

/**
 * @memberof input_mode_set 输入模式配置
 * @memberof out_mode_set 输出模式配置
 * @memberof send_data 发送数据
 * @memberof us_delay 微秒延迟
 */
typedef struct {
    void (*input_mode_set)(void);

    void (*out_mode_set)(void);

    void (*send_data)(uint32_t status);

    uint32_t (*read_data)(void);

    void (*us_delay)(uint32_t us);
} DS18B20_conf_t;

void DS18B20_conf_set(DS18B20_conf_t *cnf);

bool DS18B20_Driver_Init(void);

void DS18B20_readId(uint8_t *ds18b20_id);

float DS18B20_GetTemp_SkipRom(void);

float DS18B20_GetTemp_MatchRom(const uint8_t *ds18b20_id);

#endif //F1XX_TEMPLATE_MODULE_DS18B20_H

源文件

/*******************************************************************************
 Copyright (c) [scl]。保留所有权利。
 ******************************************************************************/
#include "ds18b20/module-ds18b20.h"

#define DBG_ENABLE
#define DBG_SECTION_NAME "ds18b20"
#define DBG_LEVEL DBG_LOG // DBG_LOG DBG_INFO DBG_WARNING DBG_ERROR

#include "sys_dbg.h"

static DS18B20_conf_t *conf_ptr = NULL;
#define DS18B20_DQ_0 conf_ptr->send_data(0)
#define DS18B20_DQ_1 conf_ptr->send_data(1)

static void DS18B20_WriteByte(uint8_t dat);

static uint8_t DS18B20_ReadByte(void);

static bool DS18B20_Presence(void);

void DS18B20_conf_set(DS18B20_conf_t *cnf) {
    conf_ptr = cnf;

}

static void DS18B20_Rst(void) {
    conf_ptr->out_mode_set();
    DS18B20_DQ_0;
    /* 主机至少产生480us的低电平复位信号 */
    conf_ptr->us_delay(750);
    /* 主机在产生复位信号后,需将总线拉高 */
    DS18B20_DQ_1;
    /*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/
    conf_ptr->us_delay(15);
}
/**
 * 驱动初始化
 * @return
 */
bool DS18B20_Driver_Init(void) {
    if (conf_ptr == NULL) return false;
    conf_ptr->out_mode_set();
    DS18B20_DQ_1;
    DS18B20_Rst();
    return DS18B20_Presence();
}

/**
 * @brief  在匹配 ROM 情况下获取 DS18B20 温度值
 * @param ds18b20_id :用于存放 DS18B20 序列号的数组的首地址
 */
void DS18B20_readId(uint8_t *ds18b20_id) {
    if (conf_ptr == NULL) return;
    uint8_t uc;
    DS18B20_WriteByte(0x33);       //读取序列号
    for (uc = 0; uc < 8; uc++)
        ds18b20_id[uc] = DS18B20_ReadByte();
}

/**
 *
 *
 * @brief 在跳过匹配 ROM 情况下获取 DS18B20 温度值
 * @return
 */
float DS18B20_GetTemp_SkipRom(void) {
    uint8_t tpmsb = 0, tplsb = 0;
    short s_tem = 0;
    float f_tem = 0;
    /* -------------跳过 ROM-START---------- */
    DS18B20_Rst();
    DS18B20_Presence();
    DS18B20_WriteByte(0XCC);
    /* -------------跳过 ROM-END---------- */

    DS18B20_WriteByte(0X44);                /* 开始转换 */
    /* -------------跳过 ROM-START---------- */
    DS18B20_Rst();
    DS18B20_Presence();
    DS18B20_WriteByte(0XCC);        /* 跳过 ROM */
    /* -------------跳过 ROM-END---------- */
    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;
    else
        f_tem = s_tem * 0.0625;
    return f_tem;
}


float DS18B20_GetTemp_MatchRom(const uint8_t *ds18b20_id) {
    uint8_t tpmsb, tplsb, i;
    short s_tem;
    float f_tem;

    /* -------------匹配 ROM-START---------- */
    DS18B20_Rst();
    DS18B20_Presence();
    DS18B20_WriteByte(0X55);
    /* -------------匹配 ROM-END---------- */
    DS18B20_Rst();

    DS18B20_Presence();

    DS18B20_WriteByte(0X55);        /* 匹配 ROM */
    for (i = 0; i < 8; i++)
        DS18B20_WriteByte(ds18b20_id[i]);

    DS18B20_WriteByte(0X44);                /* 开始转换 */

    /* -------------匹配 ROM-START---------- */
    DS18B20_Rst();
    DS18B20_Presence();
    DS18B20_WriteByte(0X55);
    /* -------------匹配 ROM-END---------- */
    for (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;
    else
        f_tem = s_tem * 0.0625;

    return f_tem;

}


static void DS18B20_WriteByte(uint8_t dat) {
    uint8_t i, testb;
    conf_ptr->out_mode_set();
    for (i = 0; i < 8; i++) {
        testb = dat & 0x01;
        dat = dat >> 1;
        /* 写0和写1的时间至少要大于60us */
        if (testb) {
            DS18B20_DQ_0;
            /* 1us < 这个延时 < 15us */
            conf_ptr->us_delay(8);
            DS18B20_DQ_1;
            conf_ptr->us_delay(58);
        } else {
            DS18B20_DQ_0;
            /* 60us < Tx 0 < 120us */
            conf_ptr->us_delay(70);
            DS18B20_DQ_1;
            /* 1us < Trec(恢复时间) < 无穷大*/
            conf_ptr->us_delay(2);
        }
    }
}

/*
 * 从DS18B20读取一个bit
 */
static uint8_t DS18B20_ReadBit(void) {
    uint8_t dat;
    /* 读0和读1的时间至少要大于60us */
    conf_ptr->out_mode_set();
    /* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
    DS18B20_DQ_0;
    conf_ptr->us_delay(10);

    /* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
    conf_ptr->input_mode_set();
    //DHT11_DELAY_US(2);
    if (conf_ptr->read_data() == 1)
        dat = 1;
    else
        dat = 0;
    /* 这个延时参数请参考时序图 */
    conf_ptr->us_delay(45);
    return dat;
}

/*
 * 从DS18B20读一个字节,低位先行
 */
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;
}

static bool DS18B20_Presence(void) {
    uint8_t pulse_time = 0;

    /* 主机设置为上拉输入 */
    conf_ptr->input_mode_set();

    /* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
     * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
     */
    while (conf_ptr->read_data() && pulse_time < 100) {
        pulse_time++;
        conf_ptr->us_delay(1);
    }
    /* 经过100us后,存在脉冲都还没有到来*/
    if (pulse_time >= 100)
        return 1;
    else
        pulse_time = 0;

    /* 存在脉冲到来,且存在的时间不能超过240us */
    while (!conf_ptr->read_data() && pulse_time < 240) {
        pulse_time++;
        conf_ptr->us_delay(1);
    }
    if (pulse_time >= 240)
        return false;
    else
        return true;
}

测试配置

/*******************************************************************************
 Copyright (c) [scl]。保留所有权利。
 ******************************************************************************/
#include "app_conf.h"

#define APP_CONF_ENABLE_DS18B20 (1)
#if APP_CONF_ENABLE_DS18B20

#include "ds18b20/module-ds18b20.h"

#define DBG_ENABLE
#define DBG_SECTION_NAME "DS18B20"
#define DBG_LEVEL DBG_LOG // DBG_LOG DBG_INFO DBG_WARNING DBG_ERROR

#include "sys_dbg.h"

/*-********************************************DS18B20变量定义******************************************-*/
static DS18B20_conf_t ds18b20_conf;
static stm_pin_define_t *ds18b20_pin_ptr = NULL;

static void out_mode_set(void) { stm32_pin_define_mode_set(ds18b20_pin_ptr, pin_mode_output); }

static void input_mode_set(void) { stm32_pin_define_mode_set(ds18b20_pin_ptr, pin_mode_input); }

static void send_data(uint32_t status) { stm32_pin_define_set(ds18b20_pin_ptr, status); }

static uint32_t read_data(void) { return stm32_pin_define_read(ds18b20_pin_ptr); }

/*-********************************************DS18B20_pre_init******************************************-*/
static void DS18B20_pre_init() {
    ds18b20_pin_ptr = stm_get_pin(PE6);
    ds18b20_conf.us_delay = bsp_us_delay_nop;
    ds18b20_conf.out_mode_set = out_mode_set;
    ds18b20_conf.input_mode_set = input_mode_set;
    ds18b20_conf.send_data = send_data;
    ds18b20_conf.read_data = read_data;
    DS18B20_conf_set(&ds18b20_conf);
}

sys_pre_init_export(DS18B20, DS18B20_pre_init);

/*-********************************************DS18B20_init******************************************-*/
static void DS18B20_init() {
    while (!DS18B20_Driver_Init()) {

    };
    LOG_D("DS18B20_Driver_Init ok");

}

sys_init_export(DS18B20, DS18B20_init);

/*-***********************************************DS18B20_after_init***************************************-*/
static void DS18B20_after_init() {
    uint8_t uc, ucDs18b20Id[8];
    DS18B20_readId(ucDs18b20Id); // 读取 DS18B20 的序列号
    os_ps("DS18B20_readId:");
    for (int i = 0; i < 8; ++i) {
        os_ps("%X", ucDs18b20Id[i]);
    }
    os_ps("\r\n");

    while (true) {
        float temp = DS18B20_GetTemp_MatchRom(ucDs18b20Id);

        LOG_D("TEMP is %0.3f", temp);
        HAL_Delay(1000);
    }
}

sys_after_init_export(DS18B20, DS18B20_after_init);

/*-**************************************DS18B20内部使用************************************************-*/


#endif //APP_CONF_ENABLE_DS18B20

结果

Clion开发Stm32之温湿度传感器(DS18B20)驱动编写和测试,STM32相关驱动,stm32,android,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-611230.html

到了这里,关于Clion开发Stm32之温湿度传感器(DS18B20)驱动编写和测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32+DHT11温湿度传感器

    DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次 通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数 部分用于以后扩展,现读出为零.操作流程如下: 一次完整的数据传输为40bit,高位先出。 数据格式:8bit湿度整数数据+8bit湿度小数数据

    2023年04月13日
    浏览(56)
  • STM32—DHT11温湿度传感器

    (1).下图一是DHT11总的时序图。 (2).图二对应图一的左边黑色部分,图三对应图一的绿色部分,图四的左部分图对应图一的红色部分,图四的右部分对应图一的黄色部分。 (3).首先图二部分是单片机向DHT11发送我要开始的信号,此时单片机IO口处于输出模式,输出低电平至少18MS,

    2024年02月19日
    浏览(60)
  • stm32连接DHT11温湿度传感器

    目录 1. DHT11简介 1.1. 连接电路  1.2. 串行接口 (单线双向)  2. cubeMX设置 3. 代码开发  3.1. 实现定时函数 3.2. 打开串口调试 3.4. 测试代码实现 4. 运行效果 信息如下: 建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使 用合适的上拉电阻  DHT11的供电电压为 3-5

    2023年04月16日
    浏览(55)
  • stm32读取DHT11温湿度传感器

    我们知道DHT11是单总线协议,只有一根数据线。 且内部有个上拉电路(下图)。那么数据线默认就是高电平那接下来就可以讲解主机如何和DHT11通讯的 读取DHT11的芯片手册,可以知道,DHT11一次完成的数据输出是40bit,高位先出。 格式:8bit湿度整数数据+8bit湿度小数数据 +8bi温

    2024年02月09日
    浏览(56)
  • STM32 —— 温湿度( AHT20 )传感器入门

    温湿度的具体使用方法可以看官方给出的基于 STM32 的历程,这里只进行简单介绍 官方历程如下: AHT20-21 DEMO V1_3(stm32) AHT20在STM32上的例程 V1.4 DHT20 是 DHT11 的全新升级产品,配置了专用的 ASIC 传感器芯片、高性能的半导体硅基电容式湿度传感器和一个标准的片上温度传感器,并

    2024年02月07日
    浏览(48)
  • 玩转传感器——DHT11温湿度传感器(STM32版)

    DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产

    2024年02月03日
    浏览(48)
  • STM32+DHT11采集温湿度传感器数据

            DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度。 DHT11 与单片机之间能采用简单的单总线进行通信,仅

    2024年02月07日
    浏览(44)
  • 【STM32】DHT11温湿度模块传感器详解&代码

    DHT11是数字温湿度传感器,测量范围:湿度20%-95%,温度0-50℃,广泛应用于加湿器、温湿度计、空调、汽车等领域。 如上图DATA引脚用于MCU与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右(超时时间的判断)。一次完整的数据传输为40bit,高位先出(MSB最高

    2024年02月12日
    浏览(55)
  • 嵌入式 STM32 SHT31温湿度传感器

    目录 简介 1、原理图  2、时序说明  数据传输 起始信号  结束信号  3、SHT31读写数据  SHT31指令集 读数据  温湿度转换 4、温湿度转换应用  sht3x初始化 读取温湿度  什么是SHT31?  一主机多从机--通过寻址的方式--每个从机都有唯一的地址(器件地址0x44+引脚地址)1 + 读写位

    2024年02月01日
    浏览(69)
  • 【STM32(HAL库)--DHT11温湿度传感器】

    stm32控制DHT11温湿度传感器,进行温湿度的读取.以下是自己的一点学习过程和心得,若有不妥之处,还望各位大佬指正,在下感激不尽. DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器 。 它应用专用的数字模块采集技术温湿度传感技术, 确保产品具有极高

    2024年04月15日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包