前言
对接rt-thread的sensor组件编写记录
DS18B20驱动
头文件
# 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
源文件
# 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)
static void ds18b20_reset ( ds18b20_device_t dev) {
DS18B20_IO_OUT ( ) ;
DS18B20_OUT_L ( ) ;
DS18B20_US_DELAY ( 750 ) ;
DS18B20_OUT_H ( ) ;
DS18B20_US_DELAY ( 15 ) ;
}
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 ( ) ;
DS18B20_OUT_L ( ) ;
DS18B20_US_DELAY ( 2 ) ;
DS18B20_OUT_H ( ) ;
DS18B20_IO_IN ( ) ;
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 ( ) ;
for ( j = 1 ; j <= 8 ; j++ ) {
testb = value & 0x01 ;
value = value >> 1 ;
if ( testb) {
DS18B20_OUT_L ( ) ;
DS18B20_US_DELAY ( 2 ) ;
DS18B20_OUT_H ( ) ;
DS18B20_US_DELAY ( 60 ) ;
} else {
DS18B20_OUT_L ( ) ;
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 ) ;
ds18b20_write_byte ( dev, 0x44 ) ;
}
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;
}
float ds18b20_temperature_read ( ds18b20_device_t dev) {
uint16_t temp;
uint8_t a, b;
float value;
ds18b20_start ( dev) ;
ds18b20_reset ( dev) ;
ds18b20_check ( dev) ;
ds18b20_write_byte ( dev, 0xcc ) ;
ds18b20_write_byte ( dev, 0xbe ) ;
a = ds18b20_read_byte ( dev) ;
b = ds18b20_read_byte ( dev) ;
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;
}
对接传感器组件
头文件
# 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
源文件
# 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) ;
测试结果