史上最细超声波测距LCD显示距离模块(HC-SR04)

首先介绍硬件配置

超声波模板:

HC-SR04

单片机型号:

STC89C52RC

液晶显示屏:

LCD1602

接线:

Trig 接P2.0Echo接P2.1,VCC接VCC,GND接GND

介绍基本原理:

 

(图片来源:知乎小师弟)

然后直接上代码:

#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define out P0
sbit RW=P2^5;
sbit RS=P2^6;
sbit E=P2^7;
sbit Trig = P2^1;
sbit Echo = P2^0;
uchar flag=0;

//LCD编码区:读状态-写命令-写数据-自动显示-------------------------------------------------------
//-----------------------------------------------------------------------------------------------
void delay(uint j)     //1ms
{
	while(j--)
	{
		uchar i;
		for(i=0;i<125;i++);
	}
}
void cbusy()  //检查忙标志位函数
{
	uchar dt;
	do
	{
		dt=0xff;
		E=0; 
		RS=0; 					//单片机原理P123页读状态
		RW=1;
		E=1;
		dt=out; 			  //状态输出给dt
	}while(dt&0x80);	//如果不忙结束
	E=0;  						//E需要一个正脉冲
}
void wcommand(uchar com) //写命令
{
	cbusy();	
	E=0;  
	RS=0;
	RW=0;
	out=com;  			//将命令com写入P0口中
	E=1;						//形成正脉冲
	_nop_();
	E=0;   					//高变低,LCD执行命令
	delay(1);				//等待硬件反应
}
void wdata(uint dat) //写数据函数
{
	cbusy();
	E=0;
	RS=1;
	RW=0;
	out=dat;			//数据从P0口输出写入LCD
	E=1;
	_nop_();
	E=0;   				//高变低,写数据操作结束
	delay(1);
}
void init() //初始化
{
	wcommand(0x38); //命令6 P124
	
	wcommand(0x0c); //命令4
	
	wcommand(0x06); //命令3
	
	wcommand(0x01); //命令1
	
	wcommand(0x80);  //设置数据指针起点
	
}
void string(uchar ad,uchar *s) //LCD显示,s指针指向字符串常量,内容无法更改
{
	wcommand(ad);
	while(*s>0)
	{
		wdata(*s++);
		delay(50);   //延迟50ms观察数字
	}
}
void tring(uchar ad,uchar s)  //LCD显示数字,s指向字符常量,内容可以更改
{
	  wcommand(ad);
		wdata(s);
	delay(50);
	}


void lcdshow()   //LCD初显示
{

	init();

			string(0x80,"distance:");
		  string(0xc0,"texting");
		
	}
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
void zd() interrupt 1            //T0中断
{
	flag=1;
}
void count()
{
	uchar a[4]={0,0,0,0};
	uint time=0;
	unsigned long dist=0;
	uchar code as[15] =    {'0','1','2','3','4','5','6','7','8','9','.','-','m'};
	time=TH0*256+TL0;         //TH0+TL0
	TH0=0;
	TL0=0;
	dist=(time*1.72)/100;     //340×0.000001=0.00034米=0.034厘米,除以2就是所测距离:0.017=1.7/100
	if((dist>1127)||flag==1)  //最大定时时间65536us*0.0172=1127cm=11.27m
	{
		flag=0;
		string(0xc0,">_<     ");                   //显示超过最大距离
	}
	else
	{
		string(0xc0,"        ");
		a[0]=dist%1000/100;              //百位
	  a[1]=dist%100/10;               //十位
	  a[2]=dist%10;                   //个位
		tring(0xc0,as[a[0]]);           //显示距离,a[0]是数字,as[0]是字符串
		string(0xc1,".");
		tring(0xc2,as[a[1]]);
    tring(0xc3,as[a[2]]);
		tring(0xc4,as[12]); 		
	}
}
void start()
{
	 Trig=1;  //启动超声波
	_nop_();  //_nop_的延时时间是一个机器周期1us,用nop进行精准控制时间,delay无法精准定时
	_nop_();  //存在20us的高电平
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	Trig=0;
}
void main()
{
	TMOD=0x01;       //初始化定时器T0为方式1
	TH0=0;
	TL0=0;
	EA=1;
	ET0=1;
	
	init();
	lcdshow();
	while(1)
	{
		start();
		while(!Echo);  //等待引脚成高电平,相当于发出超声波信号
		  TR0=1;
		while(Echo);   //等待引脚成低电平,相当于收到超声波信号
			TR0=0;
			count();
			delay(100);
	}
}

出现的页数教材是电子工业出版社单片机原理与应用设计第三版里面基础的原理,需要的私聊。

最终运行结果是个动态刷新过程。

超声波测距其实是比较差的方式,这是由于本身硬件结构所造成的

 

(图片来自百度)

倘若障碍物表面是倾斜的对应超声波接受探头(Echo)接收数据就存在偏差。

理论上应该能接受最远距离11.27,但经过我实验最远只能到达9.68,原因我暂时还未弄清

超声波这个模板常用于小车避障和附件障碍物检测,加上舵机,会很有意思。

代码部分个人编写感觉不够精简,特此希望大家提出宝贵意见。

  • 14
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值