TMF8801的频偏校正

前言

        tmf8801是一个飞行时间(ToF)激光测距传感器,通过测量光波的脉冲差测量距离。能够在±5%范围内进行高精度距离测量,并且能够在黑暗环境和有阳光的情况下运行。

        tmf8801 内部算法是按照 5MHz 的晶振频率进行计算的,但实际上 tmf8801内部晶振 频率有偏差,并不是准确的 5MHz,这就会给距离测量带来误差。因此为了使测量结果更准确, 有必要对 tmf8801输出的距离值进行频偏校正。

一、原理分析

        tmf8801 有一个 32 位的计数器按照内部晶振频率一直向上计数,并且这个计数器可供 主机读取,因此主机可以通过获取该计数值并和外部标准时间刻度比较来计算频偏因子。

二、实现方法

    有两种方法可获取tmf8801 的频偏因子:第一种方法是主机设置一个固定周期T的定时器,在定时器中断服务函数里获取tmf8801的时间戳,第一次中断获取的时间戳为t1,第二次中断获取到时间戳为t2,则可算出频偏因子为(t2-t1)/T;第二种方法是主机设置一个计数器,在第一次获取tmf8801的距离值的时候,同时获取自身的时间戳 t_host_1 和tmf8801 的时间戳 t_tof_1,第二次获取tmf8801的距离值的时候,再同时获取自身的时间 戳 t_host_2 和 TMF8x01 的 时 间 戳 t_tof_2 , 则可算出频偏因子为 (t_tof_2-t_tof_1)/(t_host_2-t_host_1)。以下结合代码分析两种方法的实现。

1.方法1:通过主机定时器终端计算频偏因子

void MRT0_IRQHandler(void)
{
	static uint32_t tof_timestamp_t1 = 0;
	static uint32_t tof_timestamp_t0 = 0;
	static uint8_t cnt               = 0;
	
	if(MRT0->CHANNEL[0].STAT & (1 << 0)) //通道0中断
	{
		cnt++;
		if(tof_timestamp_get(&tof_timestamp_t1) == TMF8x01_OK)
		{
			g_freq_bias_fac  = (tof_timestamp_t1 - tof_timestamp_t0)/(5000000.0*cnt);
			tof_timestamp_t0 = tof_timestamp_t1;
			cnt = 0;
		}
	    MRT0->CHANNEL[0].STAT |= (1 << 0); //清除通道0中断标志
	}
	
}

       这种方法主机设置了一个 1s 的定时器,每隔 1s 会进一次定时器中断服务函数,定时器 中断服务函数如图2所示,其中 tof_timestamp_t0 是一秒前tmf8801 的时间戳, tof_timestamp_t1 是现在 tmf8801 的时间戳,也就是说如果tmf8801 内部晶振是标准的 5MHz 的话,那么 tof_timestamp_t1-tof_timestamp_t0 应该等于 5000000。另外考虑到并不是 每次获取tmf8801 时间戳都会成功,所以程序中利用 cnt 将获取失败的次数累加起来,那 么从正确获取到 tof_timestamp_t0 开始,到下一次正确获取到 tof_timestamp_t1 时, tof_timestamp_t1-tof_timestamp_t0 应该等于 5000000*cnt,这样就得出了计算频偏因 子的公式。

2.方法2:通过查询主机时间戳计算频偏因子

static uint32_t std_tikcs0 = 0;
static uint32_t std_tikcs1 = 0;
static uint32_t tof_tikcs0 = 0;
static uint32_t tof_tikcs1 = 0;
uint8_t result_buf[0x3A - 0x1D + 1] = {0};
uint8_t regval                      =  0;
uint16_t distance = 0;
double result = 1.0;
static double pre = 1.0;
double err = 0;

my_iic_read(TMF8x01_REGADDR_STATUS, &regval, 1);
my_iic_read(TMF8x01_REGADDR_CONTENTS, &regval, 1);
if (regval != 0x55)
{
    return TMF8x01_ENORES;
}

if (my_iic_read(0x1d, result_buf, 0x3A - 0x1D + 1) == -1) 
{
    return TMF8x01_NK;
}

if (result_buf[0x20 - 0x1d] == p_res->result_num) 
{
    return TMF8x01_ENONEWRES;
}

p_res->result_num        = result_buf[0x20 - 0x1d];
p_res->reliability       = result_buf[0x21 - 0x1d] & 0x3F;
p_res->distance_peak     = ((uint16_t)result_buf[0x23 - 0x1d] << 8)
                             + result_buf[0x22 - 0x1d];
p_res->time_stamp        = ((uint32_t)result_buf[0x27 - 0x1D] << 24) |
                               ((uint32_t)result_buf[0x26 - 0x1D] << 16) |
                               ((uint32_t)result_buf[0x25 - 0x1D] << 8)  |
                               ((uint32_t)result_buf[0x24 - 0x1D] << 0);
p_res->xtalk             = ((uint16_t)result_buf[0x30 - 0x1d]<<8)
    		                   + result_buf[0x31 - 0x1d];

p_res->reference_hits    = ((uint32_t)result_buf[0x36 - 0x1d] << 24) |
                               ((uint32_t)result_buf[0x35 - 0x1d] << 16) |
                               ((uint32_t)result_buf[0x34 - 0x1d] << 8)  |
                               ((uint32_t)result_buf[0x33 - 0x1d] << 0);

p_res->object_hits       = ((uint32_t)result_buf[0x3A - 0x1d] << 24) |
                               ((uint32_t)result_buf[0x39 - 0x1d] << 16) |
                               ((uint32_t)result_buf[0x38 - 0x1d] << 8)  |
                               ((uint32_t)result_buf[0x37 - 0x1d] << 0);

std_tikcs1 = my_sct_count_get();
tof_tikcs1 = p_res->time_stamp;

g_freq_bias_fac = ((double)(tof_tikcs1 - tof_tikcs0)/5)/
                  ((double)(std_tikcs1 - std_tikcs0));
tof_tikcs0 = tof_tikcs1;
std_tikcs0 = std_tikcs1;
p_res->distance_cal = (p_res-distance_peak == 1)?
                    1:p_res-distance_peak/g_freq_bias_fac;

总结

     通过对频偏的校正,tmf8801的测量进度会进一步得到提高,但是大家测实验的时候,有没有发现,tmf8801的标称能测量到2.5米,但是实际测量过程中可能只能测到2米到2.2米左右,这里会涉及到例外一个问题,下一章节继续讲解。

   

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小草xyz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值