LanqiaoカップMCUの基本的な知識-----(9)超音波レンジング

LanqiaoカップMCUの基本的な知識-----(9)超音波レンジング

超音波測距の原理:

超音波送信機は、特定の方向に超音波を放射し、発射時間と同時に計時を開始します。超音波は空中を伝播し、途中で障害物に遭遇するとすぐに戻ります。超音波受信機は、反射を受信するとすぐに計時を停止します。波。空気中の超音波の伝播速度は340m / sです。タイマーによって記録された時間tに従って、発射点と障害物の間の距離(s)を計算できます。つまり、s = 340t / 2です。これは、いわゆる時差測距法です。
超音波測距の原理は、既知の空気中の超音波の伝播速度を使用し、音波が障害物に遭遇して送信後に反射する時間を測定し、送信ポイントから障害物までの実際の距離を計算することです。送信と受信の時間差について。超音波測距の原理はレーダーの原理と同じであることがわかります。
距離測定の式は次のように表されます。L= C×T
、ここでLは測定された距離の長さ、Cは空気中の超音波の伝搬速度、Tは測定された距離伝搬の時間差です(Tは放出から受信までの時間値)。
超音波距離測定は、主に反転リマインダー、建設現場、工業用地などでの距離測定に使用されます。現在の距離測定範囲は100メートルに達することができますが、測定精度はセンチメートルのオーダーにしか達しません。
超音波は、指向性の放出が容易で、指向性が高く、強度の制御が容易で、測定対象物と直接接触しないという利点があるため、液高測定の理想的な方法です。正確な液面測定ではミリメートルレベルの測定精度を達成する必要がありますが、現在の家庭用超音波測距特殊集積回路はミリメートルレベルの測定精度にすぎません。

コアコード:

//切记,计算距离不使用分频
sbit TX = P1^0;  //发射引脚
sbit RX = P1^1;  //接收引脚

void main(void)
{
    
    
  cls();
	AUXR = 0x80;
  TMOD = 0x10;  //配置定时器工作模式
  TH0 = 0xcd;
  TL0 = 0xd4;  
  TH1 = 0;
  TL1 = 0;  
  TR0 = 1;  //启动定时器
  EA = 1;
  ET0 = 1;  //打开定时器0中断
  while(1)
  {
    
    
        /** 100毫秒更新一次数据 */
		if(s_flag)
    {
    
    
      s_flag = 0;
      send_wave();  //发送方波信号
      TR1 = 1;  //启动计时
			while((RX == 1) && (TF1 == 0));  //等待收到脉冲,没有计满溢出
			TR1 = 0;  //关闭计时

			//发生溢出
			if(TF1 == 1)
			{
    
    
				TF1 = 0;
				distance = 9999;  //无返回
			}
			else
			{
    
    
				/**  计算时间  */
				time=TH1*256+TL1;
				distance = (unsigned int)(time*0.017);  //计算距离				
			}
			TH1 = 0;
			TL1 = 0;
    }
	}
}
//12us
void Delay12us()//@11.0592MHz
{
    
    
	unsigned char i;

	_nop_();
	_nop_();
	_nop_();
	i = 30;
	while (--i);
}

void send_wave()//发送八段脉冲波(40Khz)
{
    
    
	unsigned char i = 8;
	
	while(i --)
	{
    
    
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
}

試験結果:
ここに画像の説明を挿入

コード全体を貼り付けます

#include <stc15f2k60s2.h>
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int
	
sbit TX = P1^0;  //发射引脚
sbit RX = P1^1;  //接收引脚
uchar tab[] = {
    
     0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff};
uchar dspbuf[] = {
    
    10,10,10,10,10,10,10,10};
uint distance,time = 0;
uchar s_flag = 0;

void display();
void load();
void Delay12us();
void send_wave();

void cls()
{
    
    
	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;
	P2 = 0x1f;
	
	P2 = (P2 & 0x1f) | 0xa0;
	P0 = 0x00;
	P2 = 0x1f;
}

void main(void)
{
    
    
  cls();
	AUXR = 0x80;
  TMOD = 0x10;  //配置定时器工作模式
  TH0 = 0xcd;
  TL0 = 0xd4;  
  TH1 = 0;
  TL1 = 0;  
  TR0 = 1;  //启动定时器
  EA = 1;
  ET0 = 1;  //打开定时器0中断
  while(1)
  {
    
    
        /** 200毫秒更新一次数据 */
		if(s_flag)
    {
    
    
      s_flag = 0;
            /** 关闭定时器0中断:计算超声波发送到返回的时间 */
// 			ET0 = 0;
      send_wave();  //发送方波信号
      TR1 = 1;  //启动计时
			while((RX == 1) && (TF1 == 0));  //等待收到脉冲,没有计满溢出
			TR1 = 0;  //关闭计时

			//发生溢出
			if(TF1 == 1)
			{
    
    
				TF1 = 0;
				distance = 9999;  //无返回
			}
			else
			{
    
    
				/**  计算时间  */
				time=TH1*256+TL1;
				distance = (unsigned int)(time*0.017);  //计算距离				
			}
			TH1 = 0;
			TL1 = 0;
    }
	}
}

//定时器0中断服务函数
void time0()  interrupt 1  //默认中断优先级 1
{
    
    
  static unsigned int intr = 0;
	if(++intr == 100){
    
    s_flag = 1;intr = 0;}
	
	display();
}

void load()
{
    
    
	dspbuf[5] = distance/100;
	dspbuf[6] = distance%100/10;
	dspbuf[7] = distance%10; 
}

void Delay12us()//@11.0592MHz
{
    
    
	unsigned char i;

	_nop_();
	_nop_();
	_nop_();
	i = 30;
	while (--i);
}

void send_wave()//发送八段脉冲波(40Khz)
{
    
    
	unsigned char i = 8;
	
	while(i --)
	{
    
    
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
}

void display()
{
    
    
	static unsigned char dspcom = 0;
	
	load();
	
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = 0xff;
	P2 = 0x1f;
	
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 1 << dspcom;
	P2 = 0x1f;
	
	P2 = (P2 & 0x1f) | 0xe0;
	P0 = tab[dspbuf[dspcom]];
	P2 = 0x1f;
	
	if(++dspcom == 8) dspcom = 0;
}

現時点では、多くの人が12usの遅延をどうするか疑問に思うでしょう。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_43710889/article/details/109990441