wangji12 发表于 2020-5-28 14:21

RTOS】+ RT-Thread + 雅特力AT_START_F403A_V1开发板-sensor移植

本帖最后由 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模数转换的传感器就移植成功了。
页: [1]
查看完整版本: RTOS】+ RT-Thread + 雅特力AT_START_F403A_V1开发板-sensor移植