;利用超声波测距,都是统计超声波发出_到_接收的时间,然后再换算成距离 ;对于时间的统计,通常都是使用计数器完成 ;超声波发射后,启动计数器,收到回波后,取出计数值进行换算 ; ;51单片机内部的计数器,是对机器周期进行计数的 ;它的数值,和距离之间,有什么关系呢 ? ;-------------------------------------------------------- ;当晶振频率是 12MHz,它的机器周期正好是 1us ;所以,单片机计数器中的计数值即代表微秒的个数 ; ;假设声波的速度是 333m/s,那么,用微秒数除以 6,马上即可得到距离的毫米数 ;即,计数器中的值为: 0~65535,除以 6 后,距离即为: 0~10922(mm) ; ;推导如下: ; ; 1s 对应路程 0.333 km = 1/3 km ; 1ms 对应路程 0.333 m = 1/3 m ; 1us 对应路程 0.333 mm = 1/3 mm ; ; 1us : 距离 1/6 mm ; 6us : 距离 1 mm ; ; 1/6,即为每个机器周期T(即微秒)代表的距离数值(mm) ; ;-------------------------------------------------------- ;当晶振频率是 11.0592MHz,它的机器周期则是 1.085us ;(T = 12 / 11.0592 = 1 / 0.9216 = 1.0850694444...us) ; ;时间长了,路程就远了,如果仍然按照除以 6 计算,得出的结果将偏小 ;仍然这么算,好像是把声速降低了,降为:0.3072mm/us ; ;那么,用机器周期的个数乘以 1.085/6,才能得出正确的距离毫米数值 ; ; 1.085/6,即为每个机器周期T(@11.0592MHz)的距离(mm) ; ;-------------------------------------------------------- ;空气中的声速和环境温度、气压都有关系,并不一定总是 333m/s ;一般来说,310~345m/s 都是合理的数值 ;因此,计算距离,算法并不是唯一的 ; ;在网上,可以买到多种超声波测距的实验板,其中的程序的算法,花样百出 ;有除以 59 (或 60) 得出厘米数的;也有先乘以 17,再除以 100 的; ;还有一个是乘以 12,再除以 58 的,这么算,其声速已经是 400 多米了 ! ;只是因为它的测距范围较小,误差虽大,也难以看出来。 ; ;其实,除以 6,是最简单、准确的算法 ;做而论道已经用了多年,在网上却没有见到一个 ! 呵呵 ;-------------------------------------------------------- ;很多人都是用 C 语言编程,编程虽省事,单片机执行起来却要多费时 ;网上的多数程序,算出来距离,再送去显示,都要用几个甚至上百毫秒 ;这么低的效率,使得多检测几次取平均值的想法,都不好实现 ; ;其实,用汇编语言编程,效率是最高的 ;两个字节除以 6,编写一个两字节除以一字节的程序,仅仅用 300 多微秒(12MHz)即可 ; ;两个字节乘以 1.085/6,这就要费点心思,仔细琢磨琢磨算法了... ;最好是把分子、分母同时扩大多少多少倍,找个好算的数字... ;除以 6,并非是容易计算的,学过二进制的都知道,右移一位,就是除以 2 ;除以 2、4、...,2 的整数倍,计算起来才是最简单的 ;除以 256,那就最简单了 ; ;好吧,那就先乘以 43,再除以 256,这就和乘以 1/6 相差无几了 ;这种算法,声速是 335m/s;在 11.0592MHz 时,声速相当于 309.6m/s,偏小 ; ;乘以 1.085/6,又该怎样算呢? ;看看下表吧: ;--------------------------------------------------- ; 算法 | 结果距离(mm) | 相当于声速(m/s) ;----------+--------------+---@12MHz----+-@11.0592-- ; 1 / 6 | 0.16666... | 333.333... | 307.2 ; 41 / 256 | 0.16015625 | 320.3125 | 295.2 ; 42 / 256 | 0.1640625 | 328.125 | 302.4 ; 43 / 256 | 0.16796875 | 335.9375 | 309.6 ; 44 / 256 | 0.171875 | 343.75 | 316.8 ; 45 / 256 | 0.17578125 | 351.5625 | 324.0 ; 46 / 256 | 0.1796875 | 359.375 | 331.2 ; 47 / 256 | 0.18359375 | 367.1875 | 338.4 ; 48 / 256 | 0.1875 | 375.00 | 345.6 ; 49 / 256 | 0.19140625 | 382.8125 | 352.8 ;--------------------------------------------------- ; ;这个表,表示出了计算因子和声速的关系 ;这个表,是用 EXCEL 算出来的,百度的格式有点乱,能看明白吗 ? ;如果是 12MHz,可以乘以 42、43 或 44 ;如果是 11.0592MHz,可以乘以 46、47 或 48 ;在表中,可看出不同的取值所对应的声速 ; ;把两个字节的计数值,乘以 47,可以得到三个字节 ;除以 256,那就太简单了,算都不用算,直接把最低 8 位扔掉就完了 ;剩下的两个字节,就是乘以 47,再除以 256 的结果 ;程序如下: ;-------------------------------------------------------- VAR_SOUND EQU 47 ;42, 43, 44 适用于 12MHz ;46, 47, 48 适用于 11.0592MHz ;入口:R2R3 = 0~65535 ;出口:R2R3 = R2R3 * 47 / 256 ≈ R2R3 * 1.085/6 R23DIV6: MOV A, R3 MOV B, #VAR_SOUND MUL AB ; MOV R3, A ;低八位就不要了 MOV R3, B ;R3 = (R3 * 47)的高八位 MOV A, R2 MOV B, #VAR_SOUND MUL AB ;R2 * 47 ADD A, R3 ;加上刚才的 MOV R3, A ;R3 = (R2R3 * 47)的中八位 CLR A ADDC A, B MOV R2, A ;R2 = (R2R3 * 47)的高八位 RET ;全部程序共 23T ;-------------------------------------------------------- ;这是计算距离的最快算法 ;做而论道仅仅才用了 23 微秒(12MHz),就能达到别人需要几千微秒才能达到的目的 ; ;这个程序,甚至比前面所说的除以 6,还要快近十倍 ; ;程序中,VAR_SOUND 的数值,可以根据实际情况的需要进行选择 ;也可以用一个寄存器,根据当时检测的温度进行变化,进行温度修正 ; ;本程序,距离计算的精度是最高的 ;合理选择 VAR_SOUND 的值,如 46、47、48,再按照这个算法来计算 ;理论上的量化误差是 (1/256)/2 = 1/512,即小于千分之二 ;其它的算法,虽然各有各的理由,但是计算的结果,精度绝不会比这个用汇编写的高 ;--------------------------------------------------------
超声波测距的最快算法
最新推荐文章于 2024-07-15 07:59:27 发布