【Proteus】超声波测距
前言:
在proteus8.6版本已经有了超声波模块,之前的proteus7版本中是没有这个的,只能够通过信号模拟超声波,或者就是自己制作超声波模块的模型,不过意思都差不多,现在既然proteus已经有了这个模块,就可以拉出来玩一下,看看实际的效果如何。
超声波的驱动:
有关这种超声波模块的驱动程序,应该还是比较好写的,没有像IIC协议等引脚时序那样略微复杂,而且驱动程序又比较通用,关于这个超声波模块的驱动原理,在淘宝上随便搜一下,下面都有比较详细的介绍,这里我就随便找了一家:
这个写得清楚明白,简单易懂,就是先将Trig脚拉低,然后给到Trig引脚一个至少10us的高电平信号,然后再拉低。之后模块就会自动向外发送超声波,我们只需要等待Echo管脚变为高电平就可以了。这个Echo管脚高电平的时间就带有距离信息。具体的距离计算公式也给出了:
测试距离 = (高电平时间 * 声速)/ 2;
那么,我们编程的思路就有了,先将Trig管脚置低,然后给Trig引脚一个至少10us延时的高电平信号,然后再拉低,然后等待Echo管脚的高电平信号,当Echo接收到高电平信号时,就打开定时器,在定时器中断中使用一个变量来计时,记录Echo管脚的高电平时间,当Echo变为低或者时间过长时,跳出循环,进行距离计算。因为可能前方没有障碍物,导致高电平时间很长,程序就在这里一直等待,而且此时的长距离信号也没有什么意义了,因此加上了时间过长时也会跳出循环。这个可以根据自己的实际情况来进行超时时间的调整。这样子,我们的大概的驱动函数就有了:
//超声波测量距离
void measure()
{float ult = 0.0f;Trig = 1;delay_20us();Trig = 0;while(Echo == 0); //等待高电平TR0 = 1; //打开定时器0time = 0; //计时清零while((Echo == 1)&&(time <= 2000)); //等待Echo变为低电平或超出时间限制 2000us //距离计算ult = (float)time; distance = (int) (34.0f * (ult / 100.0f)); //单位cm 34 * time/100 if(distance > 1000){distance = 1000;}TR0 = 0; //关闭定时器time=0;ult=0;
}
关于定时器的问题,应该已经有很多关于51单片机的定时器的内容,这里就不在一个个寄存器来解释了。可以查阅相关的资料。在上面的驱动函数中,我们使用了time这个变量来计时。我们的定时器初始化配置如下:
/**********************************
初始化函数
***********************************/
void init()
{TMOD = 0x01; //设置定时器工作方式,第二位为定时器0TH0 = (65536 - 10)/256; //定时器0高8位 10usTL0 = (65536 - 10)%256; //定时器0低8位TR0 = 1; //打开定时器ET0 = 1; //开定时器中断EA = 1; //开总中断
}
定时器中断如下:
void T0_time() interrupt 1
{TH0 = (65536 - 10)/256; //定时器0高8位 10usTL0 = (65536 - 10)%256; //定时器0低8位time ++;
}
可以看到,time每计数一次,代表10us的时间,即0.00001秒,那么距离公式就是:
距离 = (time * 0.00001 * 340 / 2)单位:米
我们可以将单位换算为厘米,这样显示起来更加方便,而且proteus8中的超声波模块,也是按照厘米来发送电平的,因此转换为厘米就是:
距离 = time * 0.001 * 340 / 2 = time * 0.01 * 34 / 2 单位:cm
可以看到,这里正常应该是有一个除以2的,但我在实际测试中发现,proteus中的超声波模块显示的距离,发回给我的信号并没有除以2,因此我就没有除,也可能是我部分步骤有问题,欢迎指正,也可以根据自己情况进行修改。
之后是proteus原理图的绘制,正如文章开头的图片:
使用一个1602来显示距离,具体1602的驱动程序的文章,可以查看我之前的文章:【Proteus】单片机配合矩阵键盘LCD1602制作简易计算器 - 知乎
之后便是使用proteus来调试。
小技巧:我们可以在proteus的Message窗口查看proteus的仿真过程
当然,我这里是已经成功的截图,最开始仿真我也是不成功的,这里有一个小插曲:
如上图,我最开始的main中初始化时,是将Echo引脚置0的,之后仿真时,Echo引脚的电平就不会变化了,一直等不到想要的高电平,此时Message窗口的提示信息如下:
Message窗口提示Echo引脚发生了逻辑争用,之后我就一直等不到高电平信号了,解决办法就是在初始化时不要管这个Echo,可能只有Proteus仿真需要这样,如果是真实的超声波模块,应该不会有这种问题,最后的main如下:
void main()
{lcd_init(); Trig=0;// Echo=0; init(); //定时器初始化 display(); //显示函数 while(1){measure(); //测量距离display(); //显示函数delay_ms(100);}
}
main.c中所有代码如下:
#include <reg52.h>
#include <stdio.h>
#include "1602.h"
#define uchar unsigned char
#define uint unsigned int
uchar direction;
int distance = 0;
int time = 0; //超声波计时
sbit Trig = P1^0;
sbit Echo = P1^1;//延时20us 使能超声波
void delay_20us()
{ uint bt ;for(bt = 0;bt < 100;bt ++);
}//延时10us 超声波使用
void delay_10us()
{ uint bt ;for(bt = 0;bt < 30;bt ++);
}/**********************************
初始化函数
***********************************/
void init()
{TMOD = 0x01; //设置定时器工作方式,第二位为定时器0TH0 = (65536 - 10)/256; //定时器0高8位 10usTL0 = (65536 - 10)%256; //定时器0低8位TR0 = 1; //打开定时器ET0 = 1; //开定时器中断EA = 1; //开总中断
}//超声波测量距离
void measure()
{float ult = 0.0f;Trig = 1;delay_20us();Trig = 0;while(Echo == 0); //等待高电平TR0 = 1; //打开定时器0time = 0; //计时清零while((Echo == 1)&&(time <= 2000)); //等待Echo变为低电平或超出时间限制 2000us //距离计算ult = (float)time; distance = (int) (34.0f * (ult / 100.0f)); //单位cm 34 * time/100 if(distance > 1000){distance = 1000;}TR0 = 0; //关闭定时器time=0;ult=0;
}//显示函数
void display()
{char *string = "distance :";char *string2 = "cm";char Z[16];//显示距离sprintf((char*)Z,"%s%d%s",string,distance,string2); print_string(Z,1);// write_com(0x8a);
} void main()
{lcd_init(); Trig=0;// Echo=0; init(); //定时器初始化 display(); //显示函数 while(1){measure(); //测量距离display(); //显示函数delay_ms(100);}
}void T0_time() interrupt 1
{TH0 = (65536 - 10)/256; //定时器0高8位 10usTL0 = (65536 - 10)%256; //定时器0低8位time ++;}
【Proteus】超声波测距相关推荐
- 基于stm32单片机的超声波测距显示倒车雷达提醒报警系统Proteus仿真
资料编号:145 下面是相关功能视频演示: 145-基于stm32单片机的超声波测距显示倒车雷达提醒报警系统Proteus仿真(源码+原理图+仿真+论文) 设计内容 本次嵌入式课程设计综合实验的内 ...
- STM32 Proteus仿真自动刹车系统超声波测距电机控制-0042
STM32 Proteus仿真自动刹车系统超声波测距电机控制-0042 Proteus仿真小实验: STM32 Proteus仿真自动刹车系统超声波测距电机控制-0042 功能: 硬件组成:STM32 ...
- 51单片机导盲手杖_超声波测距+DS18B20测温设计
51单片机导盲手杖_超声波测距+DS18B20测温设计 (源码+原理图+PCB+仿真) 原理图PAB:Altium Designer 仿真原版本:proteus 7.8 程序编译器:keil 4/ke ...
- 基于51单片机HC-SR04超声波测距带温度补偿
基于51单片机HC-SR04超声波测距带温度补偿 1 开发环境 2 功能说明介绍 3 程序 3.1 工程文件 3.2 代码 4 原理图 5 元器件清单 6 PCB 7全部资料 1 开发环境 仿真图:p ...
- 基于51单片机超声波测距液位检测-温度检测
[毕设课设]基于51单片机超声波测距液位检测-温度检测 效果图 Proteus仿真: 功能简介: 文件内容: 程序框架: 网盘链接: 效果图 更多内容请关注@WENJIE电子科技 基于51单片 ...
- 51单片机项目设计:基于超声波的 车库停车系统、车位检测系统设计(8个超声波测距模块)keil+protues仿真
基于51单片机的车库停车系统 代码仿真资料链接https://download.csdn.net/download/mbs520/12742296 一.设计要求: 毕业设计原题: 本设计主要用于室内停 ...
- 超声波测距测速升压可调中周倒车雷达变频器传感器1:10
简 介: 通过对于是用于超声波测速变压器的基本分析,为后面构成150kHz 放大节能信标组的感应信号打下基础. 关键词: 中周,电压器,超声波 ▌01 中周变压器 购买到这个周中变压器主要是为了构 ...
- 【 FPGA 】超声波测距小实验(一)
超声波测距原理: 超声波测距原理是在超声波发射装置发出超声波,它的根据是接收器接到超声波时的时间差,与雷达测距原理相似. 超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播 ...
- 51单片机c语言测距,求助 关于C51单片机超声波测距 C语言程序设计 高手帮帮忙...
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 C51编程:超声波测距程序(附图) [请帮助] 2006-9-30 18:44:03 #include #define k1 P3_4 #define c ...
- Arduino的光敏传感器和超声波测距传感器测试代码
光敏传感器测试代码 使用的是一个未知名4pin模块, 4pin依次为Vcc, Gnd, DO, AO, 板载一个可调电阻以及一个LED, 调节电阻大小, 可以控制LED亮灭和DO输出变化对光亮的灵敏度 ...
最新文章
- 客户管理系统代码项目_西安人力资源管理系统如何有效管理销售,提高工作的效率...
- 白宫计划2019年春季发布新版人工智能研究战略
- 算法 求一个数组的最长递减子序列 C
- 138 条 Vim 命令神操作,非常齐全,建议收藏!
- 如果你是集五福的PM,你会如何设计这个产品?
- 输入一字符串,统计其中有多少个单词(单词之间用空格分隔)(java)
- Java基础——volatile关键字解析
- python 对象引用,可变性,垃圾回收
- round()和trunc()函数的应用
- Java常用的工具类库介绍
- 强制卸载kernel
- OpenCV-Android平台应用实战 - 银行卡卡号识别(01、环境搭建)
- [C++] 最小生成树
- 那些你可能不知道的视频下载奇技淫巧
- 在BAT工作是什么样的?来听听在职员工们的说法
- 中国舞蹈家协会街舞委员会与微博达成战略合作
- SCAR:Scalable Consensus Algorithm 灵活共识算法
- 目标跟踪OTB评估指标(OP, CLE, FPS)与matlab代码
- 程序员分享:最近面试 Java 后端开发的感受
- python 64式: 第24式、python项目国际化翻译实战
热门文章
- 关于在android平台使用nanohttpd实现的http服务在WIFI环境下响应明显太慢的问题
- 这些年,这些ACM大佬-施韩原访谈
- 医疗行业的信息化建设
- 大富翁论坛-富翁笔记-Delphi数据库处理(转载)
- 数模电路基础知识 —— 3. 常见电路符号说明(电容、电阻、电感)
- python爬取新浪博客_Python爬取韩寒全部新浪博客
- 打印机显示服务器连接错误怎么回事,打印机处于错误状态是怎么回事 打印机处于错误状态如何解决【图文详解】...
- 360云服务器合作,360云主机速度(云服务器)
- 一条让人不安的坐地龙
- ccd后视摄像头_20192020年车载摄像头产业报告