很久没玩硬件了,心想传统手艺不能丢啊,这次设计了个小板子,用于高精度的时间采样~
可并不是我标题党哟,这个小模块能测量皮秒级别的时间差,而这在很多地方都能有应用的,有兴趣的听我继续详细介绍XD
1ps = 10^-12s ,也就是一万亿分之一秒,这是短到窒息的一段时间,即便是以宇宙最快的光速,在1ps的时间里也只能走0.3mm,而要知道光速从上海跑到深圳1200公里只需要4毫秒。
用过单片机的同学都知道,绝大多数的单片机都有定时器的功能,通过计算配置外设寄存器,我们能利用定时器中断来精确测量一段时间。而这个时间的精度是什么决定的呢,答案是MCU时钟的频率。
也就是说,假如我们使用的是1MHz的晶振作为高速时钟(不考虑分频和倍频),那么每个时钟周期就是1us,这也就作为定时器的计数单位 – 开始计时后,每过1us,相应寄存器的值会加1,等中断到来,我们读取最终的计数值,乘以1us的单位,就得到计时的间隔了。
可见,为了提高计时的最小单位,我们就必须用上更高速的时钟,可是单片机的高速时钟都由晶振倍频而来,而晶振的频率是有限的,一般市面上能买到的最高频率为50MHz;另外就算晶振频率够高,单片机能否运行在这么高的主频也是个问题 – Arduino运行在16MHz,高端的ARM单片机也不会超过200MHz,这样算下来,能测量的最小间隔也就是1/200000000 = 5*10^-9s也就是5ns。5ns看起来也还不错,然而事实上,高主频的MCU并不会用来裸跑程序,都会上操作系统,在操作系统内核下,中断的响应一般是控制在ms级别,要综合考虑系统开销,即便ns级的时间也是很难实现的。
那还有什么办法呢?黑科技一般的原子钟,靠的是参考参考原子振动的频率(比如铯的钟跃迁频率是9.1GHz),但我们当然没有办法搞这样的操作😅,所以在ACAM的产品中,他们很聪明地利用芯片内部的逻辑门延迟来以高精度测量时间间隔。
特殊的测量方法使信号通过逻辑门的时间可以被保证非常精确,而最大的测量精度完全取决于内部信号通过逻辑门的传播时间,这个时间一般和电压和温度有关,比如3.3V 和 25°C 时,GP22 的最小分辨率是 90 ps。这次做的模块当中,使用的就是他们家最新的TDC芯片GP22。
介绍具体原理之前,让我们想象一下:假如我用一根导线把Arduino的两个IO连接起来,一个作为输出,一个作为输入,那么当输出脚电平变化的时候,另一个脚会怎么样呢?答案当然是它的电平也会跟着改变啦,但是这不是重点,重点是这个引脚的改变会滞后一段时间,因为信息的传播是有速度上限的,也就是光速,而电场的传播速度当然也是光速;这在日常的使用中我们不会感到在意,但是当我们再对比一下最上面对光速的计算,就会发现,虽然导线很短(几厘米而已),但是这段时间是远大于ps级别的,于是我们就可以通过测量这个延迟,来测量导线的长度~
原理是这样:首先由MCU启动一个假测量信号,程序里面的体现就是向TDC-GP22发一个START脉冲信号,然后MCU向TDC-GP22发一个测量脉冲,也就是其中一个引脚电平变化,该测量脉冲信号先在TDC-GP22的Stop1引脚被接收,再通过测试线缆的传输在TDC-GP22的Stop2引脚被接收,TDC-GP22芯片会计算出测试回波信号在Stop1引脚被接收和在Stop2引脚被接收的时间差(即飞行时间),通过该值乘以光速即可换算得到测试线缆的长度。
具体的测试结果如下,经过校准和拟合之后,精度还是很满意的:
总结
可以测量ps级的时间是很棒,可是这有什么用呢?
用处很多:比如利用激光发射再返回的时间差,我们能制作高精度的激光测距机(实际上TOF的激光雷达原理就是这个);比如利用光在不同介质里面的速度不同,我们可以测量液体的折射率和厚度;比如利用超声波在流动的流体中传播时就载上流体流速的信息,通过接收到的超声波就可以检测出流体的流速,从而换算成流量来制作无接触的流量计;比如Kinect就是基于TOF的深度摄像头系统,等等。
TDC-GP22的资料国内并不多,但是好在官方的文档写的很详细,于是自己调试了两天得到这个结果,中间还是遇到不少困难的。再感慨一下,做硬件和做软件其实真的需要很不一样的两种思维,这把小小爽完,重回身为软件狗的正轨啦哈哈(逃。
硬件电路开源,软件的话等有空写成库了再发