Verilog 实现超声波测距

Verilog 实现超声波测距

教学视频: https://www.bilibili.com/video/BV1Ve411x75W?p=33&spm_id_from=pageDriver&vd_source=19ae31dff4056e52d2729a4ca212602b

超声波测距原理

参考资料:STM32的超声波测距程序_超声波测距stm32程序_VaderZhang的博客-CSDN博客

推荐一波自己的文章:STM32蓝牙控制循迹避障小车源代码——3.舵机、超声波测距模块_stem32超声波舵机代码_灵风_Brend的博客-CSDN博客

  • 超声波模块工作原理:
    输出TRIG触发测距,需要给最少10us的高电平信呈;
    模块自动发送8个40KHZ的方波,自动检测是否有信号返回;
    有信号返回,通过IO口ECHO输出高电平,高电平持续时间就是超声波从发射到返回的时间;
    测试距离=高电平持续时间*声速/2

需求分析与功能定义:

  • 每隔100ms时间,定时产生10us时间的TRIG高脉冲给到超声波测距模块,用于触发超声波测距模块工作
  • 采集回响信号ECHO的高脉冲保持时间
  • 将ECHO高脉冲保持时间换算成距离信息:s = 0.173*t
  • 人机交互

代码思路:(详细教学可以看最上面的链接)

代码组成:

在这里插入图片描述


vlg_en :输出clk_en信号,对输入时钟clk做分频计数,产生1us的时钟使能信号(计数单位为us)


module vlg_en #(parameter P_CLK_PERIORD = 20	//clk的时钟周期为20ms
)
( input 		clk,input 		rst_n,output reg 	clk_en
);localparam P_DIVCLK_MAX = 1000/P_CLK_PERIORD - 1;	//分频计数器的最大值
reg [7:0] r_divcnt;///
//对输入时钟clk做分频计数,产生1us的时钟使能信号
always @(posedge clk or negedge rst_n) beginif(!rst_n)r_divcnt <= 8'b0;else if(r_divcnt < P_DIVCLK_MAX)r_divcnt <= r_divcnt + 1'b1;elser_divcnt <= 8'b0;
end///
//产生时钟使能信号
always @(posedge clk) beginif(r_divcnt == P_DIVCLK_MAX)clk_en <= 1'b1;elseclk_en <= 1'b0;
endendmodule

vlg_tirg :每隔100ms时间,定时产生10us时间的TRIG高脉冲给到超声波测距模块,用于触发超声波测距模块工作

module vlg_tirg
( input 		clk,input 		rst_n,input 		clk_en,output reg 	trig
);localparam P_TRIG_PERIORD_MAX = 100_000 - 1;	//100ms计数最大值
localparam P_TRIG_HIGH_MAX = 10;			//10us高脉冲保持时间reg [16:0] tricnt;///
//100ms周期计数
always @(posedge clk or negedge rst_n) beginif(!rst_n)tricnt <= 'b0;else if(clk_en)beginif(tricnt < P_TRIG_PERIORD_MAX)tricnt <= tricnt + 1'b1;elsetricnt <= 'b0;end		
end///
//产生保持10us的trig信号
always @(posedge clk) beginif((tricnt > 'b0)&&(tricnt <= P_TRIG_HIGH_MAX))trig <= 1'b1;elsetrig <= 1'b0;
endendmodule

上面两个信号的波形展示:

在这里插入图片描述

vlg_echo : 采集回响信号ECHO的高脉冲保持时间。(echo信号的高电平保持时间即为超声波往返的时间)

module vlg_echo
( input 		clk,input 		rst_n,input 		clk_en,input 		echo,output reg [15:0] t_us
);reg [1:0] r_echo;
wire pos_echo,neg_echo;
reg cnt_en;
reg [15:0] echo_cnt;///
//对echo信号锁存两拍,获取边沿检测信号,产生计数使能信号cnt_en
always @(posedge clk or negedge rst_n) beginif(!rst_n)r_echo <= 'b0;elser_echo <= {r_echo[0],echo};	//高位锁存,低位移位	
endassign pos_echo = ~r_echo[1] & r_echo[0];
assign neg_echo = r_echo[1] & ~r_echo[0];always @(posedge clk or negedge rst_n) beginif(!rst_n)cnt_en <= 'b0;else if(pos_echo)cnt_en <= 1'b1;else if(neg_echo)cnt_en <= 1'b0;else ;
end///
//对echo信号的高电平保持时间进行1us为单位的计数
always @(posedge clk or negedge rst_n) beginif(!rst_n)echo_cnt <= 'b0;else if(!cnt_en)echo_cnt <= 'b0;else if(clk_en)echo_cnt <= echo_cnt + 1'b1;else ;
end	///
//对echo_cnt计数最大值做锁存
always @(posedge clk or negedge rst_n) beginif(!rst_n)t_us <= 'b0;else if(neg_echo)t_us <= echo_cnt;
endendmodule

cal :将时间计算为距离。测试距离=高电平持续时间 * 声速/2。 (s = 0.173*t)

module cal
( input 		clk,input 		rst_n,input [15:0] t_us,output [14:0] s_mm
);/*	s=0.173*ts*4096=0.173*t*4096=709*t	 避免小数部分s=709*t/4096=709*t>>12709实现方法:  1)乘法器2)709=512+128+64+4+1本代码使用乘法器来实现。直接调用乘法器IP核
*/
wire [25:0] mult_result;mult_gen_0 u_mult_gen_0 (.CLK(clk),  // input wire CLK.A(10'd709),      // input wire [9 : 0] A.B(t_us),      // input wire [15 : 0] B.P(mult_result)      // output wire [25 : 0] P
);assign s_mm = mult_result[25:12];endmodule

顶层文件 vlg_top

module vlg_top(input 	clk,input 	rst_n,output 	trig
);localparam P_CLK_PERIORD = 20;//接口声明
reg clk;
reg rst_n;
reg echo;wire clk_en;
wire trig;
wire [15:0] t_us;
wire [14:0] s_mm;//使能时钟产生模块
vlg_en #(.P_CLK_PERIORD (P_CLK_PERIORD)	//clk的时钟周期为20ns
)
u_vlg_en( .clk 		(clk),.rst_n 		(rst_n),.clk_en 	(clk_en)
);//产生触发信号trig
vlg_tirg u_vlg_tirg(.clk	(clk),.rst_n	(rst_n),.clk_en	(clk_en),.trig   (trig)
);//测距模块的回响信号echo的高电平采集时间
vlg_echo u_vlg_echo(.clk	(clk),.rst_n	(rst_n),.clk_en	(clk_en),.echo	(echo),.t_us   (t_us)
);//乘法器,计算距离
cal u_cal(.clk	(clk),.rst_n	(rst_n),.t_us	(t_us),.s_mm   (s_mm)
);endmodule

调用乘法器IP核

点击IP核,输入MUL,进行下面的操作:

在这里插入图片描述


在这里插入图片描述

TB文件

`timescale 1ns/1psmodule tb_top();reg clk;
reg rst_n;
reg echo;wire [14:0] s_mm;vlg_top u_vlg_top(.clk	(clk),.rst_n	(rst_n),.trig   (trig)
);//产生时钟
initial clk = 1;
always #10 clk = ~clk;//测试激励产生
initial beginrst_n = 0;echo = 0;#200;rst_n = 1;end//函数实现 s=0.173*t
function real function_t2s;input real t;beginfunction_t2s = 0.173*t;end
endfunctioninteger tricnt = 0;
integer dly_time;always @(posedge trig)begintricnt = tricnt + 1;#5000;echo = 1;dly_time = 11+{$random}%26011;		//11<t<26011#500;$display("test %0d:\n dly_time=%0d us\n s=%0d mm\n",tricnt,dly_time,s_mm,function_t2s(dly_time));#(dly_time*1000);echo = 0;
endendmodule

仿真结果

  • 仿真波形

在这里插入图片描述

  • 结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/57918.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python工具箱系列(四十一)

使用zip批量压缩文件 前文的代码示例了使用gzip对单个文件进行压缩。本文示例使用更通用的zipfile来批量压缩文件。zipfile也是python内置的库&#xff0c;使用起来非常方便。废话不说&#xff0c;直接上代码示例。 import dbm import glob import zipfile# 保存压缩计划的库名…

AtCoder Beginner Contest 317(D-G)

D - President (atcoder.jp) &#xff08;1&#xff09;题目大意 &#xff08;2&#xff09;解题思路 考虑到z最大不超过1e5&#xff0c;N最多不超过100&#xff0c;因此可以考虑用背包来写&#xff0c;dp[j]表示拿高桥拿j分最少需要花费多少个选民转换&#xff0c;最后把答案取…

防御网络攻击风险的4个步骤

如今&#xff0c;人们正在做大量工作来保护 IT 系统免受网络犯罪的侵害。令人担忧的是&#xff0c;对于运营技术系统来说&#xff0c;情况却并非如此&#xff0c;运营技术系统用于运行从工厂到石油管道再到发电厂的所有业务。 组织应该强化其网络安全策略&#xff0c;因为针对…

移动电源专用的单节锂离子电池充电器和恒定 5V 升压控制器HU5715

航誉微HU5715 为一款移动电源专用的单节锂离子电池充电器和恒定 5V 升压控制器&#xff0c;充电 部分集高精度电压和充电电流调节器、预充、充电状态指示和充电截止等功能于一体&#xff0c; 可以输出最大 1A 充电电流。而升压电路采用 CMOS 工艺制造的空载电流极低的 VFM 开 关…

运用Python解析HTML页面获取资料

在网络爬虫的应用中&#xff0c;我们经常需要从HTML页面中提取图片、音频和文字资源。本文将介绍如何使用Python的requests库和BeautifulSoup解析HTML页面&#xff0c;获取这些资源。 一、环境准备 首先&#xff0c;确保您已经安装了Python环境。接下来&#xff0c;我们需要安…

【Java基础篇】一文搞懂Java方法的调用与重载(超详细)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【JavaSE_primary】 目录 一、方法的概念以及使用1.1什么是方法1.2方法定义1.3方法调用的执行过程1.4形参和实参的关系 二、方法的重载方…

聚观早报|2023戴尔科技峰会助力创新;小米汽车电池供应商敲定

【聚观365】8月23日消息 2023戴尔科技峰会助力企业创新 小米汽车电池供应商敲定中创新航和宁德时代 iPhone15预计有6种配色 王小川卸任自动驾驶企业禾多科技董事 特斯拉动力总成副总裁宣布离职 2023戴尔科技峰会助力企业创新 近日“新生万物 数实新格局 —— 2023戴尔科技…

暑期实习总结(焊点数据管理软件开发):Python操作MySQL数据库、Django搭建前端网页、以及Excel中数据与MySQL数据库的互转

暑期实习总结&#xff08;焊点数据管理软件开发&#xff09;:Python操作MySQL数据库、Django搭建前端网页、以及Excel中数据与MySQL数据库的互转 ​ 这一周是我在企业实习的最后一周&#xff0c;在企业做的项目已基本完成。这篇博客的目的也是总结一些项目中的一些小问题&…

实用的面试经验分享:程序员们谈论他们的面试历程

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

全套解决方案:基于pytorch、transformers的中文NLP训练框架,支持大模型训练和文本生成,快速上手,海量训练数据!

全套解决方案&#xff1a;基于pytorch、transformers的中文NLP训练框架&#xff0c;支持大模型训练和文本生成&#xff0c;快速上手&#xff0c;海量训练数据&#xff01; 1.简介 目标&#xff1a;基于pytorch、transformers做中文领域的nlp开箱即用的训练框架&#xff0c;提…

老Python程序员职业生涯感悟—写给正在迷茫的你

我来讲几个极其重要&#xff0c;但是大多数Python小白都在一直犯的思维错误吧&#xff01;如果你能早点了解清楚这些&#xff0c;会改变你的一生的。所以这一期专门总结了大家问的最多的&#xff0c;关于学习Python相关的问题来给大家聊。希望能带给大家不一样的参考。或者能提…

Cento7 Docker-compose安装RabbitMQ

RabbitMQ是一个消息中间件&#xff0c;是用Erlang语言编写的。RabbitMQ据说具有良好的性能和时效性&#xff0c;同时还能够非常好的支持集群和负载部署&#xff0c;非常适合在较大规模的分布式系统中使用。接下来我们就以docker形式安装。 1.先安装docker环境 yum -y install…

移动端h5项目的兼容和适配问题

解决兼容性问题的关键在于对移动端产品的生存环境进行梳理&#xff0c;在此基础之上制定应对策略。 所谓生存环境主要分为三个维度&#xff1a; 硬件环境&#xff0c;细分为品牌和机型&#xff0c;决定了屏幕大小、性能等硬件限制 操作系统&#xff0c;比如iOS6和iOS7&#xf…

四川玖璨电子商务有限公司:抖店运营攻略

抖店运营&#xff0c;是指在抖音平台上进行电商销售的一种新型商业模式。随着抖音平台越来越受到年轻人的喜爱和关注&#xff0c;抖店运营正变得越来越重要。那么&#xff0c;抖店运营应该如何做呢&#xff1f;我们来谈谈抖店运营的一些攻略。 第一&#xff0c;选对产品。选择…

什么是住宅ip,静态和动态怎么选?

上文我们介绍了数据中心代理&#xff0c;这次我们来介绍下住宅代理ip&#xff0c;住宅代理ip分类两种类型&#xff1a;静态住宅代理和动态住宅代理&#xff0c;他们有什么区别又能用在什么场景呢&#xff1f;我们先从他们是如何运作开始。 一、什么是住宅代理ip isp住宅代理i…

【java】【springboot】【idea】springboot项目pom.xml 灰色下划线

解决方案&#xff1a; 这里我们找到了原因&#xff0c;就是因为选择了Ignored Files导致pom.xml文件被设置在maven忽略文件清单中&#xff0c;所以我们将打勾的选项取消&#xff0c;点击Apply,然后点击OK

Spark 启动时,报JAVA_HOME is not set

文章目录 1、报错内容2、解决方式3、再次启动Spark集群 1、报错内容 Spark启动时报错&#xff1a; hadoop104: JAVA_HOME is not set2、解决方式 解决方式&#xff1a; 打开启动配置文件 cd /opt/module/spark-standalone/sbin/ vim spark-config.sh配置Java的环境变量 …

clickhouse一次异常排查记录

clickhouse中报错 关闭了自启动&#xff0c;删了status&#xff0c;重启了clickhouse还是报错 1&#xff0c;排查定时执行的脚本日志&#xff08;每小时第5分钟执行&#xff09; INSERT INTO quality0529.previously_reported_urls (url) SELECT url FROM quality0529.hourly_…

javacv基础02-调用本机摄像头并预览摄像头图像画面视频

引入架包&#xff1a; <dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.5.5-1</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId…

null和undefined区别

1.undefined&#xff0c;表示无值。 比如下面场景&#xff1a; a. 变量被声明了&#xff0c;但是没有被赋值&#xff1b; b. 调用函数的时候&#xff0c;应该给函数传参却没有给函数传这个参数打印出来就是 undefined&#xff1b; c. 访问一个对象中没有的属性&#xff1b;…