求赞,它是我写博客的动力,请鼓励鼓励我,谢谢

基于超声波测距的倒车报警系统。

计划通过超声波传感器测距,温度传感器校正误差,lcd1602显示结果,距离小于某一值时将蜂鸣报警。

总体设计思路

HC-SR04超声波传感器模块为核心装置,发射、接受超声波,产生使单片机开始计数和停止计数的信号,从而计算超声波往返的时间。

利用温度传感器DS18B20测量温度并修正当前的声速。

LCD1602液晶模块为显示装置,单片机计算完成后输送信息到LCD1602,显示测量距离和当前环境的温度。

当单片机判断距离小于某值时控制蜂鸣器电路产生报警信号。

超声波测距的原理介绍

超声波测距的原理采用回波探测法。
超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在介质中传播,
途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。
超声波在空气中0℃时的传播速度为C0=332m/s,又已知超声波速度C0与温度T(℃)的关系为
  C=C0+0.607×T
计算发射点距障碍物的距离的公式为
S=C*TIME/2。

超声波传感器(HC-SR04)介绍

该超声波收发模块可产生40kHz的方波,经放大电路驱动后超声波发射探头发射超声波,
发射出去的超声波经障碍物反射后由超声波接收探头接收。
当没有发送超声波时ECHO引脚输出低电平。从开始发送超声波到街道回波这一段时间内ECHO引脚均为高电平,
可以此控制计数器的启动与停止。在ECHO引脚上产生方波脉冲的脉冲宽度与被测距离成线性关系。
使用HC-SR04超声波收发模块进行距离测量测量时,单片机只需要输出触发信号,并监视回响引脚,
通过定时器计算回响信号宽度,并换算成距离即可。此超声波模块所需单片机的引脚少,便于控制。

报警距离调整功能设计

P3.2和P3.3引脚检测到低电平时产生外部中断0,1,
由软件代码调整内部alarm_distance变量,
P3.2脚按键按下每次增加5cm
P3.3脚按键按下每次减少5cm

程序设计

主程序

          

温度数据处理子函数

距离计算子函数

LCD驱动程序

#include"lcd.h"/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能         : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时
*******************************************************************************/void Lcd1602_Delay1ms(uint c)   //误差 0us
{uchar a,b;for (; c>0; c--){for (b=199;b>0;b--){for(a=1;a>0;a--);}      }}/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能         : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
#ifndef     LCD1602_4PINS    //当没有定义这个LCD1602_4PINS时
void LcdWriteCom(uchar com)   //写入命令
{LCD1602_E = 0;     //使能LCD1602_RS = 0;      //选择发送命令LCD1602_RW = 0;    //选择写入LCD1602_DATAPINS = com;     //放入命令Lcd1602_Delay1ms(1);        //等待数据稳定LCD1602_E = 1;           //写入时序Lcd1602_Delay1ms(5);      //保持时间LCD1602_E = 0;
}
#else
void LcdWriteCom(uchar com)   //写入命令
{LCD1602_E = 0;     //使能清零LCD1602_RS = 0;  //选择写入命令LCD1602_RW = 0;    //选择写入LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1;     //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;//    Lcd1602_Delay1ms(1);LCD1602_DATAPINS = com << 4; //发送低四位Lcd1602_Delay1ms(1);LCD1602_E = 1;   //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能         : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/
#ifndef     LCD1602_4PINS
void LcdWriteData(uchar dat)            //写入数据
{LCD1602_E = 0;    //使能清零LCD1602_RS = 1;  //选择输入数据LCD1602_RW = 0;    //选择写入LCD1602_DATAPINS = dat; //写入数据Lcd1602_Delay1ms(1);LCD1602_E = 1;   //写入时序Lcd1602_Delay1ms(5);   //保持时间LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)            //写入数据
{LCD1602_E = 0;      //使能清零LCD1602_RS = 1;      //选择写入数据LCD1602_RW = 0;    //选择写入LCD1602_DATAPINS = dat;    //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1;      //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = dat << 4; //写入低四位Lcd1602_Delay1ms(1);LCD1602_E = 1;     //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;
}
#endif/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能       : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/
#ifndef     LCD1602_4PINS
void LcdInit()                        //LCD初始化子程序
{LcdWriteCom(0x38);  //开显示LcdWriteCom(0x0c);  //开显示不显示光标LcdWriteCom(0x06);  //写一个指针加1LcdWriteCom(0x01);  //清屏LcdWriteCom(0x80);  //设置数据指针起点
}
#else
void LcdInit()                        //LCD初始化子程序
{LcdWriteCom(0x32);  //将8位总线转为4位总线LcdWriteCom(0x28);     //在四位线下的初始化LcdWriteCom(0x0c);  //开显示不显示光标LcdWriteCom(0x06);  //写一个指针加1LcdWriteCom(0x01);  //清屏LcdWriteCom(0x80);  //设置数据指针起点
}
#endif

DS18B20温度传感器驱动程序

#include"temp.h"
/*******************************************************************************
* 函数名         : Delay1ms
* 函数功能         : 延时函数
* 输入           : 无
* 输出             : 无
*******************************************************************************/void Delay1ms(unsigned int y)
{unsigned int x;for(y;y>0;y--)for(x=110;x>0;x--);
}
/*******************************************************************************
* 函数名         : Ds18b20Init
* 函数功能         : 初始化
* 输入           : 无
* 输出             : 初始化成功返回1,失败返回0
*******************************************************************************/unsigned char Ds18b20Init()
{unsigned int i;DSPORT=0;           //将总线拉低480us~960usi=70;   while(i--);//延时642usDSPORT=1;          //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低i=0;while(DSPORT)    //等待DS18B20拉低总线{i++;if(i>5000)//等待>5MSreturn 0;//初始化失败  }return 1;//初始化成功
}/*******************************************************************************
* 函数名         : Ds18b20WriteByte
* 函数功能         : 向18B20写入一个字节
* 输入           : com
* 输出             : 无
*******************************************************************************/void Ds18b20WriteByte(unsigned char dat)
{unsigned int i,j;for(j=0;j<8;j++){DSPORT=0;         //每写入一位数据之前先把总线拉低1usi++;DSPORT=dat&0x01; //然后写入一个数据,从最低位开始i=6;while(i--); //延时68us,持续时间最少60usDSPORT=1;   //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值dat>>=1;}
}
/*******************************************************************************
* 函数名         : Ds18b20ReadByte
* 函数功能         : 读取一个字节
* 输入           : com
* 输出             : 无
*******************************************************************************/unsigned char Ds18b20ReadByte()
{unsigned char byte,bi;unsigned int i,j;    for(j=8;j>0;j--){DSPORT=0;//先将总线拉低1usi++;DSPORT=1;//然后释放总线i++;i++;//延时6us等待数据稳定bi=DSPORT;   //读取数据,从最低位开始读取/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/byte=(byte>>1)|(bi<<7);                         i=4;     //读取完之后等待48us再接着读取下一个数while(i--);}              return byte;
}
/*******************************************************************************
* 函数名         : Ds18b20ChangTemp
* 函数功能         : 让18b20开始转换温度
* 输入           : com
* 输出             : 无
*******************************************************************************/void  Ds18b20ChangTemp()
{Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);      //跳过ROM操作命令      Ds18b20WriteByte(0x44);        //温度转换命令
//  Delay1ms(100);  //等待转换成功,而如果你是一直刷着的话,就不用这个延时了}
/*******************************************************************************
* 函数名         : Ds18b20ReadTempCom
* 函数功能         : 发送读取温度命令
* 输入           : com
* 输出             : 无
*******************************************************************************/void  Ds18b20ReadTempCom()
{   Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);    //跳过ROM操作命令Ds18b20WriteByte(0xbe);  //发送读取温度命令
}
/*******************************************************************************
* 函数名         : Ds18b20ReadTemp
* 函数功能         : 读取温度
* 输入           : com
* 输出             : 无
*******************************************************************************/int Ds18b20ReadTemp()
{int temp=0;unsigned char tmh,tml;Ds18b20ChangTemp();              //先写入转换命令Ds18b20ReadTempCom();          //然后等待转换完后发送读取温度命令tml=Ds18b20ReadByte();       //读取温度值共16位,先读低字节tmh=Ds18b20ReadByte();     //再读高字节temp=tmh;temp<<=8;temp|=tml;return temp;
}

PROTEUS仿真

原理图

实物

   (还有一张图片大了上传不成功)

总结

1.发现返回的温度值不正常,导致显示的温度值(ascII码显示)不是数值而是乱码,经过检查发现获取温度的函数中温度值比实际值大10倍,修正后问题解决。

2.通过温度校正超声波的速度时,计算出的距离总是比实际距离小,检查发现存在精度损失,原因为速度在函数中定义时为unsigned int型,不符合实际情况,修改为float型后问题解决。

3.给蜂鸣器管脚输出高电平后,蜂鸣器不响,
经查阅资料发现,开发板上的蜂鸣器为无源蜂鸣器,
需要一定周期的脉冲序列方可响,而不是单一的高电平。

4.发现计算的距离随着时间不断递增,直至超出量程,经过检查发现,在每次计算时间后,只有计数器低位被置零,高位没有置零,修改后问题解决。

最后附上项目文件地址:

https://github.com/RSMung/UltrasonicDistanceMeasurementSystem

求赞,它是我写博客的动力,请鼓励鼓励我,谢谢

有问题可留言

超声波测距系统(stc89c52单片机+lcd1602+srf04超声波传感器+DS18B20温度传感器+无源蜂鸣器)相关推荐

  1. 51单片机学习——9--温度传感器DS18B20

    温度传感器 DS18B20 简介 特点 实物图 原理图 内部结构 (1) 64位(激)光刻只读存储器 (2) DS18B20温度转换规则 (3) DS18B20温度传感器的存储器 (4) 配置寄存器 ...

  2. 基于51单片机LCD1602温度显示(DS18B20测温)

    基于51单片机DS18B20测温 要在1602上显示温度先要了解1602是如何显示的.详情可以参考我之前的文章基于51单片机1602显示 DS18B20是美国DALLAS半导体公司推出的第一片支持&q ...

  3. STC89C52单片机 LCD1602液晶显示屏

    LCD1602显示 VVcat #include <reg52.h>typedef unsigned char uchar; typedef unsigned int uint;sbit ...

  4. STC89C52单片机LCD1602显示屏介绍与代码演示

    目录 LCD1602显示屏介绍 引脚介绍 内部结构框图 存储器 DDRAM储存器地址 CGRAM与 CGROM的地址 时序介绍 LCD1602快捷指令 LCD1602指令操作流程: 字符.字符串的显示 ...

  5. Arduino UNO R3开发板+MQ-2烟雾浓度传感器+火焰传感器+舵机+无源蜂鸣器+风扇+步进电机+WIFI模块+RGB三色LED灯+SIM900A所构成的室内安全报警模块

    该系统模块主要由Arduino UNO R3开发板+MQ-2烟雾浓度传感器+火焰传感器+舵机+无源蜂鸣器+风扇+步进电机+WIFI模块+RGB三色LED灯+SIM900A所组成,MQ-2烟雾浓度传感器 ...

  6. 【毕设狗】【单片机毕业设计】基于单片机的超声波测距系统的设计

    软件安装: Keil:点击下载 Proteus:点击下载 AD:点击下载 Visio:点击下载 设计简介: 本设计是基于单片机的超声波测距系统的设计,主要实现以下功能: 实现通过DS18B20测量当前 ...

  7. 单片机STM8S测量电压电路_STM32单片机的高精度超声波测距系统的设计

    相比于传统的单片机,STM32单片机具有更高的时间测量分辨率,其主频与定时器频率高达72MHz,且该单片机在开启定时器的同时,会启动PWM通道驱动超声波发射器和通道捕捉回波信号,提高了测量的精度和准确 ...

  8. 基于51单片机驱动HC-SR04超声波模块(LCD1602显示)

    基于51单片机驱动HC-SR04超声波模块(LCD1602显示) 一.基本参数 二.通信时序 三.部分代码展示 四.实际效果 总结 一.基本参数 点击图片购买 HC- SR04+是一款宽电压工作的超声 ...

  9. 利用LCD1602显示超声波测距

    利用LCD1602显示超声波测距 介绍 一.需要的器件 二.原理 工程代码 一. LCD1602 二.超声波测距及主程序 运行图 介绍 一.需要的器件 51单片机:任意一款都可以,我这里使用的是STC ...

最新文章

  1. POJ-2195(最小费用最大流)
  2. mfc控件变量没定义_WinCC字符串归档变量查询
  3. 墙裂推荐!顶级赛事CCF BDCI即将开赛!
  4. ECCV 2020 亮点摘要(上)
  5. 红米Note 7 Pro在印度首销迅速售罄
  6. 《人月神话》阅读笔记一
  7. 【图像处理】图像强度变换、直方图均衡化(Image Intensity Transformations and Histogram Equalization)
  8. java去哪导包_在Java语言中,哪一个包中的类是自动导入的?( )java.applet
  9. 2022电工杯:5G 网络环境下应急物资配送问题(优化)
  10. 腾讯视频转码,把qlv格式转换成mp4格式
  11. 关于高校房产管理系统中主要管理模块都有哪些
  12. 相片审核处理工具步骤_相片
  13. call、aplay 和 bind 三者之间的区别?
  14. 跨专业考计算机研究生有专业限制吗,我想跨专业考计算机专业研究生
  15. Android Studio设置关闭当前页面的快捷键
  16. redis的安装教程(单机、win10)
  17. TCP的三次握手与四次挥手
  18. 湖北师范大学----操作系统实训(c语言)
  19. 【通信原理】PC上调试MODBUS基本功能(附报文解析)
  20. LINUX命令(1)-创建文件

热门文章

  1. 使用高德地图微信小程序SDK开发案例-输入提示(附源码)
  2. 南京晓庄学院计组期末复习限时训练16(第六章计算机的计算方法)
  3. 过来人看PMP证书:究竟含金量有多高?
  4. MTBF检测方法及标准
  5. 月薪4万的人,为什么还是那么穷?
  6. 一、图的定义,邻接矩阵和邻接表的实现
  7. 【Linux】基本的指令(一)
  8. 用Kinect来控制鼠标的移动、单击、双击和右击 及PPT控制(Windows sdk)
  9. oracle财务系统名称,Oracle财务系统常用标准报表
  10. 第三次上机作业 大连理工大学