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单片机的按键控制超声波测距及显示(带提示音)具有测量范围大,稳定性较高的特点,能够较好的完成测距工作。
上一篇:1602液晶显示屏显示字符
下一篇:51单片机的IIC总线
推荐阅读最新更新时间:2024-03-16 16:08