本帖最后由 wangji12 于 2020-5-28 14:22 编辑
sensor框架传感器移植之adc传感器移植 在本应用中导线温度通过NTC热敏电阻器来获取或者通过18B20来获取,环境温湿度通过sht3x来获取。为了可以使用sensor框架对传感器进行统一的管理,需要把传感器注册到sensor中,ops 接口对接、传感器设备注册。 1、使能sensor框架
1、通过menuconfig使能adc1
2、编写获取n通道adc采集函数 static rt_uint32_t thread_get_temperature(rt_base_t channel)
{
rt_uint32_t value,vol;
value = rt_adc_read(adc_dev,channel);
/* 转换为对应电压值 */
vol = value * REFER_VOLTAGE / CONVERT_BITS;
//rt_kprintf("adc[%d]the voltage is :%d.%02d \n",channel,vol / 100, vol % 100);
return vol;
}
3、实现rt_sensor_ops结构体中获取传感器数据和传感器控制函数如下: static struct rt_sensor_ops sensor_ops = { thread_temp_fetch_data,//获取温度传感器数据 thread_temp_control//控制温度传感器数据 }; static rt_size_t thread_temp_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 _threadTemp_polling_get_data(sensor, buf); } else return 0;
} static rt_size_t _threadTemp_polling_get_data(rt_sensor_t sensor, struct rt_sensor_data *data) { if (sensor->info.type == RT_SENSOR_CLASS_TEMP) { data->data.temp = thread_get_temperature((rt_base_t)sensor->config.intf.user_data); data->timestamp = rt_sensor_get_ts(); } return 1;
}
static rt_err_t thread_temp_control(struct rt_sensor_device *sensor, int cmd, void *args) { rt_err_t result = RT_EOK; return result;
} 4、通过rt_hw_threadTemp_init(const char *name, struct rt_sensor_config *cfg)来将ADC温度传感器注册到sensor中 int rt_hw_threadTemp_init(const char *name, struct rt_sensor_config *cfg)
{
rt_int8_t result;
rt_sensor_t sensor_temp = RT_NULL;
if (!threadTemp_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_USER;
sensor_temp->info.model = "ltemp";
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;
}
5、将rt_hw_threadTemp_port注册成组件初始化温度传感器。 static int rt_hw_threadTemp_port(void)
{
uint8_t channel = 0;
struct rt_sensor_config cfg;
cfg.intf.user_data = (void *)channel;
rt_hw_threadTemp_init("thread", &cfg);
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_threadTemp_port);
6、为了便于测试sensor-温度传感器是否移植成功,编写thread_read_temp_sample测试例子,并注册成命令。 static int thread_read_temp_sample(void)
{
rt_device_t dev = RT_NULL;
struct rt_sensor_data sensor_data;
rt_size_t res;
rt_uint8_t get_data_freq = 1; /* 1Hz */
dev = rt_device_find("temp_thread");
if (dev == RT_NULL)
{
return RT_ERROR;
}
if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
{
rt_kprintf("open device failed!\n");
return RT_ERROR;
}
rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)(&get_data_freq));
res = rt_device_read(dev, 0, &sensor_data, 1);
if (res != 1)
{
rt_kprintf("read data failed! result is %d\n", res);
rt_device_close(dev);
return RT_ERROR;
}
else
{
if (sensor_data.data.temp >= 0)
{
rt_kprintf("temp:%d\n" ,sensor_data.data.temp);
}
}
rt_device_close(dev);
return RT_EOK;
}
MSH_CMD_EXPORT_ALIAS(thread_read_temp_sample, read_temp, read threadTemp);
MSH_CMD_EXPORT_ALIAS(thread_read_temp_sample, read_temp, read threadTemp); 7、在shell里执行thread_read_temp_sample命令测试。
至此使用sensor框架读取使用adc模数转换的传感器就移植成功了。 |