dongfang 发表于 2025-4-9 19:03:33

关于超声波测距计算

关于超声波测距计算,我正在玩超声波测距,按照说明书计算方法无法正常显示,求高手解惑

这是串口收到三个字节,说明书说通过下面的计算得到距离,


u32time1,time;

time=((RX2_DATA<<16)+(RX2_DATA<<8)+RX2_DATA)/1000;



通过下面函数显示,
void Conut(void)
        {       
                       
                       
                if(time!=time1)
                                {
                                        time1=time;
                                        if(time1<4000)
                                                {
                                                        qian = time1/1000;
                                                        bai= time1%1000/100;
                                                        shi= time1%100/10;       
                                                        ge   = time1%10;
                                               
                                                        OLED_P8x16Ch(40, 0, (qian+16));
                                                        OLED_P8x16Ch(48, 0, (bai+16));
                                                        OLED_P8x16Ch(56, 0, (shi+16));
                                                        OLED_P8x16Ch(64, 0, (ge+16));
                                                }
                               else
                                       {
                                                        OLED_P8x16Ch(40, 0, (13));
                                                        OLED_P8x16Ch(48, 0, (13));
                                                        OLED_P8x16Ch(56, 0, (13));
                                                        OLED_P8x16Ch(64, 0, (13));
                                               time=2100;                       
                                       }
                               }                               
        }
求高手看看什么原因

国芯人工智能 发表于 2025-4-9 19:08:00

在超声波测距应用中,距离的计算通常基于超声波从发射到接收的时间差(即飞行时间,Time of Flight, ToF)。根据你提供的信息,你正在使用串口接收到的三个字节来计算距离,但遇到了无法正常显示的问题。以下是对该问题的详细分析和解决方案。

1. 超声波测距原理
超声波测距的基本原理是通过发射超声波脉冲,并测量其从发射到接收的时间差。根据声速和飞行时间,可以计算出目标物体与传感器之间的距离。公式如下:

\[ \text{距离} = \frac{\text{声速} \times \text{飞行时间}}{2} \]

其中,声速在常温下约为343米/秒(或34300厘米/秒),飞行时间通常以微秒(μs)为单位。

2. 数据处理与计算
根据你提供的信息,串口接收到的三个字节用于计算飞行时间。假设这三个字节分别代表时间的高位、中位和低位,那么飞行时间可以通过以下方式计算:

```c
u32 time1, time;
time = ((RX2DATA

[本文内容由国芯人工智能辅助生成,仅供参考]

DebugLab 发表于 2025-4-9 20:21:36

发现部分超声波测距模块发送完会输出一个脉冲干扰,程序处理时要跳过,具体建议用逻辑分析仪测一下输出的信号
以下是我几年前写的语音超声波测距程序,外挂语音OTP实现的,按需要移植
附超声波测距温度补偿excel计算器
#include <STC8.H>
#include <intrins.h>
#define         TRIG        P30
#define         ECHO        P31
#define         BUSY        P32
#define                DATA        P33
#define                RST                P54
#define                KEY                P55
#define                BANDGAP        1188UL

//                1                2                3                4                5                6                7                8
//                无                一                二                三                四                五                六                七

//                9                10                11                12                13                14                15                16
//                八                九                十                百                点                当前        设置        距离

//                17                18                19                20                21                22                23                24
//                电压        电流        水位        温度        重量        单价        总价        厘米

//                25                26                27                28                29                30                31                32
//                米                伏                安                度                千克        元                零                滴

bit Error;
unsigned int Distance,Voltage;
unsigned char Lenth,Play_Pointer,Buff_Pointer;
unsigned char Number={31,2,3,4,5,6,7,8,9,10};
unsigned char Buff;
unsigned int Integer,Decimal;

/*----------------------------延时10us@STC-Y6@6MHz----------------------------*/
void Delay_10us(void)
{
        unsigned char i;
        i=18;
        while(--i);
}

/*----------------------------延时x10us----------------------------*/
void Delay_x10us(unsigned char x)
{
        while(x--)
                Delay_10us();
}

void Send(unsigned char x)
{
        unsigned char i;
        RST=1;
        Delay_x10us(10);
        RST=0;
        Delay_x10us(10);
        for(i=0;i<x;i++)
        {
                DATA=1;
                Delay_x10us(10);
                DATA=0;
                Delay_x10us(10);
        }
        Delay_x10us(10);
}

void Speak_Function(unsigned char x)
{
        Buff=x;
        Buff_Pointer++;
}

void Speak_Number(unsigned char x)
{
        unsigned char integer_2,integer_1,integer_0,decimal_1,decimal_2,decimal_3;
        integer_2=(unsigned char)(Integer%1000/100);
        integer_1=(unsigned char)(Integer%100/10);
        integer_0=(unsigned char)(Integer%10);
        decimal_1=(unsigned char)(Decimal%1000/100);
        decimal_2=(unsigned char)(Decimal%100/10);
        decimal_3=(unsigned char)(Decimal%10);
        if(integer_2>0)
        {
                Speak_Function(Number);
                Speak_Function(12);
                if(integer_1==0)
                {
                        if(integer_0!=0)
                        {
                                Speak_Function(Number);
                        }
                }
                else
                {
                        Speak_Function(Number);
                }
        }
        else
        {
                if(integer_1>1)
                {
                        Speak_Function(Number);
                }
        }
        if(integer_1>0)
        {
                Speak_Function(11);
        }
        if(integer_0==0)
        {
                if(integer_2==0&&integer_1==0)
                {
                        Speak_Function(Number);
                }
        }
        else
        {
                Speak_Function(Number);
        }
        switch(x)
        {
                case 1:
                        Speak_Function(13);
                        Speak_Function(Number);
                break;
                case 2:
                        Speak_Function(13);
                        Speak_Function(Number);
                        Speak_Function(Number);
                break;
                case 3:
                        Speak_Function(13);
                        Speak_Function(Number);
                        Speak_Function(Number);
                        Speak_Function(Number);
                break;
                default:
                break;
        }
}

void Speak(void)
{
        if(BUSY&&Lenth>0)
        {
                Send(Buff);
                Play_Pointer++;
                if(Play_Pointer==Lenth)
                {
                        Play_Pointer=0;
                        Lenth=0;
                }
        }
}

void Speak_Distance(unsigned int temp)
{
        Buff_Pointer=0;
        Integer=temp/10;
        Decimal=temp%10*100;
        Speak_Function(32);
        Speak_Function(14);
        Speak_Function(16);
        Speak_Number(1);
        Speak_Function(24);
        Lenth=Buff_Pointer;
}

void Speak_Voltage(unsigned int temp)
{
        Buff_Pointer=0;
        Integer=temp/1000;
        Decimal=temp%1000;
        Speak_Function(32);
        Speak_Function(14);
        Speak_Function(17);
        Speak_Number(3);
        Speak_Function(26);
        Lenth=Buff_Pointer;
}

void Trig(void)
{
        TRIG=1;
        Delay_x10us(100);
        TRIG=0;
}

void Init(void)
{
        AUXR&=0x7F;                //设置定时器0时钟12T模式
        TMOD=0x08;                //设置定时器模式:定时器0受INT0控制,16位自动重载模式
        TF0=0;                        //清除定时器0中断标志
        TH0=0;                        //初始化定时器0
        TL0=0;                        //初始化定时器0
        ET0=1;                        //打开定时器0中断
        EA=1;                        //打开总中断
        P3M0=0x00;                //初始化GPIO模式
        P3M1=0x00;                //初始化GPIO模式
        P5M0=0x00;                //初始化GPIO模式
        P5M1=0x00;                //初始化GPIO模式
        DATA=0;                        //初始化GPIO
        RST=0;                        //初始化GPIO
        TRIG=0;                        //初始化GPIO
        Integer=0;                //初始化变量
        Decimal=0;                //初始化变量
        Error=0;                //初始化变量
        ADCCFG=ADC_RESFMT;                //设置ADC转换结果右对齐,设置ADC时钟
        ADC_CONTR=ADC_POWER|15;        //使能ADC
        Delay_x10us(100);
        ADC_CONTR|=ADC_START;        //启动ADC
        while(!(ADC_CONTR&ADC_FLAG));
        Voltage=ADC_RES<<8|ADC_RESL;
        Voltage=BANDGAP*1024UL/Voltage;
        Speak_Voltage(Voltage);
        ADC_CONTR=0x00;
}

void main(void)
{
        Init();
        while(1)
        {
                if(!KEY&&!Lenth)
                {
                        Error=0;
                        TH0=0;
                        TL0=0;
                        Trig();
                        while(!ECHO);
                        TR0=1;
                        while(ECHO);
                        TR0=0;
                        if(Error)
                                Distance=0;
                        else
                        {
                                Distance=TH0;
                                Distance<<=8;
                                Distance|=TL0;
                                Distance*=0.34645;
                        }
                        Speak_Distance(Distance);
                }
                Speak();
        }
}

void Timer0_ISR(void) interrupt 1
{
        TR0=0;
        TH0=0;
        TL0=0;
        Error=1;
}

C_wolf 发表于 2025-4-9 20:24:39

RX2_DATA数组定义用的是u8?

定义个u32 TEMP

TEMP = (u32)RX2_DATA

再移位TEMP

dongfang 发表于 2025-4-10 06:42:19

C_wolf 发表于 2025-4-9 20:24
RX2_DATA数组定义用的是u8?

定义个u32 TEMP

非常感谢,我就是怀疑数据类型的问题,经测试,没问题

        time=(u32)RX2_DATA;
        time3=(u16)RX2_DATA;
        time=((time<<16)+(time3<<8)+RX2_DATA)/1000;

页: [1]
查看完整版本: 关于超声波测距计算