/*
* 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
Comments | NOTHING