rtthread-TMF8801激光测距芯片

news/2024/10/18 7:57:45/

一、芯片介绍

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;elsemsg[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;elsemsg[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;elsemsg[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;elsemsg[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 TMF8801uint8_t cmd_buf[9] = {0x03, 0x23, 0x00, 0x00, 0x00, 0x32, 0xD8, 0x04, 0x02};
#elseuint8_t cmd_buf[9] = {0x00, 0xA3, 0x00, 0x00, 0x00, 0x64, 0x84, 0x03, 0x02};
#endifuint8_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 0if (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;}}
#endiftof_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;elsesys_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;elsetmf8x0x_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;}
}

四 结果


http://www.ppmy.cn/news/248310.html

相关文章

联发科发布天玑920和天玑810 5G移动芯片

MediaTek 发布天玑系列 5G 移动芯片的两款新品&#xff1a;天玑 920 和天玑 810。这两款 5G 移动芯片将为终端带来强劲的性能、出色的影像和更智能的显示技术&#xff0c;为 5G 智能手机用户带来非凡的移动体验。 天玑 920采用高能效 6nm 制程&#xff0c;拥有强悍性能和低功耗…

TMF8801激光测距芯片驱动程序

TMF8801激光测距芯片驱动程序 一、芯片介绍 TMF8801是2019年艾迈斯半导体推出的用于测量直接飞行时间(dToF)距离的集成式模块&#xff0c;号称全球体积最小&#xff08;表示怀疑&#xff0c;不过体积确实非常小&#xff09;。这个传感器可以精准测量0.02m至2.5m范围&#xff…

TX2--TX2介绍

一、性能参数介绍 1、具体参数如下 二、实物 三、架构 1、CPU、GPU、软件架构详见 TX2学习笔记--Tegra架构介绍。 致谢 1、 Hardware For Every Situation&#xff08;官方&#xff09; 2、 TX2学习笔记--Tegra架构介绍

关于ElementPlus中的表单验证

关于ElementPlus中表单的校验规则&#xff0c;官网文档已经给出了&#xff0c;但是没有说明性文字&#xff0c;所以我想来记录一下&#xff0c;给出一些文字说明 ElementPlus中的简单校验 ElementPlus的表单的一般结构是&#xff1a; <el-form><el-form-item>&l…

vue3的api解读-watch

目录 副作用&#xff08;Side Effect&#xff09; 纯粹计算背后的效果【我们做UI时非常需要】 副作用的封装&#xff08;伪代码&#xff09; 副作用失效&#xff08;Invalidate&#xff09;问题 API:WatchEffect Coding&#xff1a;WatchEffect【演示代码】 /src/exampl…

【虚拟机】常用的9款虚拟机软件

&#x1f41a;作者简介&#xff1a;花神庙码农&#xff08;专注于Linux、WLAN、TCP/IP、Python等技术方向&#xff09;&#x1f433;博客主页&#xff1a;花神庙码农 &#xff0c;地址&#xff1a;https://blog.csdn.net/qxhgd&#x1f310;系列专栏&#xff1a;善假于物&#…

RestCloud-新一代(智能)全域数据集成平台

新一代智能全域数据集成平台 一、介绍1.1 企业级数据集成架构面临的痛点1.2 RestCloud说明1.3 重构企业数据融合架构&#xff0c;解决各种复杂、即时、高合规的数据集成需求1.4 (智能)全域数据集成平台1.5 300数据及应用连接器轻松汇聚全域数据 二、产品简介2.1 功能特性2.2 产…

基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建

基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建 文章目录 基于双视角图表示算法的双向人职匹配偏好建模推荐系统构建1. 传统推荐系统模型2. 协同过滤算法3. 基于双视角图表示学习算法的模型构建3.1 数据输入3.2 双视角交互图的构建3.3 混合偏好传播策略3.4 对于双向意…