关于HC04超声波模块测距的思考(51版)
之前写过一篇HC04的使用文章,当时是使用stm32来实现的,原文链接。
后来又多次使用51来驱动这个模块,有时候有测距需要,使用了几次,总是感觉我上次那个程序不是很好,
所以这次对它进行了改进。虽然上一次也使用了多次测量取平均值,但是内有排除中间会有错误数据的情况。
之前的程序是这样的(测距部分) :
u32 t = ;
int i = ;
float lengthTemp = ;
float sum = ;
while(i!=)
{
TRIG_Send = ; //发送口高电平输出
Delay_Us();
TRIG_Send = ;
while(ECHO_Reci == ); //等待接收口高电平输出
OpenTimerForHc(); //打开定时器
i = i + ;
while(ECHO_Reci == );
CloseTimerForHc(); //关闭定时器
t = GetEchoTimer(); //获取时间,分辨率为1US
lengthTemp = ((float)t/58.0);//cm
sum = lengthTemp + sum ;
}
lengthTemp = sum/5.0;
return lengthTemp;
就是当超出测量范围的时候(3.4米),数据肯定是不准确的。还有就是当因为某些原因模块没有接收到返回的超声波,也会导致错误的数据,
就算是取平均值,如果中间有一个很大的数据的话,计算的结果也是不精确的。
利用51再次使用这个模块的程序如下:
/*
获取当前距离
2018.3.5 误差在1cm以内
*/
float get_distence()
{
unsigned long int time_buf = ; //总耗时
float distence = ; //计算一次距离
float sum = ; //多次计算的总距离
uchar i = ; while(i < NUM)
{
time_flag = ; //先清除标志
sr04_start(); //开始测距
while(!ECHO); //等待发出40khz脉冲,触发信号之后,echo会变成高电平
time_0_start(); //当把trig拉高10us之后,模块即开始发出8个40khz的脉冲,与此同时,echo变为高电平时,打开定时器。
while(ECHO); //等待回响信号,收到回响信号,echo会变低电平
TR0 = ; //关闭定时器 if(time_flag != ) //超出测量范围
continue; //不进行计算,放弃这次测量,从新测量 else //time_flag = 0,没有超出测量范围
{
time_buf = (TH0 * ) + TL0;
distence = time_buf * 0.0168;//(单位:cm)虽然声速340m/s,发现使用0.0168更精确,可能和温度有关
sum+= distence;
i++;
}
}
return (sum/NUM) ; //取NUM次平均值
}
其实就是在进行计算前先判断一下定时器是否产生中断,如果产生中断,就放弃本次数据,再次测量。这样测出的数据算是很精确了,唯一的误差就是声速的计算上面,导致会有1-2cm的误差。
16位的定时器,12M的晶振,定时器模式1,从0开始计数,最大到65535,一次溢出需要的时间是0.065s,声速为340m/s。那么溢出时的距离为22.1m,已经远远超过了超声波模块的测量范围(0-5m),所以只要产生一次溢出,就可以认为是超出测量范围.。
所以在定时器中断函数中 :
void TIME0() interrupt
{
// TF0 = 0; //模式1硬件自动清零
TH0 = ;
TL0 = ;
time_flag++;
}
其中对一些操作进行了简单的封装。开始测距函数,就是按照要求拉高TRIG引脚
/*start*/
void sr04_start()
{
TRIG = ;
delay_10us(); //拉高50us
TRIG = ;
}
还有就是定时器开始函数,在这个函数里面需要把计数清零:
/*开启定时器0,打开之前先清除之前的计数,不然会累计计数*/
void time_0_start()
{
TH0 = ; //打开前计数清零
TL0 = ;
TR0 = ; //打开定时器
}
然后就是模块的 初始化函数了,在初始化的时候其实就是对定时器的初始化,顺便把TRIG和ECHO引脚置0;
void sr04_init()
{
TRIG = ;
ECHO = ; TMOD |= 0X01; //定时器0模式设置1
TH0 = ; //从0开始计数
TL0 = ;
TR0 = ; //关闭定时器
EA = ; //开总中断
ET0 = ; //允许定时器0中断
}
关于HC04超声波模块测距的思考(51版)的更多相关文章
- 树莓派控制HC-SR04超声波模块测距(新手向+C语言向)
因为作业要求使用c语言代码,这里先附上一段摘自网上的代码 感谢KalaerSun的c语言代码,摘自https://blog.csdn.net/qq_25247589/article/details/6 ...
- 超声波模块HC-SR04简介以及编程
HC-SR04 一.主要参数1:使用电压:DC-5V2:静态电流:小于2mA3:电平输出:高5V4:电平输出:底0V5:感应角度:不大于15度6:探测距离:2cm-450cm7:高精度 可达0.2cm ...
- [TPYBoard - Micropython之会python就能做硬件 8] 学习使用超声波模块制作避障小车
转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 欢迎加入讨论群 64770604 一.实验器材 1.TPYboard V102板 一块 2.电机驱动模块L2 ...
- C语言单片机项目实战超声波雷达测距
本实验是基于MSP430利用HC-SR04超声波传感器进行测距,测距范围是3-65cm,讲得到的数据显示在LCD 1602液晶屏上. 模块工作原理如下 (1)采用 IO 触发测距,给至少 10us 的 ...
- stm32与HC-SR04超声波传感器测距
首先,先来看一下这个模块的基本功能和原理. HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm:模块包括超声波发射器.接收器与控制电路.像智能小车的测距 ...
- stm32驱动超声波模块
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发. #define HCSR04_PORT GPIOB #define HCSR04_CLK RCC ...
- Mybatis的mapper文件引起模块划分的思考
起因:项目中将公用的代码抽离到单独一个项目 cms-common.jar (注:公用的代码不只是工具类代码,包含service和dao等) 构建:每次构建项目 cms.war 的时候,需要引入cms- ...
- 一些node模块的学习思考
12月14日清单 1 readline模块 var readline = require("readline"); // input 是必须的,output是可选的 rl = re ...
- 【Arduino】超声波模块(HC-SR04)
还好,这个模块有现成的库能够用: https://github.com/bosgood/arduino-playground/tree/master/lib/HCSR04Ultrasonic 下面仅仅 ...
随机推荐
- 【转载】Linux时间相关结构与函数
1 时间的获取 在程序当中, 我们经常要输出系统当前的时间,比如日志文件中的每一个事件都要记录其产生时间.在 C 语言中获取当前时间的方法有以下几种,它们所获得的时间精度从秒级到纳秒,各有所不同. 表 ...
- 什么是Servlet,Servlet的作用,生命周期,如何创建、配置Servlet
什么是Servlet,作用是? servlet是一个基于java技术的WEB组件,运行在服务器端,我们利用 sevlet可以很轻松的扩展WEB服务器的功能,使它满足特定的应用需要.servlet由se ...
- remap.config文件配置模板
# # URL Remapping Config File # # Using remap.config allows you to accomplish two things: # # 1) Rew ...
- JAVA List根据字段排序以及取前几条数据
1.经常会遇到对组装的list排序或提取list中前几条数据,例如: 根据时间排序: list.sort((o1, o2) -> o2.getCreateTime().compareTo(o1. ...
- 【django之用户认证】
一.auth模块 模块导入 from django.contrib import auth 主要方法如下: 1 .authenticate() 提供了用户认证,即验证用户名以及密码是否正确,一般 ...
- Cypher查询语言--Neo4j 综合(四)
目录 返回节点 返回关系 返回属性 带特殊字符的标识符 列的别名 可选属性 特别的结果 查询中的返回部分,返回途中定义的感兴趣的部分.可以为节点.关系或其上的属性. 图 返回节点 返回一个节点,在 ...
- Hands-On Machine Learning with Scikit-Learn and TensorFlow---读书笔记
去年在北京参加了一次由O'Reilly和Cloudera联合举办的大数据会议Strata Data Conference,并有幸获得了O'Reilly出版的Hands-On Machine Learn ...
- PHP可以通过类名调用非静态方法
今日有兄弟遇上一个问题,就是可以通过class名称直接调用该类中的函数,我测试了一下,确实可以,概念中是只有静态方法才可以这样调用的,现在 被刷新了,于是我在方法中加入一行$this相关的操作,再运行 ...
- python函数式编程之装饰器(一)
1.开放封闭原则 简单来说,就是对扩展开放,对修改封闭 在面向对象的编程方式中,经常会定义各种函数. 一个函数的使用分为定义阶段和使用阶段,一个函数定义完成以后,可能会在很多位置被调用 这意味着如果函 ...
- 夏令营讲课内容整理 Day 4.
本日主要内容就是搜索(打暴力 搜索可以说是OIer必会的算法,同时也是OI系列赛事常考的算法之一. 有很多的题目都可以通过暴力搜索拿到部分分,而在暴力搜索的基础上再加一些剪枝优化, 就有可能会拿到更多 ...