rtthread-TMF8801激光测距芯片

一、芯片介绍

TMF8801是2019年艾迈斯半导体推出的用于测量直接飞行时间(dToF)距离的集成式模块,这个传感器测量范围是2cm至2500cm。亮的环境下能达到2.4m,暗环境下能够测量到2.5m,但是在2cm以下测量数据不准备,距离比2cm要短。相比VL53L0X测距模块测量距离和精度确实要好很多。

二、引脚定义

三、驱动流程

1、项目开发使用了RTT实时操作系统,因此会使用到模拟I2C驱动跟传感器驱动框架,首先注册I2C总线设备驱动及传感器驱动。

1)使能I2C接口及定义I2C引脚号,初始化I2C引脚,注册I2C总线设备驱动

#define RT_USING_I2C
#define RT_USING_I2C_BITOPS
#define BSP_USING_I2C2
#define BSP_I2C2_SCL_PIN			GET_PIN(B,10)
#define BSP_I2C2_SDA_PIN			GET_PIN(B,11)

/* I2C initialization function */
int rt_hw_i2c_init(void)
{
    rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct stm32_i2c);
    rt_err_t result;

    for (int i = 0; i < obj_num; i++)
    {
        i2c_obj[i].ops = stm32_bit_ops_default;
        i2c_obj[i].ops.data = (void *)&soft_i2c_config[i];
        i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
        stm32_i2c_gpio_init(&i2c_obj[i]);
        result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
        RT_ASSERT(result == RT_EOK);
        stm32_i2c_bus_unlock(&soft_i2c_config[i]);

       
    }

    return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_i2c_init);

2)注册传感器设备驱动

int rt_hw_tof_tmf8x0x_init(char *name, struct rt_sensor_config *cfg)
{
    rt_err_t ret = RT_EOK;
    rt_sensor_t tof_sensor = RT_NULL;

    /* 找到I2C总线设备 */
    i2c_bus_dev = rt_i2c_bus_device_find(cfg->intf.dev_name);
    if (i2c_bus_dev == RT_NULL)
    {
        LOG_E("i2c bus device %s not found!\r\n", cfg->intf.dev_name);
        ret = -RT_ERROR;
    }
    tof_i2c_addr = (((uint32_t)cfg->intf.user_data) & 0xff);

    tof_sensor = rt_calloc(1, sizeof(struct rt_sensor_device));
    if (tof_sensor == RT_NULL)
    {
        LOG_E("Can't allocate memory for tof '%s' ", name);
        return -RT_ERROR;
    }


    rt_memset(tof_sensor, 0, sizeof(struct rt_sensor_device));
    tof_sensor->info.type       = RT_SENSOR_CLASS_TOF;
    tof_sensor->info.vendor     = RT_SENSOR_VENDOR_AMS;
    tof_sensor->info.model      = TMF8X0X_DEVICE_NAME;
    tof_sensor->info.unit       = RT_SENSOR_UNIT_MM;
    tof_sensor->info.intf_type  = RT_SENSOR_INTF_I2C;
    tof_sensor->info.range_max  = TMF8X0X_DIST_RANGE_MAX;
    tof_sensor->info.range_min  = TMF8X0X_DIST_RANGE_MIN;
    tof_sensor->info.period_min = TMF8X0X_DIST_PEROID;		/* read ten times in 1 second */
    rt_memcpy(&tof_sensor->config, cfg, sizeof(struct rt_sensor_config));
    tof_sensor->ops = &tmf8x0x_ops;

    ret = rt_hw_sensor_register(tof_sensor, TMF8X0X_DEVICE_NAME, RT_DEVICE_FLAG_RDWR, RT_NULL);
    if (ret != RT_EOK)
    {
        LOG_E("device register err code: %d", ret);
        rt_free(tof_sensor);
        return -RT_ERROR;
    }

    LOG_I("tof tmf8x0x init success");
    return ret;
}

3)实现数据获取及设置操作函数

rt_size_t tof_tmf8x0x_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len)
{
    struct rt_sensor_data *sensor_data = (struct rt_sensor_data *)buf;
    uint8_t  status = 0;
    uint32_t tick   = 0;
    result_info_t tof_result_data = {0};
    if (buf == RT_NULL)
    {
        LOG_E("%s error", __FUNCTION__);
        return 0;
    }
    if (sensor->config.mode == RT_SENSOR_MODE_POLLING)
    {
        status = tof_tmf8801_int_status_get();
        if (status & 0x01)
        {
            /* 发生检测中断 */
            tof_tmf8801_int_status_clr();
            while (1)
            {
                if (tof_tmf8801_result_get(&tof_result_data) == TMF8X0X_OK)
                {
                    break;
                }
                if (++tick >= DEFAULT_RETRY)
                {
                    LOG_E("%s mo!", __FUNCTION__);
                    return 0;
                }
            }
        }

        sensor_data->type = RT_SENSOR_CLASS_TOF;
        sensor_data->timestamp = tof_result_data.time_stamp;
        sensor_data->data.proximity = tof_result_data.distance_peak;
        return len;
    }
    return 0;
}

rt_err_t tof_tmf8x0x_control(struct rt_sensor_device *sensor, int cmd, void *arg)
{
    rt_err_t ret = RT_EOK;
    switch (cmd)
    {
        case RT_SENSOR_CTRL_BL_INIT:
            if (tof_tmf8801_init() != TMF8X0X_OK)
            {
                ret = RT_ERROR;
            }
            break;
        case RT_SENSOR_CTRL_APP0_START:
            if (tof_tmf8801_app0_start((app0_init_config_t *)arg) != TMF8X0X_OK)
            {
                ret = RT_ERROR;
            }
            break;
        case RT_SENSOR_CTRL_APP0_STOP:
            if (tof_tmf8801_app0_stop() != TMF8X0X_OK)
            {
                ret = RT_ERROR;
            }
            break;
        case RT_SENSOR_CTRL_TIMESTAMP_GET:
            if (tof_tmf8x0x_timestamp_get((uint32_t *)arg) != TMF8X0X_OK)
            {
                ret = RT_ERROR;
            }
            break;
        default:
            break;
    }
    return ret;
}

static struct rt_sensor_ops tmf8x0x_ops =
{
    tof_tmf8x0x_fetch_data,
    tof_tmf8x0x_control
};

4)实现tmf8x0x的读写函数

int tof_tmf8x0x_write_regs(uint8_t reg, uint8_t *data, uint16_t data_size)
{
    struct rt_i2c_msg msg[2] = {0};

    if (i2c_bus_dev == RT_NULL)
        return -RT_ERROR;
    /*msg[0]*/
    if (tof_i2c_addr == 0)
        msg[0].addr = TOF_DEFALUT_I2C_ADDR;
    else
        msg[0].addr	= tof_i2c_addr;
    msg[0].flags	= RT_I2C_WR;
    msg[0].len   	= 1;
    msg[0].buf   	= &reg;
    /*msg[1]*/
    if (tof_i2c_addr == 0)
        msg[1].addr = TOF_DEFALUT_I2C_ADDR;
    else
        msg[1].addr	= tof_i2c_addr;
    msg[1].flags	= RT_I2C_WR | RT_I2C_NO_START;
    msg[1].len   	= data_size;
    msg[1].buf   	= data;
    if (rt_i2c_transfer(i2c_bus_dev, msg, ITEM_NUM(msg)) == ITEM_NUM(msg))
    {
        return RT_EOK;
    }
    else
    {
        LOG_E("i2c bus write failed!");
        return -RT_ERROR;
    }
}

int tof_tmf8x0x_read_regs(uint8_t reg, uint8_t *data, uint16_t data_size)
{
    struct rt_i2c_msg msg[2] = {0};

    if (i2c_bus_dev == RT_NULL)
        return -RT_ERROR;

    /*msg[0]*/
    if (tof_i2c_addr == 0)
        msg[0].addr = TOF_DEFALUT_I2C_ADDR;
    else
        msg[0].addr	= tof_i2c_addr;
    msg[0].flags = RT_I2C_WR;
    msg[0].len   = 1;
    msg[0].buf   = &reg;
    /*msg[1]*/
    if (tof_i2c_addr == 0)
        msg[1].addr = TOF_DEFALUT_I2C_ADDR;
    else
        msg[1].addr	= tof_i2c_addr;
    msg[1].flags = RT_I2C_RD;
    msg[1].len   = data_size;
    msg[1].buf   = data;

    if (rt_i2c_transfer(i2c_bus_dev, msg, ITEM_NUM(msg)) == ITEM_NUM(msg))
    {
        return RT_EOK;
    }
    else
    {
        LOG_E("i2c bus read failed!");
        return -RT_ERROR;
    }
}

2、模块初始化,在bootload中将固件下载到ram中,然后从ram中启动tmf8x0x固件,实现测距,具体参考编程手册。

BOOTLOAD寄存器地址及命令

BL_CMD_STAT (Address 0x08)

BL_SIZE (Address 0x09)

BL_DATA (Address 0x0A-0x8A)

BL_DATA (Address 0x0A-0x8A)

1)模块复位(寄存器地址:0xE0)

/**
 * \brief TMF8801 复位
 */
static int8_t tof_tmf8x0x_rst(void)
{
    uint8_t  regval = 0;
    uint32_t tick   = 0;

    regval = TMF8X0X_CPU_RESET_OSC_ENABLE;
    tof_tmf8x0x_write_regs(TMF8X0X_ENABLE_REG, &regval, 1);
    rt_thread_mdelay(2);
    while (1)
    {
        /* wait CPU ready */
        regval = 0;
        tof_tmf8x0x_read_regs(TMF8X0X_ENABLE_REG, &regval, 1);
        if (regval == TMF8X0X_CPU_READY_AND_IDLE)
        {
            break;
        }
        if (++tick >= DEFAULT_RETRY)
        {
            LOG_E("%s tmo!", __FUNCTION__);
            return TMF8X0X_NK;
        }
    }
    return TMF8X0X_OK;
}

2)初始化下载 HW(寄存器地址:0x08)

/**
 * \brief 初始化下载 HW
 */
static int8_t tof_tmf8x0x_download_init(void)
{
    /*
     * cmd_buf[0]    : 初始化下载 HW 命令(0x14)
     * cmd_buf[1]    : 数据长度(0x01)
     * cmd_buf[3]    : 1个字节数据
     * cmd_buf[4]    : 校验字节
     */
    uint8_t  cmd_buf[] = {0x14, 0x01, 0x29, 0xC1};
    uint32_t tick = 0;

    tof_tmf8x0x_write_regs(TMF8X0X_BOOT_COMMAND_REG, cmd_buf, ITEM_NUM(cmd_buf));
    rt_thread_delay(1);
    while (1)
    {
        if (tof_tmf8x0x_status_read() == TMF8X0X_OK)
        {
            break;
        }
        if (++tick >= DEFAULT_RETRY)
        {
            LOG_E("%s tmo!", __FUNCTION__);
            return TMF8X0X_NK;
        }
    }
    return TMF8X0X_OK;
}

3)设置写 RAM 地址(寄存器首地址:0x08)

/**
 * \brief 设置写 RAM 地址
 */
static int8_t tof_tmf8x0x_set_ram_addr(uint16_t addr)
{
    /*
     * cmd_buf[0]    : 写 RAM 地址命令(0x43)
     * cmd_buf[1]    : 数据长度(0x02)
     * cmd_buf[4:3]  : 2个字节数据
     * cmd_buf[5]    : 校验字节
     */
    uint8_t  cmd_buf[5] = {0};
    uint32_t tick       =  0;

    cmd_buf[0] = 0x43;
    cmd_buf[1] = 0x02;
    cmd_buf[2] = (uint8_t)addr;         /* 地址低 8 位 */
    cmd_buf[3] = (uint8_t)(addr >> 8);  /* 地址高 8 位 */
    /* 校验字节 */
    cmd_buf[4] = tof_tmf8x0x_checksum(cmd_buf, (ITEM_NUM(cmd_buf) - 1));

    tof_tmf8x0x_write_regs(TMF8X0X_BOOT_COMMAND_REG, cmd_buf, ITEM_NUM(cmd_buf));
    rt_thread_delay(1);
    while (1)
    {
        if (tof_tmf8x0x_status_read() == TMF8X0X_OK)
        {
            break;
        }
        if (++tick >= DEFAULT_RETRY)
        {
            LOG_E("%s tmo!", __FUNCTION__);
            return TMF8X0X_NK;
        }
    }
    return TMF8X0X_OK;
}

4)写 RAM数据(寄存器首地址:0x08)

/**
 * \brief 写 RAM
 */
static int8_t tof_tmf8x0x_write_ram(const uint8_t *app_buf, uint16_t len)
{
    /*
     * cmd_buf[0]    : 命令(0x41)
     * cmd_buf[1]    : 数据长度(0x10)
     * cmd_buf[17:2] : 16个字节数据
     * cmd_buf[18]   : 校验字节
     */
    uint8_t  cmd_buf[APP_WRITE_ONE_LEN + 3] = {0};
    uint16_t buf_remain_len = len;        /* app_buf 总字节个数 */
    uint16_t write_index = 0;
    uint16_t buf_line_len = 0;        		/* app_buf 行地址 */
    uint32_t tick = 0;

    cmd_buf[0] = 0x41;                     	/* 写 RAM */
    while (buf_remain_len)
    {
        /* 计算待写数据长度 */
        if (buf_remain_len >= ITEM_NUM(cmd_buf) - 3)
        {
            buf_line_len = ITEM_NUM(cmd_buf) - 3;
        }
        else
        {
            buf_line_len = buf_remain_len;
        }
        cmd_buf[1] = buf_line_len;

        /* 装载命令数据缓存区 */
        for (uint32_t i = 0; i < buf_line_len; i++)
        {
            cmd_buf[2 + i] = app_buf[write_index + i];
        }

        /* 计算偏移索引及剩余数据 */
        write_index += buf_line_len;
        buf_remain_len -= buf_line_len;

        /* 计算校验字节 */
        cmd_buf[buf_line_len + 2] = tof_tmf8x0x_checksum(cmd_buf, (buf_line_len + 2));

        /* 写 RAM */
        tof_tmf8x0x_write_regs(TMF8X0X_BOOT_COMMAND_REG, cmd_buf, buf_line_len + 3);
        rt_thread_delay(1);

        /* 读状态寄存器 */
        while (1)
        {
            if (tof_tmf8x0x_status_read() == TMF8X0X_OK)
            {
                break;
            }
            if (++tick >= DEFAULT_RETRY)
            {
                LOG_E("%s tmo!", __FUNCTION__);
                return TMF8X0X_NK;
            }
        }
    }
    return TMF8X0X_OK;
}

5)重映射 RAM 到地址 0 并复位

/**
 * \brief 重映射 RAM 到地址 0 并复位
 */
static int8_t tof_tmf8x0x_ram_remap_rst(void)
{
    /*
     * cmd_buf[0]    : RAM 地址重映射并复位命令(0x11)
     * cmd_buf[1]    : 数据长度(0x00)
     * cmd_buf[2]    : 校验字节
     */
    uint8_t  cmd_buf[] = {0x11, 0x00, 0xEE};
    uint8_t  regval    =  0;
    uint32_t tick      =  0;

    tof_tmf8x0x_write_regs(TMF8X0X_BOOT_COMMAND_REG, cmd_buf, ITEM_NUM(cmd_buf));
    rt_thread_delay(1);
    while (1)
    {
        /* wait CPU ready */
        tof_tmf8x0x_read_regs(TMF8X0X_ENABLE_REG, &regval, 1);
        if (regval == TMF8X0X_CPU_READY_AND_IDLE)
        {
            break;
        }
        if (++tick >= DEFAULT_RETRY)
        {
            LOG_E("%s tmo!", __FUNCTION__);
            return TMF8X0X_NK;
        }
    }
    return TMF8X0X_OK;
}

6)获取 TMF8801 信息,包括读取APP0 主版本号(寄存器地址:0x01),读取次版本号和修订版本号(寄存器地址:0x12),读取芯片修订 ID(寄存器地址:0xE4),生成序列号(寄存器地址:0x10),读取序列号(寄存器地址:0x1E)

/**
 * \brief 获取 TMF8801 信息
 */
static int8_t tof_tmf8x0x_info_read(void)
{
    uint8_t  app0_rev_num[3] = {0};
    uint8_t  chip_rev_id     =  0;
    uint8_t  serial_num[4]   = {0};

    uint8_t  regval          =  0;
    uint32_t tick            =  0;

    /* APP0 主版本号 */
    tof_tmf8x0x_read_regs(TMF8X0X_APPREV_MAJOR_REG, &app0_rev_num[0], 1);

    /* 次版本号和修订版本号 */
    tof_tmf8x0x_read_regs(TMF8X0X_APPREV_MINOR_REG, &app0_rev_num[1], 2);

    /* 芯片修订 ID */
    tof_tmf8x0x_read_regs(TMF8X0X_CHIPREV_REG, &chip_rev_id, 1);

    /* 序列号 */
    regval = SERIAL_NUM;                                  /* 发送读序列号命令 */
    tof_tmf8x0x_write_regs(TMF8X0X_COMMAND_REG, &regval, 1);

    while (1)
    {
        /* 等待序列号生成完毕 */
        tof_tmf8x0x_read_regs(TMF8X0X_CONTENTS_REG, &regval, 1);
        if (regval == SERIAL_NUM)
        {
            break;
        }
        if (++tick >= DEFAULT_RETRY)
        {
            LOG_E("%s tmo!", __FUNCTION__);
            return TMF8X0X_NK;
        }
    }
    tof_tmf8x0x_read_regs(TMF8X0X_STATE_DATA_0_REG, serial_num, ITEM_NUM(serial_num));

    /* 打印 */
    LOG_I("Serial Number: %02x-%02x-%02x-%02",
          serial_num[0], serial_num[1], serial_num[2], serial_num[3]);
    LOG_I("App0 Revision: %d.%d.%d",
          app0_rev_num[0], app0_rev_num[1], app0_rev_num[2]);
    LOG_I("Chip Revision: %d", chip_rev_id);

    return TMF8X0X_OK;
}

7)使能检测中断

/******************************************************************************/
void tof_tmf8801_intx_enable(void)
{
    uint8_t regval = 0x01;
    tof_tmf8x0x_write_regs(TMF8X0X_INT_ENABLE_REG, &regval, 1);
}

3、配置APP0写入校准数据(寄存器地址:0x20)

/******************************************************************************/
int8_t tof_tmf8801_app0_start(app0_init_config_t *p_config)
{
    /*
     * cmd_data7=03  Algorithm state and factory calibration is provided
     * cmd_data6=23
     * cmd_data5=00  No GPIO control used
     * cmd_data4=00  No GPIO control used
     * cmd_data3=00  Object detection threshold
     * cmd_data2=64  Repetition period in ms 64 hex = 100ms
     * cmd_data1=84  Number of iterations, low byte; 1 LSB=1 k
     * cmd_data0=03  Number of iterations, high byte; Set to 900k iterations
     * command  =02  Set flag to perform target distance measurement with 8
     *               bytes of data containing where including setting of
     *               calibration (and algorithm state) configuration.
     */
#ifdef TMF8801
    uint8_t cmd_buf[9] = {0x03, 0x23, 0x00, 0x00, 0x00, 0x32, 0xD8, 0x04, 0x02};
#else
    uint8_t cmd_buf[9] = {0x00, 0xA3, 0x00, 0x00, 0x00, 0x64, 0x84, 0x03, 0x02};
#endif

    uint8_t  cali_ok   =  0;
    uint8_t  regval    =  0;
    uint8_t  i         =  0;

    tof_tmf8x0x_read_regs(TMF8X0X_ENABLE_REG, &regval, 1);
    if (regval != TMF8X0X_CPU_READY_AND_IDLE)
    {
        /* CPU 没准备好与主机 IIC 通信 */
        return TMF8X0X_NK;
    }

    /* 配置 APP0 相关参数 */
    if (p_config != RT_NULL)
    {
        cmd_buf[0] = p_config->calibration_state_mask;
        cmd_buf[2] = p_config->gpio_control;
        cmd_buf[3] = p_config->gpio_output_control;
        cmd_buf[5] = p_config->repetition_period_ms;
        cmd_buf[6] = p_config->iterations & 0xFF;
        cmd_buf[7] = (p_config->iterations >> 8) & 0xFF;
    }

    /* 预装载工厂校准数据或算法状态数据 */
    if (cmd_buf[0] & FACTORY_CALIBRATION_PROVIDE)
    {
        /* 提供了工厂校准数据 */
#if 0
        if (eepromRead(CALI_STA_ADDR, &cali_ok, 1) != EE_SUCCESS)
        {
            return TMF8X0X_NK;
        }
        if (cali_ok == 0xAA)
        {
            /* 执行过工厂校准 */
            if (eepromRead(CALI_DATA_ADDR, g_cali_buf, 14) != EE_SUCCESS)/* 读取工厂校准数据 */
            {
                return TMF8X0X_NK;
            }
        }
#endif

        tof_tmf8x0x_write_regs(TMF8X0X_FACTORY_CALIB_0_REG, g_cali_buf, ITEM_NUM(g_cali_buf));/* 写入 14 字节校准数据 */

        if (cmd_buf[0] & ALGORITHM_STATE_PROVIDE)
        {
            /* 提供了算法状态数据 */
            tof_tmf8x0x_write_regs(TMF8X0X_STATE_DATA_WR_0_REG, g_state_buf, ITEM_NUM(g_state_buf));/* 写入 11 字节算法状态数据 */
        }
    }
    else if (cmd_buf[0] & ALGORITHM_STATE_PROVIDE)
    {
        /* 提供了算法状态数据 */
        tof_tmf8x0x_write_regs(TMF8X0X_FACTORY_CALIB_0_REG, g_state_buf, ITEM_NUM(g_state_buf));/* 写入 11 字节算法状态数据 */
    }

    tof_tmf8x0x_write_regs(TMF8X0X_BOOT_COMMAND_REG, cmd_buf, ITEM_NUM(cmd_buf));/* 配置 TOF 功能并启动 */

    LOG_I("start config APP0:"); /* 回显打印 */
    for (i = 0; i < 9; i++)
    {
        LOG_RAW("%02x ", cmd_buf[i]);
    }
    LOG_RAW("\r\n");

    return TMF8X0X_OK;
}

三.应用校准晶振偏差及获取数据

1)找到设备并初始化设备

temp_dev = rt_device_find("tof_tmf8x0x");
if (temp_dev == RT_NULL)
{
	rt_kprintf("not found tof_tmf8x0x device\r\n");
	tmf8x0x_running = RT_FALSE;
}

if (rt_device_open(temp_dev, RT_DEVICE_FLAG_RDONLY) != RT_EOK)
{
	rt_kprintf("open tof_tmf8x0x failed\r\n");
	tmf8x0x_running = RT_FALSE;
}

if (rt_device_control(temp_dev, RT_SENSOR_CTRL_BL_INIT, RT_NULL) != RT_EOK)
{
	LOG_E("tmf8x0x init error!");
	tmf8x0x_running = RT_FALSE;
}

/* 配置app0*/
config.calibration_state_mask = FACTORY_CALIBRATION_PROVIDE;//提供了工厂校准数据
config.repetition_period_ms = 100;//重复测量周期为100ms
config.iterations           = 900;//迭代次数 900k
if (rt_device_control(temp_dev, RT_SENSOR_CTRL_APP0_START, (void *)&config) != RT_EOK)
{
	LOG_E("tmf8801_app0_start error!\r\n");
	tmf8x0x_running = RT_FALSE;
}

2)晶振频偏比例值计算

/* 计算晶振频偏比列*/
rt_thread_delay(1000);
if (rt_device_control(temp_dev, RT_SENSOR_CTRL_TIMESTAMP_GET, (void *)&tmf8x0x_time_start) == RT_EOK)
{
	sys_time_start = clock_cpu_microsecond(clock_cpu_gettime());
	rt_thread_delay(6000);
	if (rt_device_control(temp_dev, RT_SENSOR_CTRL_TIMESTAMP_GET, (void *)&tmf8x0x_time_end) == RT_EOK)
	{
		sys_time_end = clock_cpu_microsecond(clock_cpu_gettime());
		if (sys_time_start < sys_time_end)
			sys_time_interval = sys_time_end - sys_time_start;
		else
			sys_time_interval = clock_cpu_microsecond(0xffffffff) - sys_time_start + sys_time_end;
		LOG_D("sys_time_interval :%d", sys_time_interval);

		if (tmf8x0x_time_start < tmf8x0x_time_end)
			tmf8x0x_time_interval = tmf8x0x_time_end - tmf8x0x_time_start;
		else
			tmf8x0x_time_interval = 0xffffffff - tmf8x0x_time_start + tmf8x0x_time_end;
		tmf8x0x_time_interval /= 5;
		LOG_D("tmf8x0x_time_interval :%d", tmf8x0x_time_interval);

		if (tmf8x0x_time_interval != 0)
		{
			osc_freq_bias = sys_time_interval / (tmf8x0x_time_interval * 1.0);
			osc_freq_bias_flag = 1;
			LOG_I("osc_freq_bias :%d", (uint32_t)(osc_freq_bias * 10000));
		}
	}
}

3)获取传感器数据

res = rt_device_read(temp_dev, 0, &temp_data, 1);
if (res == 0)
{
	rt_kprintf("read data failed! result is %d\n", res);;
}
else
{
	if (osc_freq_bias_flag == 1)
		temp_data.data.proximity *= osc_freq_bias;
	read_sample_dist[read_dist_index++] = temp_data.data.proximity & 0xffff;
	LOG_D("distance[%dmm],timestamp[%d]", temp_data.data.proximity, temp_data.timestamp);
	if (read_dist_index >= TOF_TMF8X0X_SAMPLE_TOTAL_NUM)
	{
		/* 读取数据排序 */
		bubble_sort(read_sample_dist, TOF_TMF8X0X_SAMPLE_TOTAL_NUM);
		/* 删除最高跟最低获取平均数 */
		read_average_dist = average_get(read_sample_dist, TOF_TMF8X0X_SAMPLE_TOTAL_NUM, TOF_TMF8X0X_SAMPLE_DEL_NUM);
		LOG_I("average distance[%dmm]", read_average_dist);
		read_dist_index = 0;
	}
}

四 结果

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值