打印
[uCOS/RTOS]

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

[复制链接]
1198|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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模数转换的传感器就移植成功了。

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

9

帖子

0

粉丝