18B20

发布于 2022-10-11  13 次阅读


/*
 * 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 "main.h"
#define DS18B20_FUNCTION
#ifdef DS18B20_FUNCTION

#define CONNECT_SUCCESS  0
#define CONNECT_FAILED   1


typedef  uint32_t rt_uint32_t ;
typedef  uint16_t rt_uint16_t ;
typedef  uint8_t rt_uint8_t ;
typedef long    rt_base_t;


struct pin_index
{
    int index;
    GPIO_TypeDef *gpio;
    uint32_t pin;
};

#define __STM32_PIN(index, gpio, gpio_index)                                \
    {                                                                       \
        index, GPIO##gpio, GPIO_PIN_##gpio_index                            \
    }


struct ds18b20_device
{
    rt_base_t pin;
		int temp;
};
typedef struct ds18b20_device *ds18b20_device_t;

uint8_t ds18b20_init(rt_base_t pin);
int32_t ds18b20_get_temperature(rt_base_t pin);
void Robot_DS18B20_update(void);
//int rt_hw_ds18b20_init(const char *name, struct rt_sensor_config *cfg);

#endif

#endif /* __DS18B20_H_ */


/*
 * 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.
 * 2020-07-28     WillianChan     add ds18b20 init error message
 */

#include "ds18b20.h"
#include <stdlib.h>
#include <stdio.h>



#ifdef DS18B20_FUNCTION

#define DS18B20_DEBUG 1

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


#define PIN_MODE_OUTPUT 1
#define PIN_MODE_INPUT 0
#define PIN_HIGH 1
#define PIN_LOW 0


/** 函数名:rt_hw_us_delay
  * 功能	:微秒延时
  * 输入	:延时时间(微秒)
	* 输出	:NULL
	* 编写人:ZJ
  */
void rt_hw_us_delay(uint32_t us)
{
    uint32_t start, now, delta, reload, us_tick;
    start = SysTick->VAL;
    reload = SysTick->LOAD;
    us_tick = SystemCoreClock / 1000000UL;
    do {
        now = SysTick->VAL;
        delta = start > now ? start - now : reload + start - now;
    } while(delta < us_tick * us);
}

//void rt_hw_us_delay(rt_uint32_t us)
//{
//  uint32_t cnt = us*100; 
//  uint32_t i = 0;

//	for(i=0;i<cnt;i++)__NOP();
//}


static const struct pin_index pins[] = 
{
	__STM32_PIN(0, C, 8),
//	__STM32_PIN(1, D, 1),
};

static void rt_pin_mode(rt_base_t pin,rt_uint8_t mode)
{
		const struct pin_index *index;
    GPIO_InitTypeDef GPIO_InitStruct;

    index = &pins[pin];
    /* Configure GPIO_InitStructure */
    GPIO_InitStruct.Pin = index->pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    if (mode == 1)
    {
        /* output setting */
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
    }
    else if (mode == 0)
    {
        /* input setting: not pull. */
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
    }
    HAL_GPIO_Init(index->gpio, &GPIO_InitStruct);

}

static void rt_pin_write(rt_base_t pin, rt_base_t value)
{
	   const struct pin_index *index;

    index = &pins[pin];
    HAL_GPIO_WritePin(index->gpio, index->pin, (GPIO_PinState)value);
}

static int rt_pin_read(rt_base_t pin)
{
	int value;
    const struct pin_index *index;

    value = 0;

    index = &pins[pin];
    value = HAL_GPIO_ReadPin(index->gpio, index->pin);

    return value;

}

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(12);

    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;
		portENTER_CRITICAL();
    for (i = 1; i <= 8; i++)
    {
        j = ds18b20_read_bit(pin);
        dat = (j << 7) | (dat >> 1);
    }
		portEXIT_CRITICAL();
    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);
		portENTER_CRITICAL();
    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);
        }
    }
		portEXIT_CRITICAL();
}

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);
    if(ds18b20_init(pin) == CONNECT_FAILED)
			return 0xfffff;
    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;
    }
}

__IO uint32_t ds18b20_temp = 0;

void Robot_DS18B20_update(void)
{
	ds18b20_temp = ds18b20_get_temperature(0);
	#if DS18B20_DEBUG
	
	lwlog_debug("temp:%d.",ds18b20_temp);
	
	#endif

}


#endif

一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。