rt-thread组件之传感器组件编写记录(ds18b20温度传感器)

news/2024/6/2 18:55:39 标签: stm32, 单片机, 驱动开发

前言

  1. 对接rt-thread的sensor组件编写记录

DS18B20驱动

头文件

//
// Created by shchl on 2024/3/14.
//

#ifndef F4_OS_DS18B20_H
#define F4_OS_DS18B20_H

#include <rthw.h>
#include <rtthread.h>
#include "rtdevice.h"

struct ds18b20_device {
    rt_base_t pin;
};

typedef struct ds18b20_device *ds18b20_device_t;

rt_err_t ds18b20_init(ds18b20_device_t dev, char *pin_name);
float ds18b20_temperature_read(ds18b20_device_t dev);
#endif //F4_OS_DS18B20_H

源文件

//
// Created by shchl on 2024/3/14.
//

#include "ds18b20.h"
#define DS18B20_IO_OUT()    rt_pin_mode(dev->pin,PIN_MODE_OUTPUT)
#define DS18B20_IO_IN()     rt_pin_mode(dev->pin,PIN_MODE_INPUT)
#define DS18B20_DQ_IN       rt_pin_read(dev->pin)
#define DS18B20_OUT_H()     rt_pin_write(dev->pin,PIN_HIGH)
#define DS18B20_OUT_L()     rt_pin_write(dev->pin,PIN_LOW)
#define DS18B20_US_DELAY(us) rt_hw_us_delay(us)

/*******************************************************************************
* 函 数 名         : ds18b20_reset
* 函数功能		   : 复位DS18B20
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
static void ds18b20_reset(ds18b20_device_t dev) {

    DS18B20_IO_OUT();           //SET PG11 OUTPUT
    DS18B20_OUT_L();            //拉低DQ
    DS18B20_US_DELAY(750);      //拉低750us
    DS18B20_OUT_H();            //DQ=1
    DS18B20_US_DELAY(15);       //15US
}

/*******************************************************************************
* 函 数 名         : ds18b20_check
* 函数功能		   : 检测DS18B20是否存在
* 输    入         : 无
* 输    出         : 1:未检测到DS18B20的存在,0:存在
*******************************************************************************/
static uint8_t ds18b20_check(ds18b20_device_t dev) {
    uint8_t retry = 0;
    DS18B20_IO_IN();
    while (DS18B20_DQ_IN && retry < 200) {
        retry++;
        DS18B20_US_DELAY(1);
    };
    if (retry >= 200)return 1;
    else retry = 0;
    while (!DS18B20_DQ_IN && retry < 240) {
        retry++;
        DS18B20_US_DELAY(1);
    };
    if (retry >= 240)return 1;
    return 0;
}

static uint8_t ds18b20_read_bit(ds18b20_device_t dev) {
    uint8_t data;
    DS18B20_IO_OUT();//SET  OUTPUT
    DS18B20_OUT_L();
    DS18B20_US_DELAY(2);
    DS18B20_OUT_H();
    DS18B20_IO_IN();//SET  INPUT
    DS18B20_US_DELAY(12);
    if (DS18B20_DQ_IN)data = 1;
    else data = 0;
    DS18B20_US_DELAY(50);
    return data;
}

static void ds18b20_write_byte(ds18b20_device_t dev, uint8_t value) {
    uint8_t j;
    uint8_t testb;
    DS18B20_IO_OUT();//SET  OUTPUT;
    for (j = 1; j <= 8; j++) {
        testb = value & 0x01;
        value = value >> 1;
        if (testb) {
            DS18B20_OUT_L();// Write 1
            DS18B20_US_DELAY(2);
            DS18B20_OUT_H();
            DS18B20_US_DELAY(60);
        } else {
            DS18B20_OUT_L();// Write 0
            DS18B20_US_DELAY(60);
            DS18B20_OUT_H();
            DS18B20_US_DELAY(2);
        }
    }
}

static void ds18b20_start(ds18b20_device_t dev) {
    ds18b20_reset(dev);
    ds18b20_check(dev);
    ds18b20_write_byte(dev, 0xcc);// skip rom
    ds18b20_write_byte(dev, 0x44);// convert
}

static uint8_t ds18b20_read_byte(ds18b20_device_t dev) {
    uint8_t i, j, dat;
    dat = 0;
    for (i = 1; i <= 8; i++) {
        j = ds18b20_read_bit(dev);
        dat = (j << 7) | (dat >> 1);
    }
    return dat;
}

/*******************************************************************************
* 函 数 名          :   ds18b20_temperature_read
* 函数功能		  :     从ds18b20得到温度值
* 输    出         :  温度数据
*******************************************************************************/
float ds18b20_temperature_read(ds18b20_device_t dev) {
    uint16_t temp;
    uint8_t a, b;
    float value;
    ds18b20_start(dev);                    // ds1820 start convert
    ds18b20_reset(dev);
    ds18b20_check(dev);
    ds18b20_write_byte(dev, 0xcc);// skip rom
    ds18b20_write_byte(dev, 0xbe);// convert
    a = ds18b20_read_byte(dev); // LSB
    b = ds18b20_read_byte(dev); // MSB
    temp = b;
    temp = (temp << 8) + a;
    if ((temp & 0xf800) == 0xf800) {
        temp = (~temp) + 1;
        value = temp * (-0.0625);
    } else {
        value = temp * 0.0625;
    }
    return value;
}

rt_err_t ds18b20_init(ds18b20_device_t dev, char *pin_name) {
    dev->pin = rt_pin_get(pin_name);
    rt_pin_mode(dev->pin, PIN_MODE_OUTPUT);
    DS18B20_OUT_H();
    ds18b20_reset(dev);
    if (ds18b20_check(dev) == 0) {
        return RT_EOK;
    }
    return RT_ERROR;
}



对接传感器组件

头文件

//
// Created by shchl on 2024/3/14.
//

#ifndef F4_OS_SENSOR_TEMPERATURE_DS18B20_H
#define F4_OS_SENSOR_TEMPERATURE_DS18B20_H
#include "ds18b20.h"

int rt_hw_ds18b20_init(const char *name, struct rt_sensor_config *cfg);
#endif //F4_OS_SENSOR_TEMPERATURE_DS18B20_H

源文件

//
// Created by shchl on 2024/3/14.
//

#include "sensor_temperature_ds18b20.h"

#define DBG_ENABLE
#define DBG_TAG "ds18b20"
#define DBG_LVL DBG_INFO

#include <rtdbg.h>


static ds18b20_device_t ds18b20_create(struct rt_sensor_intf *intf) {
    ds18b20_device_t hdev = (struct ds18b20_device *) rt_malloc(sizeof(struct ds18b20_device *));
    if (RT_NULL == hdev) {
        return RT_NULL;
    }
    ds18b20_init(hdev, intf->dev_name);
    return hdev;
}

static rt_size_t ds18b20_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len) {
    ds18b20_device_t hdev = sensor->parent.user_data;
    struct rt_sensor_data *data = (struct rt_sensor_data *) buf;

    if (sensor->info.type == RT_SENSOR_CLASS_TEMP) {
        float temp_value;
        temp_value = ds18b20_temperature_read(hdev);
        data->type = RT_SENSOR_CLASS_TEMP;
        data->data.temp = (rt_int32_t) (temp_value * 10);
        data->timestamp = rt_sensor_get_ts();
    }
    return 1;
}

static struct rt_sensor_ops sensor_ops =
        {
                ds18b20_fetch_data,
        };

int rt_hw_ds18b20_init(const char *name, struct rt_sensor_config *cfg) {

    int result = -RT_ERROR;
    rt_sensor_t sensor = RT_NULL;
    ds18b20_device_t hdev = ds18b20_create(&cfg->intf);

    sensor = rt_calloc(1, sizeof(struct rt_sensor_device));
    if (RT_NULL == sensor) {
        LOG_E("calloc failed");
        return -RT_ERROR;
    }

    sensor->info.type = RT_SENSOR_CLASS_TEMP;
    sensor->info.vendor = RT_SENSOR_VENDOR_UNKNOWN;
    sensor->info.model = "ds18b20_temp";
    sensor->info.unit = RT_SENSOR_UNIT_DCELSIUS;
    sensor->info.intf_type = RT_SENSOR_INTF_ONEWIRE;
    sensor->info.range_max = 65535;
    sensor->info.range_min = 1;
    sensor->info.period_min = 120;

    rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config));
    sensor->ops = &sensor_ops;

    result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDONLY, hdev);
    if (result != RT_EOK) {
        LOG_E("device register err code: %d", result);
        rt_free(sensor);
        return -RT_ERROR;
    } else {
        LOG_I("temperature sensor init success");
        return RT_EOK;
    }
}

// 测试
int ds18b20_port(void) {
    struct rt_sensor_config cfg;
    cfg.intf.dev_name = "PG.9";
    cfg.irq_pin.pin = RT_PIN_NONE;
    rt_hw_ds18b20_init("ds18b20", &cfg);
    return 0;
}

INIT_APP_EXPORT(ds18b20_port);

测试结果

在这里插入图片描述


http://www.niftyadmin.cn/n/5430110.html

相关文章

Linux-TCP并发模型相关函数接口-014

1【TCP】多线程模型 相关函数接口已在前面章节介绍&#xff0c;这里不再赘述源码示例&#xff08;1&#xff09;&#xff1a; //【client.c】 int CreateTcpClient(char *pip, int port) {int ret 0;int sockfd 0;struct sockaddr_in seraddr;sockfd socket(AF_INET, SOCK…

十一、软考-系统架构设计师笔记-未来信息综合技术

1、信息物理系统技术概述 信息物理系统的概念 信息物理系统(Cyber-Physical Systems&#xff0c;CPS)通过集成先进的感知、计算、通信、控制等信息技术和自动控制技术&#xff0c;构建了物理空间与信息空间中人、机、物、环境、信息等要素相互映射、适时交互、高效协同的复杂系…

Hadoop大数据应用:Linux 部署 MapReduce 与 Yarn

目录 一、实验 1.环境 2.Linux 部署 MapReduce 3.Linux 部署 Yarn 4.Linux 调用大数据集群分析数据 二、问题 1.hadoop 的启动和停止命令 2.HDFS 使用命令 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构软件版本IP备注hadoop NameNode &#xf…

python 写入文件的中文乱码了怎么处理

如果在写入JSON文件时遇到中文乱码问题&#xff0c;你可以在使用json.dump()函数时设置ensure_ascii参数为False&#xff0c;以保留非ASCII字符的原始形式。这样可以确保中文字符正确地写入JSON文件。 以下是一个示例&#xff1a; import jsondata {"name": "…

vue3中子级页面绑定调用父级页面得自定义事件

使用得vue3中defineEmit函数 在 Vue 3 的 Composition API 中,defineEmits 是一个函数,用于在 setup 函数中明确地声明一个组件可以触发的自定义事件。这有助于提供更好的类型检查和更清晰的组件接口。 当你使用 Vue 3 的 <script setup> 语法糖时,defineEmits 尤其有…

Grass推出Layer 2 Data Rollup

Grass推出Layer 2 Data Rollup Grass邀请链接最新资讯 Grass邀请链接 欢迎使用我的邀请码进行注册: 邀请链接 如果你还不知道注册流程&#xff1a;详见Grass: 出售闲置带宽实现被动收入 最新资讯 简讯&#xff1a;2024年3月13日&#xff0c;Grass宣布正在建立基于Solana的La…

介绍一下redis中底层磁盘及IO模型,数据持久化机制,哨兵机制

底层磁盘及IO模型&#xff1a; Redis中的数据存储在内存中&#xff0c;但为了保证数据的持久化&#xff0c;Redis还提供了两种数据持久化方式&#xff1a;RDB&#xff08;Redis DataBase&#xff09;和AOF&#xff08;Append-Only File&#xff09;。 RDB&#xff1a;RDB是一种…

面试(持续更新)

面试问题记录 主要用于记录在面试中遇到的一些问题&#xff0c;方便复盘和补足 2024年3月14日10:45:24 金证科技一面 Java开发工程师 &&自我介绍与项目简介 1.自我介绍 2.项目介绍 3.项目中报错的解决方案&#xff1f; &&mysql数据库 1.查询张三&#xff0c…