蓝桥杯单片机必备知识—–(9)超声波测距

蓝桥杯单片机必备知识—–(9)超声波测距

蓝桥杯单片机必备知识—–(9)超声波测距

超声波测距原理:

超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离(s),即:s=340t/2 。这就是所谓的时间差测距法。
超声波测距的原理是利用超声波在空气中的传播速度为已知,测量声波在发射后遇到障碍物反射回来的时间,根据发射和接收的时间差计算出发射点到障碍物的实际距离。由此可见,超声波测距原理与雷达原理是一样的。
测距的公式表示为:L=C×T
式中L为测量的距离长度;C为超声波在空气中的传播速度;T为测量距离传播的时间差(T为发射到接收时间数值的一半)。
超声波测距主要应用于倒车提醒、建筑工地、工业现场等的距离测量,虽然目前的测距量程上能达到百米,但测量的精度往往只能达到厘米数量级。
由于超声波易于定向发射、方向性好、强度易控制、与被测量物体不需要直接接触的优点,是作为液体高度测量的理想手段。在精密的液位测量中需要达到毫米级的测量精度,但是目前国内的超声波测距专用集成电路都是只有厘米级的测量精度。

核心代码:

//切记,计算距离不使用分频
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延时该如何做;
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100124.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • webman windows调试环境搭建

    webman windows调试环境搭建目录环境启动脚本 web 服务器搭建好了 如此简单 性能拽的很 windows 启动后界面局域网测试 这个意义不大花生壳内网穿透 20 万次访问 服不服映射配置一句话 带宽扛得住 问题不大 异步处理会更好

    2025年10月20日
    5
  • TerminateProcess函数简单使用示例[通俗易懂]

    TerminateProcess顾名思义,就是终止进程的意思。是WindowsAPI的函数,示例代码如下://Demo.cpp:定义控制台应用程序的入口点。//终止进程Demo#include”stdafx.h”usingnamespacestd;//@param:dwpid:指定需要关闭的进程pidintCloseProcess(DWORDdwpi…

    2022年4月7日
    121
  • 域名怎么与主机空间绑定的_域名绑定虚拟主机

    域名怎么与主机空间绑定的_域名绑定虚拟主机域名怎么与主机空间绑定2008-07-2623:41由于各种原因,我们有时候需要在一个IP地址上建立多个web站点,在IIS中,我们可能通过简单的设置达到这个目标。  在IIS中,每个Web站点都具有唯一的、由三个部分组成的标识,用来接收和响应请求:  1、IP地址  2、端口号  3、主机头名。  在IIS中,在一个IP地址上建立多个独

    2022年10月15日
    3
  • App的宣传方式?

    ##1.线上渠道各大下载市场、应用商店、大平台、下载站的覆盖,线上推广的第一步是要上线,这是最基础的。无需砸钱,只需最大范围的覆盖,具体有:运营商渠道推广、第三方商店、手机厂商商店、积分墙推广、刷榜推广、社交平台推广、广告平台、换量推广等等很多方式。##2.线下推广主要是手机厂商预装、水货刷机、行货店面刷机、地推、线下活动推广等。##3.是线上宣传PR传播、事件营

    2022年4月5日
    43
  • 两列向量正交有什么性质线性代数_线性代数正交化怎么算

    两列向量正交有什么性质线性代数_线性代数正交化怎么算正交向量  正交是垂直的令一种说法,两个向量正交意味着两个向量的夹角是90°。  这可以用直角三角形的三边解释:  当x和y正交时,二者的点积是0,反过来也一样。这个结论在n维空间也适用,当Rn空间内的两个向量x和向量y正交时:  如果x是零向量,xTy还是0,也意味着零向量和任意向量正交。正交子空间  正交性还可以推广到子空间,如果说一个子空间V和另一个子空间W…

    2025年5月26日
    6
  • Java课程设计之 学生成绩管理系统「建议收藏」

    Java课程设计之 学生成绩管理系统「建议收藏」实现内容:设计开发一个学生成绩管理系统(1)根据实现的功能,划分出合理的对象类,明确各个对象类之间的关系。为各个对象类设计正确的域和方法,为每个方法设计合理的方法体。同时,为对象类及内部的域和方法运用正确的修饰符。功能要求:(1)录入成绩(2)查询成绩(3)成绩排序(4)修改成绩(5)删除成绩(6)将数据保存在数据库表中该课程设计涉及MySQL数据库,建表操作,java操作SQL语句(JDBC数据库操作)以及JavaS

    2022年7月9日
    25

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号