超声波测距的最快算法

;利用超声波测距,都是统计超声波发出_到_接收的时间,然后再换算成距离
;对于时间的统计,通常都是使用计数器完成
;超声波发射后,启动计数器,收到回波后,取出计数值进行换算
;
;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,即小于千分之二
;其它的算法,虽然各有各的理由,但是计算的结果,精度绝不会比这个用汇编写的高
;--------------------------------------------------------
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值