【蓝桥杯单片机进阶强化-05】超声波测距
内容学习来自小蜜蜂老师
一、超声波测距原理
超声波发射模块向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。
二、计算公式
距离 = 声速 × 发出超声波到接收返回的时间/2
因为超声波在空气中的传播速度受温度影响。声波在空气中的传播速度与温度的关系是:
在20摄氏度时,声速V = 332 + 0.607t (m/s)
利用超声波进行距离测量,要求精度一般都不高,取20摄氏度时候的声速344M/S进行计算,再进行适当的补偿就可以。所以,其计算公式为:距离L = 344M/S * T / 2 = 172M/S * T
三、测距步骤
1-产生8个40KHz的超声波信号,通过TX引脚发射出去。
2-启动定时器,计算计数脉冲。
3-等待超声波信号返回,如果接收到反射回来的信号,RX引脚变为低电平。
4-停止定时器,读取脉冲个数,即获得时间T。
5-根据公式,L = V * T /2m,进行距离的计算。
四、代码实现
#include "reg52.h"
#include "intrins.h"
/********************************************
Date:2022-1-19
Author:小殷同学
Base Learn From:B 站小蜜蜂老师
*********************************************/
sbit TX = P1^0;
sbit RX = P1^1;
unsigned int Time = 0;
unsigned int dis = 0;
#define somenop() {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
//共阳数目管段码
unsigned char month = 0; //定义一个变量让其变化显示
//0-f 0xbf代表 -
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xbf};
//---------------------------------简单延时函数-------------------------
void delay(unsigned int t)
{
while(t--);
}
void Delay12us() //@12.000MHz 延时12us
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
//-------------------------------74HC138初始化---------------------------
void Init_74HC138(unsigned char n)
{
switch(n)
{
case 4:P2 = P2| 0x1f; P2 = 0x80; break;
case 5:P2 = P2| 0x1f; P2 = 0xa0; break;
case 6:P2 = P2| 0x1f; P2 = 0xc0; break;
case 7:P2 = P2| 0x1f; P2 = 0xe0; break;
case 0:P2 = P2| 0X1f; P2 = 0x00; break; //所有锁存器都不选择
}
}
//----------------------------------系统初始化---------------------------
void InitSystem(void)
{
Init_74HC138(5);
P0 = 0x00; //关闭继电器与蜂鸣器
Init_74HC138(4);
P0 = 0xff; //关闭led
}
//---------------------------------数码管安位显示--------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
Init_74HC138(6);
P0 = 0x01 << pos ;//位选
Init_74HC138(7);
P0 = dat; //段码
}
//-------------------------------关闭所有数码管----------------------
void SMG_CLOSEALL(unsigned char dat)
{
Init_74HC138(6);
P0 = 0xff; //选中所有数码管
Init_74HC138(7);
P0 = dat; //关闭
}
void SMG_Display_Dynamic(void)
{
SMG_DisplayBit(0,0xff);
delay(200);
SMG_DisplayBit(1,0xff);
delay(200);
SMG_DisplayBit(2,0xff);
delay(200);
SMG_DisplayBit(3,0xff);
delay(200);
SMG_DisplayBit(4,0xff);
delay(200);
SMG_DisplayBit(5,SMG_Duan[dis/100]);
delay(200);
SMG_DisplayBit(6,SMG_Duan[dis/10%10]);
delay(200);
SMG_DisplayBit(7,SMG_Duan[dis%10]);
delay(200);
SMG_CLOSEALL();
delay(200);
}
//--------------------------------------发出声波----------------------------------
void SendWave(void)
{
unsigned char i;
for(i = 0; i < 8;i++)
{
TX = 1;
somenop();
TX = 0;
somenop();
}
}
//------------------------------------超声波测距----------------------------------
void Ultrasonic_Dis(void)
{
TMOD &= 0x0f; //定时器1模式0 13位最大值8192
TH1 = 0x00;
TL1 = 0x00;
TF1 = 0; //溢出标志位
TR1 = 0;
SendWave(); //发送声波信号
TR1 = 1;//启动定时
while(RX == 1 && TF1 == 0); //等待超声波信号返回或者等到测量超出范围 返回RX = 0
TR1 = 0;//停止计时
if(TF1 == 1) //溢出了还没有返回信号
{
TF1 = 0;
dis = 999;
}
else
{
//接收到了返回信号 将定时时间合成16位
Time = (TH1 << 8) | TL1; //总时间
//dis = ((Time / 10) * 17) / 100 + 3;
dis = Time * 0.0172;
}
}
//------------------------------------------------------------------------------------
void Delay_SMG( unsigned char t)
{
while(t--)
{
SMG_Display_Dynamic();
}
}
void main(void)
{
InitSystem();
while(1)
{
Ultrasonic_Dis();
Delay_SMG(50);
}
}
上面代码测距有误差
dis = ((Time / 10) * 17) / 100 + 3; 这个是按老师写的 实现的最大为207 这句代码有点没有理解 望大佬指点