chrisrh 发表于 2022-3-7 12:55

[GD32L233C] + 7.在RTthread下使用ds18b20温度传感器

本帖最后由 chrisrh 于 2022-3-7 12:55 编辑

<p><span style="font-size:16px;">在RTT_Nano的基础上,增加对ds18b20传感器的读取:</span></p>

<p><strong><span style="font-size:16px;"><span style="color:#e67e22;">①首先在头文件中进行宏定义,这里选用的是PB8口</span></span></strong></p>

<pre>
<code class="language-cpp">#define DS18B20_CLK                               RCU_GPIOB
#define DS18B20_COM_GPIO_PORT       GPIOB
#define DS18B20_COM_GPIO_PIN       GPIO_PIN_8
#define DS18B20_IO_IN        {GPIO_CTL(GPIOB)&amp;=0xFFFFFFF3;GPIO_CTL(GPIOB)|=0&lt;&lt;8;}
#define DS18B20_IO_OUT        {GPIO_CTL(GPIOB)&amp;=0xFFFFFFF3;GPIO_CTL(GPIOB)|=1&lt;&lt;8;}
#define DS18B20_Pin_ongpio_bit_set(DS18B20_COM_GPIO_PORT, DS18B20_COM_GPIO_PIN)//GPIO_BOP(DS18B20_COM_GPIO_PORT) = DS18B20_COM_GPIO_PIN;
#define DS18B20_Pin_offgpio_bit_reset(DS18B20_COM_GPIO_PORT, DS18B20_COM_GPIO_PIN)//GPIO_BC(DS18B20_COM_GPIO_PORT) = DS18B20_COM_GPIO_PIN;
#define DS18B20_get               gpio_input_bit_get(DS18B20_COM_GPIO_PORT, DS18B20_COM_GPIO_PIN)
void DS18B20_config_init();</code></pre>

<p><strong><span style="font-size:16px;"><span style="color:#e67e22;">②对IO进行初始化</span></span></strong></p>

<pre>
<code class="language-cpp">/*!
    \brief      configure DS18B20_Pin
*/
void DS18B20_config_init()
{
    /* enable the DS18B20 clock */
    rcu_periph_clock_enable(DS18B20_CLK);
    /* configure DS18B20 GPIO port */
    gpio_mode_set(DS18B20_COM_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DS18B20_COM_GPIO_PIN);
    gpio_output_options_set(DS18B20_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, DS18B20_COM_GPIO_PIN);
    gpio_bit_set(DS18B20_COM_GPIO_PORT, DS18B20_COM_GPIO_PIN);//GPIO_BC(DS18B20_COM_GPIO_PORT) = DS18B20_COM_GPIO_PIN;
}</code></pre>

<p><strong><span style="font-size:16px;"><span style="color:#e67e22;">③使用了rtthread传感器中关于ds18b20相关的文件,头文件sensor_dallas_ds18b20.h如下:</span></span></strong></p>

<pre>
<code class="language-cpp">#ifndef __DS18B20_H__
#define __DS18B20_H__

#include &lt;rthw.h&gt;
#include &lt;rtthread.h&gt;
#include "gd32l23x.h"
#include "gd32l233c_start.h"

#define CONNECT_SUCCESS0
#define CONNECT_FAILED   1

struct ds18b20_device
{
    rt_base_t pin;
    rt_mutex_t lock;
};
typedef struct ds18b20_device *ds18b20_device_t;

void ds18b20_reset(void);
uint8_t ds18b20_connect(void);
uint8_t ds18b20_read_bit(void);
uint8_t ds18b20_read_byte(void);
void ds18b20_write_byte(uint8_t dat);
void ds18b20_start(void);
uint8_t ds18b20_init(void);
int32_t ds18b20_get_temperature(void);


#endif /* __DS18B20_H_ */</code></pre>

<p><strong><span style="font-size:16px;"><span style="color:#e67e22;">④使用了rtthread传感器中关于ds18b20相关的文件,驱动函数sensor_dallas_ds18b20.c如下:</span></span></strong></p>

<pre>
<code class="language-cpp">
#include "sensor_dallas_ds18b20.h"
#include &lt;rtthread.h&gt;
#include "gd32l23x.h"
#include "gd32l233c_start.h"
#include &lt;rtdbg.h&gt;
#include "systick.h"

#define DBG_TAG "sensor.dallas.ds18b20"
#define DBG_LVL DBG_INFO

#define SENSOR_TEMP_RANGE_MAX (125)
#define SENSOR_TEMP_RANGE_MIN (-55)

void ds18b20_reset(void)
{
    DS18B20_IO_OUT;
    DS18B20_Pin_off;
    delay_1us(780);               /* 480us - 960us */
    DS18B20_Pin_on;
    delay_1us(40);                /* 15us - 60us*/
}

uint8_t ds18b20_connect(void)
{
    uint8_t retry = 0;
    DS18B20_IO_IN;

    while (DS18B20_get &amp;&amp; retry &lt; 200)
    {
      retry++;
      delay_1us(1);
    };

    if(retry &gt;= 200)
      return CONNECT_FAILED;
    else
      retry = 0;

    while (!DS18B20_get &amp;&amp; retry &lt; 240)
    {
      retry++;
      delay_1us(1);
    };

    if(retry &gt;= 240)
      return CONNECT_FAILED;

    return CONNECT_SUCCESS;
}

uint8_t ds18b20_read_bit(void)
{
    uint8_t data;

    DS18B20_IO_OUT;
    DS18B20_Pin_off;
    delay_1us(2);
    DS18B20_Pin_on;
    DS18B20_IO_IN;
    /* maybe 12us, maybe 5us, whatever...I have no idea */
    delay_1us(5);

    if(DS18B20_get)
      data = 1;
    else
      data = 0;

    delay_1us(50);

    return data;
}

uint8_t ds18b20_read_byte(void)
{
    uint8_t i, j, dat;
    dat = 0;

    for (i = 1; i &lt;= 8; i++)
    {
      j = ds18b20_read_bit();
      dat = (j &lt;&lt; 7) | (dat &gt;&gt; 1);
    }

    return dat;
}

void ds18b20_write_byte(uint8_t dat)
{
    uint8_t j;
    uint8_t testb;
    DS18B20_IO_OUT;

    for (j = 1; j &lt;= 8; j++)
    {
      testb = dat &amp; 0x01;
      dat = dat &gt;&gt; 1;

      if(testb)
      {
            DS18B20_Pin_off;
            delay_1us(2);
            DS18B20_Pin_on;
            delay_1us(60);
      }
      else
      {
            DS18B20_Pin_off;
            delay_1us(60);
            DS18B20_Pin_on;
            delay_1us(2);
      }
    }
}

void ds18b20_start(void)
{
    ds18b20_reset();
    ds18b20_connect();
    ds18b20_write_byte(0xcc);/* skip rom */
    ds18b20_write_byte(0x44);/* convert */
}

uint8_t ds18b20_init(void)
{
    uint8_t ret = 0;

    ds18b20_reset();
    ret = ds18b20_connect();

    return ret;
}

int32_t ds18b20_get_temperature()
{
    uint8_t TL, TH;
    int32_t tem;
   
    ds18b20_start();
    ds18b20_init();
    ds18b20_write_byte(0xcc);
    ds18b20_write_byte(0xbe);
    TL = ds18b20_read_byte();    /* LSB first */
    TH = ds18b20_read_byte();
    if (TH &gt; 7)
    {
      TH =~ TH;
      TL =~ TL;
      tem = TH;
      tem &lt;&lt;= 8;
      tem += TL;
      tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
      return -tem;
    }
    else
    {
      tem = TH;
      tem &lt;&lt;= 8;
      tem += TL;
      tem = (int32_t)(tem * 0.0625 * 10 + 0.5);
      return tem;
    }
}
</code></pre>

<p><strong><span style="font-size:16px;"><span style="color:#e67e22;">⑤在main.c中定义线程和入口函数:</span></span></strong></p>

<pre>
<code class="language-cpp">#include "gd32l23x.h"
#include "systick.h"
#include "rtthread.h"
#include "gd32l233c_start.h"
#include "stdio.h"
#include "sensor_dallas_ds18b20.h"

rt_thread_t temp_thread = RT_NULL;
static void temp_thread_entry(void *parameter);//temperature

int main(void)
{
       temp_thread = rt_thread_create( "temp",                   /*线程名字*/
                                temp_thread_entry,                /*线程入口函数*/
                                RT_NULL,                        /*线程入口函数参数*/
                                256,                            /*线程栈大小*/
                                6 ,                                    /*线程优先级*/
                                20);                                   /*线程时间片*/
}

static void temp_thread_entry(void *parameter)
{        int temp;
        while(1)
        {
                rt_kprintf("temp:");
                temp = ds18b20_get_temperature();
                printf("%d\r\n",temp);
                rt_thread_delay(1000);
        }
}


/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
        usart_data_transmit(USART0, (uint8_t) ch );            //发送字符
        while (usart_flag_get(USART0,USART_FLAG_TC) == RESET);   //检查是否发送完毕
        return (ch);
}</code></pre>

<p><strong><span style="font-size:16px;"><span style="color:#e67e22;">⑥在finsh_port.c中添加了如下函数,方便在finsh中调用:</span></span></strong></p>

<pre>
<code class="language-cpp">void ds18b20_get_val(void)
{               
                extern rt_thread_t temp_thread;
                rt_thread_startup (temp_thread);
                rt_kprintf("temp_thread startup\r\n");
                rt_thread_delay(1000);
}
MSH_CMD_EXPORT(ds18b20_get_val, control ds18b20 thread start);//将该函数添加进入finsh,方便以后调用
</code></pre>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:20px;"><span style="color:#e74c3c;"><strong>!!在rtthread中的一个关于us的延时函数,</strong></span></span><strong style="color: rgb(231, 76, 60); font-size: 20px;">加入工程中即可使用us的延时</strong></p>

<pre>
<code class="language-cpp">void rt_hw_us_delay(uint32_t us)
{
                uint32_t start,now,delta,reload,us_tick;
                start = SysTick-&gt;VAL;
                reload = SysTick-&gt;LOAD;
                us_tick = SystemCoreClock / 1000000UL;
        do{
                now = SysTick-&gt;VAL;
                delta = start&gt;now?start-now:reload + start -now;
        }while(delta&lt;us_tick*us);
}</code></pre>

<p>&nbsp;</p>

<p>&nbsp;</p>

Jacktang 发表于 2022-3-7 21:10

<p>中间的驱动函数sensor_dallas_ds18b20.c是官网例程么</p>

freebsder 发表于 2022-3-7 22:27

<p>不应该是do while(0)吗?</p>

chrisrh 发表于 2022-3-8 08:38

Jacktang 发表于 2022-3-7 21:10
中间的驱动函数sensor_dallas_ds18b20.c是官网例程么

<p>嗯,是的!</p>

chrisrh 发表于 2022-3-8 08:39

freebsder 发表于 2022-3-7 22:27
不应该是do while(0)吗?

<p>嗯嗯,程序还有许多别的问题,<img height="28" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/face-with-finger-covering-closed-lips_1f92b.png" width="28" /></p>

wangerxian 发表于 2022-3-8 17:12

<p>RTThread就是好,这些常用的都直接有库了。想给公司也搞一个驱动库,可以直接用的那种~</p>

chrisrh 发表于 2022-3-8 17:25

wangerxian 发表于 2022-3-8 17:12
RTThread就是好,这些常用的都直接有库了。想给公司也搞一个驱动库,可以直接用的那种~

<pre>
<code class="language-cpp">/* Sensor types */

#define RT_SENSOR_CLASS_NONE         (0)
#define RT_SENSOR_CLASS_ACCE         (1)/* Accelerometer   */
#define RT_SENSOR_CLASS_GYRO         (2)/* Gyroscope         */
#define RT_SENSOR_CLASS_MAG            (3)/* Magnetometer      */
#define RT_SENSOR_CLASS_TEMP         (4)/* Temperature       */
#define RT_SENSOR_CLASS_HUMI         (5)/* Relative Humidity */
#define RT_SENSOR_CLASS_BARO         (6)/* Barometer         */
#define RT_SENSOR_CLASS_LIGHT          (7)/* Ambient light   */
#define RT_SENSOR_CLASS_PROXIMITY      (8)/* Proximity         */
#define RT_SENSOR_CLASS_HR             (9)/* Heart Rate      */
#define RT_SENSOR_CLASS_TVOC         (10) /* TVOC Level      */
#define RT_SENSOR_CLASS_NOISE          (11) /* Noise Loudness    */
#define RT_SENSOR_CLASS_STEP         (12) /* Step sensor       */
#define RT_SENSOR_CLASS_FORCE          (13) /* Force sensor      */

/* Sensor vendor types */

#define RT_SENSOR_VENDOR_UNKNOWN       (0)
#define RT_SENSOR_VENDOR_STM         (1)/* STMicroelectronics */
#define RT_SENSOR_VENDOR_BOSCH         (2)/* Bosch */
#define RT_SENSOR_VENDOR_INVENSENSE    (3)/* Invensense */
#define RT_SENSOR_VENDOR_SEMTECH       (4)/* Semtech */
#define RT_SENSOR_VENDOR_GOERTEK       (5)/* Goertek */
#define RT_SENSOR_VENDOR_MIRAMEMS      (6)/* MiraMEMS */
#define RT_SENSOR_VENDOR_DALLAS      (7)/* Dallas */

/* Sensor unit types */

#defineRT_SENSOR_UNIT_NONE         (0)
#defineRT_SENSOR_UNIT_MG             (1)/* Accelerometer         unit: mG         */
#defineRT_SENSOR_UNIT_MDPS         (2)/* Gyroscope               unit: mdps       */
#defineRT_SENSOR_UNIT_MGAUSS         (3)/* Magnetometer            unit: mGauss   */
#defineRT_SENSOR_UNIT_LUX            (4)/* Ambient light         unit: lux      */
#defineRT_SENSOR_UNIT_CM             (5)/* Distance                unit: cm         */
#defineRT_SENSOR_UNIT_PA             (6)/* Barometer               unit: pa         */
#defineRT_SENSOR_UNIT_PERMILLAGE   (7)/* Relative Humidity       unit: permillage */
#defineRT_SENSOR_UNIT_DCELSIUS       (8)/* Temperature             unit: dCelsius   */
#defineRT_SENSOR_UNIT_HZ             (9)/* Frequency               unit: HZ         */
#defineRT_SENSOR_UNIT_ONE            (10) /* Dimensionless quantityunit: 1          */
#defineRT_SENSOR_UNIT_BPM            (11) /* Heart rate            unit: bpm      */
#defineRT_SENSOR_UNIT_MM             (12) /* Distance                unit: mm         */
#defineRT_SENSOR_UNIT_MN             (13) /* Force                   unit: mN         */

/* Sensor communication interface types */

#defineRT_SENSOR_INTF_I2C            (1 &lt;&lt; 0)
#defineRT_SENSOR_INTF_SPI            (1 &lt;&lt; 1)
#defineRT_SENSOR_INTF_UART         (1 &lt;&lt; 2)
#defineRT_SENSOR_INTF_ONEWIRE      (1 &lt;&lt; 3)

/* Sensor power mode types */

#defineRT_SENSOR_POWER_NONE          (0)
#defineRT_SENSOR_POWER_DOWN          (1)/* power down mode   */
#defineRT_SENSOR_POWER_NORMAL      (2)/* normal-power mode */
#defineRT_SENSOR_POWER_LOW         (3)/* low-power mode    */
#defineRT_SENSOR_POWER_HIGH          (4)/* high-power mode   */</code></pre>

<p><span style="color:#e74c3c;">in&nbsp; &nbsp;&quot;sensor.h&quot;</span></p>

<p>消化吸收,先变成自己的,再变成公司适用的,<img height="28" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/face-with-rolling-eyes_1f644.png" width="28" /></p>

<p>一起学习RTT呀!</p>

wangerxian 发表于 2022-3-9 09:30

chrisrh 发表于 2022-3-8 17:25
/* Sensor types */

#define RT_SENSOR_CLASS_NONE         (0)
#define RT_SENSOR_CLASS_ACCE   ...

<p>得找到一种合适得接口,到时候可以封装成.lib的库用。</p>
页: [1]
查看完整版本: [GD32L233C] + 7.在RTthread下使用ds18b20温度传感器