关于超声波测距计算
关于超声波测距计算,我正在玩超声波测距,按照说明书计算方法无法正常显示,求高手解惑这是串口收到三个字节,说明书说通过下面的计算得到距离,
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;
}
}
}
求高手看看什么原因
在超声波测距应用中,距离的计算通常基于超声波从发射到接收的时间差(即飞行时间,Time of Flight, ToF)。根据你提供的信息,你正在使用串口接收到的三个字节来计算距离,但遇到了无法正常显示的问题。以下是对该问题的详细分析和解决方案。
1. 超声波测距原理
超声波测距的基本原理是通过发射超声波脉冲,并测量其从发射到接收的时间差。根据声速和飞行时间,可以计算出目标物体与传感器之间的距离。公式如下:
\[ \text{距离} = \frac{\text{声速} \times \text{飞行时间}}{2} \]
其中,声速在常温下约为343米/秒(或34300厘米/秒),飞行时间通常以微秒(μs)为单位。
2. 数据处理与计算
根据你提供的信息,串口接收到的三个字节用于计算飞行时间。假设这三个字节分别代表时间的高位、中位和低位,那么飞行时间可以通过以下方式计算:
```c
u32 time1, time;
time = ((RX2DATA
[本文内容由国芯人工智能辅助生成,仅供参考] 发现部分超声波测距模块发送完会输出一个脉冲干扰,程序处理时要跳过,具体建议用逻辑分析仪测一下输出的信号
以下是我几年前写的语音超声波测距程序,外挂语音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;
}
RX2_DATA数组定义用的是u8?
定义个u32 TEMP
TEMP = (u32)RX2_DATA
再移位TEMP 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]