Просмотр исходного кода

Merge pull request #1 from willianchanlovegithub/WillianChan

First Commit
Willian Chan 6 лет назад
Родитель
Сommit
0f53a2b59c
4 измененных файлов с 411 добавлено и 0 удалено
  1. 20 0
      SConscript
  2. 36 0
      inc/sensor_dallas_ds18b20.h
  3. 97 0
      sample/ds18b20_sample.c
  4. 258 0
      src/sensor_dallas_ds18b20.c

+ 20 - 0
SConscript

@@ -0,0 +1,20 @@
+from building import *
+Import('rtconfig')
+
+src   = []
+cwd   = GetCurrentDir()
+
+# add ds18b20 src files.
+if GetDepend('PKG_USING_DS18B20'):
+    src += Glob('src/sensor_dallas_ds18b20.c')
+
+if GetDepend('PKG_USING_DS18B20_SAMPLE'):
+    src += Glob('sample/ds18b20_sample.c')
+
+# add ds18b20 include path.
+path  = [cwd + '/inc']
+
+# add src and include to group.
+group = DefineGroup('ds18b20', src, depend = ['PKG_USING_DS18B20'], CPPPATH = path)
+
+Return('group')

+ 36 - 0
inc/sensor_dallas_ds18b20.h

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author          Notes
+ * 2019-07-15     WillianChan     the first version.
+ *
+ */
+
+#ifndef __DS18B20_H__
+#define __DS18B20_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "sensor.h"
+
+#define CONNECT_SUCCESS  0
+#define CONNECT_FAILED   1
+
+struct ds18b20_device
+{
+    rt_base_t pin;
+    rt_mutex_t lock;
+};
+typedef struct ds18b20_device *ds18b20_device_t;
+
+uint8_t ds18b20_init(rt_base_t pin);
+int32_t ds18b20_get_temperature(rt_base_t pin);
+int rt_hw_ds18b20_init(const char *name, struct rt_sensor_config *cfg);
+
+#endif /* __DS18B20_H_ */
+
+

+ 97 - 0
sample/ds18b20_sample.c

@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-24     WillianChan    the first version
+ */
+
+#include <stdlib.h>
+#include <rtthread.h>
+#include "sensor.h"
+#include "sensor_dallas_ds18b20.h"
+
+/* Modify this pin according to the actual wiring situation */
+#define DS18B20_DATA_PIN    GET_PIN(G, 9)
+
+static void read_temp_entry(void *parameter)
+{
+    rt_device_t dev = RT_NULL;
+    struct rt_sensor_data sensor_data;
+    rt_size_t res;
+
+    dev = rt_device_find(parameter);
+    if (dev == RT_NULL)
+    {
+        rt_kprintf("Can't find device:%s\n", parameter);
+        return;
+    }
+
+    if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
+    {
+        rt_kprintf("open device failed!\n");
+        return;
+    }
+    rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)100);
+
+    while (1)
+    {
+        res = rt_device_read(dev, 0, &sensor_data, 1);
+        if (res != 1)
+        {
+            rt_kprintf("read data failed!size is %d\n", res);
+            rt_device_close(dev);
+            return;
+        }
+        else
+        {
+            if (sensor_data.data.temp >= 0)
+            {
+                rt_kprintf("temp:%3d.%dC, timestamp:%5d\n",
+                       sensor_data.data.temp / 10,
+                       sensor_data.data.temp % 10,
+                       sensor_data.timestamp);
+            }
+            else
+            {
+                rt_kprintf("temp:-%2d.%dC, timestamp:%5d\n",
+                       abs(sensor_data.data.temp / 10),
+                       abs(sensor_data.data.temp % 10),
+                       sensor_data.timestamp);
+            }
+        }
+        rt_thread_mdelay(100);
+    }
+}
+
+static int ds18b20_read_temp_sample(void)
+{
+    rt_thread_t ds18b20_thread;
+
+    ds18b20_thread = rt_thread_create("18b20tem",
+                                      read_temp_entry,
+                                      "temp_ds18b20",
+                                      1024,
+                                      RT_THREAD_PRIORITY_MAX / 2,
+                                      20);
+    if (ds18b20_thread != RT_NULL)
+    {
+        rt_thread_startup(ds18b20_thread);
+    }
+
+    return RT_EOK;
+}
+INIT_APP_EXPORT(ds18b20_read_temp_sample);
+
+static int rt_hw_ds18b20_port(void)
+{
+    struct rt_sensor_config cfg;
+    
+    cfg.intf.user_data = (void *)DS18B20_DATA_PIN;
+    rt_hw_ds18b20_init("ds18b20", &cfg);
+    
+    return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(rt_hw_ds18b20_port);

+ 258 - 0
src/sensor_dallas_ds18b20.c

@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author          Notes
+ * 2019-07-15     WillianChan     the first version.
+ *
+ */
+
+#include "sensor_dallas_ds18b20.h"
+#include "sensor.h"
+#include "board.h"
+#include <rtdbg.h>
+
+#define DBG_TAG "sensor.dallas.ds18b20"
+#define DBG_LVL DBG_INFO
+
+#define SENSOR_TEMP_RANGE_MAX (125)
+#define SENSOR_TEMP_RANGE_MIN (-55)
+
+RT_WEAK void rt_hw_us_delay(rt_uint32_t us)
+{
+    rt_uint32_t delta;
+
+    us = us * (SysTick->LOAD / (1000000 / RT_TICK_PER_SECOND));
+    delta = SysTick->VAL;
+
+    while (delta - SysTick->VAL < us) continue;
+}
+
+static void ds18b20_reset(rt_base_t pin)
+{
+    rt_pin_mode(pin, PIN_MODE_OUTPUT);
+    rt_pin_write(pin, PIN_LOW);
+    rt_hw_us_delay(780);               /* 480us - 960us */
+    rt_pin_write(pin, PIN_HIGH);
+    rt_hw_us_delay(40);                /* 15us - 60us*/
+}
+
+static uint8_t ds18b20_connect(rt_base_t pin)
+{
+    uint8_t retry = 0;
+    rt_pin_mode(pin, PIN_MODE_INPUT);
+
+    while (rt_pin_read(pin) && retry < 200)
+    {
+        retry++;
+        rt_hw_us_delay(1);
+    };
+
+    if(retry >= 200)
+        return CONNECT_FAILED;
+    else
+        retry = 0;
+
+    while (!rt_pin_read(pin) && retry < 240)
+    {
+        retry++;
+        rt_hw_us_delay(1);
+    };
+
+    if(retry >= 240)
+        return CONNECT_FAILED;
+
+    return CONNECT_SUCCESS;
+}
+
+static uint8_t ds18b20_read_bit(rt_base_t pin)
+{
+    uint8_t data;
+
+    rt_pin_mode(pin, PIN_MODE_OUTPUT);
+    rt_pin_write(pin, PIN_LOW);
+    rt_hw_us_delay(2);
+    rt_pin_write(pin, PIN_HIGH);
+    rt_pin_mode(pin, PIN_MODE_INPUT);
+    /* maybe 12us, maybe 5us, whatever...I have no idea */
+    rt_hw_us_delay(5);
+
+    if(rt_pin_read(pin))
+        data = 1;
+    else
+        data = 0;
+
+    rt_hw_us_delay(50);
+
+    return data;
+}
+
+static uint8_t ds18b20_read_byte(rt_base_t pin)
+{
+    uint8_t i, j, dat;
+    dat = 0;
+
+    for (i = 1; i <= 8; i++)
+    {
+        j = ds18b20_read_bit(pin);
+        dat = (j << 7) | (dat >> 1);
+    }
+
+    return dat;
+}
+
+static void ds18b20_write_byte(rt_base_t pin, uint8_t dat)
+{
+    uint8_t j;
+    uint8_t testb;
+    rt_pin_mode(pin, PIN_MODE_OUTPUT);
+
+    for (j = 1; j <= 8; j++)
+    {
+        testb = dat & 0x01;
+        dat = dat >> 1;
+
+        if(testb)
+        {
+            rt_pin_write(pin, PIN_LOW);
+            rt_hw_us_delay(2);
+            rt_pin_write(pin, PIN_HIGH);
+            rt_hw_us_delay(60);
+        }
+        else
+        {
+            rt_pin_write(pin, PIN_LOW);
+            rt_hw_us_delay(60);
+            rt_pin_write(pin, PIN_HIGH);
+            rt_hw_us_delay(2);
+        }
+    }
+}
+
+void ds18b20_start(rt_base_t pin)
+{
+    ds18b20_reset(pin);
+    ds18b20_connect(pin);
+    ds18b20_write_byte(pin, 0xcc);  /* skip rom */
+    ds18b20_write_byte(pin, 0x44);  /* convert */
+}
+
+uint8_t ds18b20_init(rt_base_t pin)
+{
+    uint8_t ret = 0;
+
+    ds18b20_reset(pin);
+    ret = ds18b20_connect(pin);
+
+    return ret;
+}
+
+int32_t ds18b20_get_temperature(rt_base_t pin)
+{
+    uint8_t TL, TH;
+    int32_t tem;
+    
+    ds18b20_start(pin);
+    ds18b20_init(pin);
+    ds18b20_write_byte(pin, 0xcc);
+    ds18b20_write_byte(pin, 0xbe);
+    TL = ds18b20_read_byte(pin);    /* LSB first */
+    TH = ds18b20_read_byte(pin);
+    if (TH > 7)
+    {
+        TH =~ TH;
+        TL =~ TL;
+        tem = TH;
+        tem <<= 8;
+        tem += TL;
+        tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
+        return -tem;
+    }
+    else
+    {
+        tem = TH;
+        tem <<= 8;
+        tem += TL;
+        tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
+        return tem;
+    }
+}
+
+static rt_size_t _ds18b20_polling_get_data(rt_sensor_t sensor, struct rt_sensor_data *data)
+{
+    rt_int32_t temperature_x10;
+    if (sensor->info.type == RT_SENSOR_CLASS_TEMP)
+    {
+        temperature_x10 = ds18b20_get_temperature((rt_base_t)sensor->config.intf.user_data);
+        data->data.temp = temperature_x10;
+        data->timestamp = rt_sensor_get_ts();
+    }    
+    return 1;
+}
+
+static rt_size_t ds18b20_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len)
+{
+    RT_ASSERT(buf);
+
+    if (sensor->config.mode == RT_SENSOR_MODE_POLLING)
+    {
+        return _ds18b20_polling_get_data(sensor, buf);
+    }
+    else
+        return 0;
+}
+
+static rt_err_t ds18b20_control(struct rt_sensor_device *sensor, int cmd, void *args)
+{
+    rt_err_t result = RT_EOK;
+
+    return result;
+}
+
+static struct rt_sensor_ops sensor_ops =
+{
+    ds18b20_fetch_data,
+    ds18b20_control
+};
+
+int rt_hw_ds18b20_init(const char *name, struct rt_sensor_config *cfg)
+{
+    rt_int8_t result;
+    rt_sensor_t sensor_temp = RT_NULL; 
+    
+    if (!ds18b20_init((rt_base_t)cfg->intf.user_data))
+    {
+        /* temperature sensor register */
+        sensor_temp = rt_calloc(1, sizeof(struct rt_sensor_device));
+        if (sensor_temp == RT_NULL)
+            return -1;
+
+        sensor_temp->info.type       = RT_SENSOR_CLASS_TEMP;
+        sensor_temp->info.vendor     = RT_SENSOR_VENDOR_DALLAS;
+        sensor_temp->info.model      = "ds18b20";
+        sensor_temp->info.unit       = RT_SENSOR_UNIT_DCELSIUS;
+        sensor_temp->info.intf_type  = RT_SENSOR_INTF_ONEWIRE;
+        sensor_temp->info.range_max  = SENSOR_TEMP_RANGE_MAX;
+        sensor_temp->info.range_min  = SENSOR_TEMP_RANGE_MIN;
+        sensor_temp->info.period_min = 5;
+
+        rt_memcpy(&sensor_temp->config, cfg, sizeof(struct rt_sensor_config));
+        sensor_temp->ops = &sensor_ops;
+
+        result = rt_hw_sensor_register(sensor_temp, name, RT_DEVICE_FLAG_RDONLY, RT_NULL);
+        if (result != RT_EOK)
+        {
+            LOG_E("device register err code: %d", result);
+            goto __exit;
+        }
+
+    }
+    return RT_EOK;
+    
+__exit:
+    if (sensor_temp)
+        rt_free(sensor_temp);
+    return -RT_ERROR;     
+}