基于51单片机的按键控制超声波测距及显示的实现

发布者:红尘清梦最新更新时间:2018-07-14 来源: eefocus关键字:51单片机  按键控制  超声波测距 手机看文章 扫描二维码
随时随地手机看文章

1.方案设计:

1.1器件的选择:

hc-sr04超声波模块具有探测距离精度高、性能稳定、盲区小的特点,这能使测距更加精确和改进更加合理。

该系统的单片机采用宏晶公司的STC90C516RD+单片机,是原来STC89系列的升级版本,具有更强的抗干扰,抗静电能力,复位效果更好,功耗低,速度快。

蜂鸣器采用无源蜂鸣器,相比有源蜂鸣器虽然难度变大,必须用2K~5K的方波去驱动它,但声音频率可控,且价格更加低廉。

Lcd1602工业字符型液晶能够同时显示16x02即32个字符,与其他液晶显示器相比,显示字母和数字比较方便,控制简单,成本较低。

按键采用独立按键。

如图:


1.2模块改进

   超声波模块的处理:由于这次题目要求测到7米,所以普通的超声波测距模块肯定达不到,所以要么通过硬件改进,要么通过软件改进。这里介绍硬件改进方法:

实物图:




原理图:



上图标志电阻R3,可以调节最大探测距离。R3电阻为392,探测距离最大4.5M 左右,探测角度小于15 度;R3 电阻为472,探测距离最大 7M左右,探测角度小于30度;出厂默认392,即最大探测距离4.5M左右。R3 电阻大,接收部分增益高,检测距离大,但检测角度会相应变大,容易检测到前方旁边的物体。所以精度又2mm降低到1cm。

可以通过在洞洞板上焊接排座和排针来固定超声波模块:同时更方便的连接引脚和更换超声波模块。


2.电路原理图,硬件连接图

lcd1602的RW、RS、E脚和D0~D7引脚通过手动焊接与单片机P0~P7引脚相连.如图:


蜂鸣器:


按键:通过软件延时消抖



硬件连接图:


说明:将hc-sr04 TRIG脚连接 P2.3,ECHO脚连接P2.4,VCC、GND分别连接单片机的VCC、GND。

P1连接8个独立按键,启动测距。

P0连接 D0~D7脚,E脚连接P2.7,RW = P2^5,RS脚连接P2.6(事先已焊接好内部电路,不需要外部连接)。

蜂鸣器接P2.1。

3.算法部分

通过检测按键是否为按下,按下,则启动检测,再检测按键是否松开。同时蜂鸣器响提示开始检测,给TRIG脚至少 10us 的高电平信号,模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回, 有信号返回,通过ECHO脚输出一高电平,高电平持续的时间就是超声波从发射到返回的时间。只需通过定时器记下ECHO脚高电平时间t,再通过公式s=(t*v)/2,就可算出距离s,

再通过lcd1602进行显示。

4.程序


#include

#include

#define uchar unsigned char

#define uint  unsigned int

#define key P1//定义按键为P1

#define LCD1602_DATAPINS P0 //定义D0~D7

sbit LCD1602_E = P2^7; //位定义E、RW、RS

sbit LCD1602_RW = P2^5;

sbit LCD1602_RS = P2^6;

sbit trig = P2^3; //定义超声波发,收

sbit echo = P2^4; 

sbit BF = P0^7; //定义读忙

sbit beep=P2^1;//蜂鸣器

void check();//声明检测函数

void Delay1ms(uint c);//延时误差 0us

void LcdWriteCom(uchar com);//写指令函数

void LcdWriteData(uchar dat);//写数据函数

void LcdInit();//1602初始化函数

void count();//计算距离

uchar busytest();//读忙函数

uint scank();//扫描键盘

uint time,keyvalue,S;  //定义全局变量时间,键值,距离

void main()

{

uchar x[]="0123456789cm";//

TMOD=0x01;//设置工作方式

EA=1; //开总中断

ET0=1; //开定时器允许中断

TH0=0;//赋初值

TL0=0;

while(1)

{

int a=100;

keyvalue=scank();  //扫描键盘

if(keyvalue!=0)

{

while(a--)//蜂鸣器响一下

{beep=1;

Delay1ms(1);

beep=0;

Delay1ms(1);

}

check();   //超声波测距

count();  //计算距离

LcdInit(); //1602初始化函数

LcdWriteData(x[S/100]);//显示百位

LcdWriteData(x[S%100/10]); //十位

LcdWriteData(x[S%100%10]); //个位

LcdWriteData(x[10]);

LcdWriteData(x[11]); //单位

Delay1ms(100) ;

while(1) //保持显示

{

keyvalue=scank();  //扫描键盘

if(keyvalue!=0)

break;

}

}

}

 

/**************************************************************************************/

 

void check() //检测函数

{

trig=1;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

trig=0;

}

uint scank()

   uint i=0;

   keyvalue=0;

   if(key!=0xff)//检测按键是否按下

   {

     Delay1ms(5);//消抖

 

   }

   if(key!=0xff)//再次检测按键是否按下

   {

       keyvalue=key;

  while((key!=0xff)&&(i<50) )//检测按键是否送开

  {

   i++;

  }

  Delay1ms(5);//消抖

}

   return keyvalue;//返回键值

}

void count() //计算函数

{

  while(!echo);//当ECHO脚为1,开始记时

  TR0=1;

  while(echo);//当ECHO脚为0,关闭计时

  TR0=0;

  time=TH0*256+TL0;

  TH0=0;

  TL0=0;

  S=(time*1.7)/100; //单位厘米

void LcdWriteCom(uchar com)  //写入命令

{

while(busytest()==1);

LCD1602_E = 0;     //使能

LCD1602_RS = 0;   //选择输入命令

LCD1602_RW = 0;   //选择写入

LCD1602_DATAPINS = com;     //放入命令

    Delay1ms(1); //等待数据稳定

 

LCD1602_E = 1;          //写入时序

    Delay1ms(5);  //保持时间

LCD1602_E = 0;

}

void LcdWriteData(uchar dat) //写入数据

{

    while(busytest()==1);

LCD1602_E = 0; //使能清零

LCD1602_RS = 1; //选择输入数据

LCD1602_RW = 0; //选择写入

 

LCD1602_DATAPINS = dat; //写入数据

Delay1ms(1);

 

LCD1602_E = 1;   //写入时序

Delay1ms(5);   //保持时间

LCD1602_E = 0;

}

void LcdInit()  //LCD初始化子程序

{

  LcdWriteCom(0x38);  //功能设定[8位数据],[双行显示],[5*8点阵显示模式]

LcdWriteCom(0x0c);  //开显示不显示光标

LcdWriteCom(0x06);  //写一个指针加1

LcdWriteCom(0x01);  //清屏

LcdWriteCom(0x80);  //设置数据指针起点

}

void Delay1ms(uint c)   //误差 0us

{

    uchar a,b;

for (; c>0; c--)

{

for (b=199;b>0;b--)

{

  for(a=1;a>0;a--);

}      

}

   

}

uchar busytest(void)//读忙,1为忙,0为不忙

{

    bit result;//位定义,一字节

LCD1602_E = 1;

LCD1602_RS = 0;

LCD1602_RW = 1;

    Delay1ms(1);

result=BF; //确定是否处于忙碌状态

LCD1602_E=0;

return result;

 

 

}

前提是你得添加51单片机的库reg52.h,我使用的是keil编译环境。



5.遇到的问题

通过改变电阻的方法来扩大增益,增大测量距离,将原来的测量范围由4.5增大到7米,但角度会增大到30度,会检测到前方旁边的物体。导致了稳定性降低,测距会出现大误差数据,并且精度降低。

6.结论

本文阐述了超声波模块的改进方法和各种模块连接的方法,采用了按键、lcd1602、蜂鸣器等模块,改变电阻解决了超声波模块测量距离短的问题,基于51单片机的按键控制超声波测距及显示(带提示音)具有测量范围大,稳定性较高的特点,能够较好的完成测距工作。


关键字:51单片机  按键控制  超声波测距 引用地址:基于51单片机的按键控制超声波测距及显示的实现

上一篇:1602液晶显示屏显示字符
下一篇:51单片机的IIC总线

推荐阅读最新更新时间:2024-03-16 16:08

外中断(按键控制数码管显示
#include config.h #define uint unsigned int #define uchar unsigned char #define ulong unsigned long #define SIGNAL P3_5 // 键盘初始信号 #define KEY6 P3_2 // KEY6口就是INT0口 #define KEY2 P3_3 int num; // 延时约(0.001 * n)秒 void delay(unsigned char n) { ulong i; do { i = CPUCLK / 1000; while(i--);
[单片机]
基于AT89C51单片机和传感器实现家庭安全报警系统的设计
家庭安全报警系统家庭安防报警功能是智能家居系统的重要功能,同家庭的各种传感器、功能键、探测器及执行器共同构成家庭的安防体系,是家庭安防体系的“大脑”。报警功能包括防火、防盗、煤气泄露报警及紧急求助等功能,报警系统采用先进智能型控制网络技术、由微机管理控制,实现对匪情、盗窃、火灾、煤气、紧急求助等意外事故的自动报警。然而市场上出现的各类家庭安全报警系统功能虽较齐全,但并不完善,明显的不足之处就是报警号码都是预先存入,而且没有提供人机交互功能,用户如因特殊情况需更换报警电话号码时往往无能为力,其设计显然不够人性化,也给用户带来了诸多不便。明显的不足之处就是报警号码都是预先存入,而且没有提供人机交互功能,用户如因特殊情况需更换报警电话号
[单片机]
基于AT89C<font color='red'>51单片机</font>和传感器实现家庭安全报警系统的设计
51单片机特殊功能寄存器功能一览表
21个特殊功能寄存器(52系列是26个)不连续地分布在128个字节的SFR存储空间中,地址空间为80H-FFH,在这片SFR空间中,包含有128个位地址空间,地址也是80H-FFH,但只有83个有效位地址,可对11个特殊功能寄存器的某些位作位寻址操作(这里介绍一个技巧:其地址能被8整除的都可以位寻址)。   在51单片机内部有一个CPU用来运算、控制,有四个并行I/O口,分别是P0、P1、P2、P3,有ROM,用来存放程序,有RAM,用来存放中间结果,此外还有定时/计数器,串行I/O口,中断系统,以及一个内部的时钟电路。在单片机中有一些独立的存储单元是用来控制这些器件的,被称之为特殊功能寄存器(SFR)。这样的特殊功能寄存器5
[单片机]
51单片机基础之矩阵键盘4X4
原理: 16个键盘,通过八个引脚就可以控制,高四位控制行,低四位控制列。 代码: #include reg51.h #define SMG P0 //宏定义数码管 #define KEY P1 //宏定义矩阵键盘 typedef unsigned char u8; typedef unsigned int u16; u8 sum; //定义一个全局变量,用来保存按键的值 u8 SMG_Code ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0xff}; //数码管显示的
[单片机]
<font color='red'>51单片机</font>基础之矩阵键盘4X4
INT0和INT1中断计数 PROTEUS 和51单片机教程
功能:INT0和INT1中断计数,INT0和INT1分别计数和清零,也可以把两个连在一起计数 PROTEUS 和51单片机教程 程序的C语言代码如下: /* INT0与INT1中断计数 */ #include typedef unsigned char uint8; typedef unsigned int uint16; sbit K3 = P3^4; sbit K4 = P3^5; void delay(uint16 x) { uint16 i,j; for(i = x; i 0; i --) for(j = 114; j 0; j --); } code uint8 LED_CODE = {0x
[单片机]
INT0和INT1中断计数 PROTEUS 和<font color='red'>51单片机</font>教程
51单片机多机通信原理
一、多机通信原理 在多机通信中,主机必须要能对各个从机进行识别,在51系列单片机中可以通过SCON寄存器的SM2位来实现。当串口以方式2或方式3发送数据时,每一帧信息都是11位,第9位是数据可编程位,通过给TB8置1或置0来区别地址帧和数据帧,当该位为1时,发送地址帧;该位为0时,发送数据帧。 在多机通信过程中,主机先发送某一从机的地址,等待从机的应答,所有的从机接收到地址帧后与本机地址进行比较,若相同,则将SM2置0准备接收数据;若不同,则丢弃当前数据,SM2位不变。 二、多机通信电路图 此处,U1作为主机,U2为从机1,U3为从机2。 三、C语言程序 (1)主机程序 #include#include #define
[单片机]
<font color='red'>51单片机</font>多机通信原理
基于AT89C2051智能汽车防撞报警器设计
  引言   随着现代生活节奏的加快,交通事故发生的频率也在增加,为提高汽车运行的安全性,本文介绍一种单片机控制的汽车防撞报警系统。该装置将单片机的实时控制及数据处理功能,与超声波的测距技术、传感器技术相结合,可检测汽车运行中后方障碍物与汽车的距离及汽车车速,通过数显装置显示距离,并由发声电路根据距离远近情况发出警告声。   1 超声波测距原理   超声波测距的原理是,通过不断检测超声波发射后遇到障碍物所反射的回波,从而测出发射超声波和接收到回波的时间差T,然后求出距离S=C×T/2,其中,C为超声波波速,常温下取为344m/s。声速确定后,只要测得超声波往返的时间,即可求得距离。   2 测速原理   汽车车速的测量是
[单片机]
基于AT89C2051智能汽车防撞报警器设计
基于89C51单片机的环境噪声测量仪
   1 引 言      环境噪声监测,是人类提高生活质量,加强环境保护的一个重要环节,在各大城市的繁华街区和居民区,已有大型环境噪声显示器竖立街头。但目前国内的便携式噪声测试仪,多为价格昂贵的进口专用设备,除卫生、计量等环保专业部门拥有外,无法作为民用品推广普及。本文介绍一种以89C51单片机为核心,采用V/F转换技术构成的低成本、便携式数字显示环境噪声测量仪。该仪器工作稳定、性能良好,经校验定标后能满足一般民用需要,可广泛应用于工矿企业、机关、学校等需要对环境噪声进行测量和控制的场合。 2 声压级的测量机理   人耳的听阈一般是20μPa,痛阈一般是200 Pa,其间相差107倍,这样宽广的声压范围很不易测量,
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved