基于FPGA的超声波测距

news2024/10/5 20:22:04

文章目录

  • 一、HC-SR04超声波测距模块说明
    • 1、产品特点
    • 2、电气参数
    • 3、HC-SR04超声波测距模块
    • 4、超声波时序图
  • 二、程序设计

一、HC-SR04超声波测距模块说明

1、产品特点

HC-SR04 超声波测距模块可提供 2cm-400cm 的非接触式距离感测功能,测距精度可达高到 3mm;模块包括超声波发射器、接收器与控制电路。

基本工作原理:
(1)采用 IO 口 TRIG 触发测距,给最少 10us 的高电平信呈。
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声
波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。

2、电气参数

在这里插入图片描述

3、HC-SR04超声波测距模块

在这里插入图片描述
VCC 供 5V电源,GND 为地线,TRIG 触 发 控 制 信 号 输入,ECHO 回响信号输出等四个接口端。

4、超声波时序图

在这里插入图片描述
以上时序图表明你只需要提供一个 10uS 以上脉冲触发信号,该模块内部将
发出 8 个 40kHz 周期电平并检测回波。一旦检测到有回波信号则输出回响信号。
回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号
时间间隔可以计算得到距离。公式:uS/58=厘米或者 uS/148=英寸;或是:距离= 高电平时间*声速(340M/S)/2;建议测量周期为 60ms 以上,以防止发射信号对
回响信号的影响。

注:
1、此模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则会影响模块的正常工作。
2、测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果

二、程序设计

在这里插入图片描述

/*================================================*\
		  Filename ﹕
			Author ﹕
	  Description  ﹕产生周期为1us的时钟信号
		 Called by ﹕
Revision History   ﹕ mm/dd/202x
		  			  Revision 1.0
  			  Email﹕ 
			Company﹕ 
\*================================================*/
module 	clk_div(
	input  wire			Clk		, //system clock 50MHz
	input  wire 		Rst_n	, //reset ,low valid
		   
	output wire  		clk_us 	  //
);
//Parameter Declarations
	parameter CNT_MAX = 19'd50;//1us的计数值为 50 * Tclk(20ns)

//Interrnal wire/reg declarations
	reg		[5:00]	cnt		; //Counter 
	wire			add_cnt ; //Counter Enable
	wire			end_cnt ; //Counter Reset 
	
//Logic Description
	
	always @(posedge Clk or negedge Rst_n)begin  
		if(!Rst_n)begin  
			cnt <= 'd0; 
		end  
		else if(add_cnt)begin  
			if(end_cnt)begin  
				cnt <= 'd0; 
			end  
			else begin  
				cnt <= cnt + 1'b1; 
			end  
		end  
		else begin  
			cnt <= cnt;  
		end  
	end 
	
	assign add_cnt = 1'b1; 
	assign end_cnt = add_cnt && cnt >= CNT_MAX - 19'd1;
	
	assign clk_us = end_cnt;
	

endmodule 


/*================================================*\
		  Filename ﹕
			Author ﹕
	  Description  ﹕超声波检测距离模块
					本模块理论测试距离 2cm~510cm
						输出结果保留两位小数
		 Called by ﹕
Revision History   ﹕ mm/dd/202x
		  			  Revision 1.0
  			  Email﹕ 
			Company﹕ 
\*================================================*/
module 	hc_sr_echo(
	input  wire 		Clk		, //clock 50MHz
	input  wire			clk_us	, //system clock 1MHz
	input  wire 		Rst_n	, //reset ,low valid
		   
	input  wire 		echo	, //
	output wire [31:00]	data_o	  //检测距离,保留3位小数,*1000实现
);
/* 		S(um) = 17 * t 		-->  x.abc cm	*/
//Parameter Declarations
	parameter T_MAX = 16'd60_000;//510cm 对应计数值

//Interrnal wire/reg declarations
	reg				r1_echo,r2_echo; //边沿检测	
	wire			echo_pos,echo_neg; //
	
	reg		[15:00]	cnt		; //Counter 
	wire			add_cnt ; //Counter Enable
	wire			end_cnt ; //Counter Reset 
	
	reg		[31:00]	data_r	;
//Logic Description
	//如果使用clk_us 检测边沿,延时2us,差值过大
	always @(posedge Clk or negedge Rst_n)begin  
		if(!Rst_n)begin  
			r1_echo <= 1'b0;
			r2_echo <= 1'b0;
		end  
		else begin  
			r1_echo <= echo;
			r2_echo <= r1_echo;
		end  
	end
	
	assign echo_pos = r1_echo & ~r2_echo;
	assign echo_neg = ~r1_echo & r2_echo;
	
	
	always @(posedge clk_us or negedge Rst_n)begin  
		if(!Rst_n)begin  
			cnt <= 'd0; 
		end 
		else if(add_cnt)begin  
			if(end_cnt)begin  
				cnt <= cnt; 
			end  
			else begin  
				cnt <= cnt + 1'b1; 
			end  
		end  
		else begin  //echo 低电平 归零
			cnt <= 'd0;  
		end  
	end 
	
	assign add_cnt = echo; 
	assign end_cnt = add_cnt && cnt >= T_MAX - 1; //超出最大测量范围则保持不变,极限
	
	always @(posedge Clk or negedge Rst_n)begin  
		if(!Rst_n)begin  
			data_r <= 'd2;
		end  
		else if(echo_neg)begin  
			data_r <= (cnt << 4) + cnt;
		end  
		else begin  
			data_r <= data_r;
		end  
	end //always end
	
	assign data_o = data_r >> 1;

endmodule 


/*================================================*\
		  Filename ﹕
			Author ﹕
	  Description  ﹕超声波触发测距模块
					波形周期300ms,前10us高电平
		 Called by ﹕
Revision History   ﹕ mm/dd/202x
		  			  Revision 1.0
  			  Email﹕ 
			Company﹕ 
\*================================================*/
module 	hc_sr_trig(
	input  wire			clk_us	, //system clock 1MHz
	input  wire 		Rst_n	, //reset ,low valid
		   
	output wire  		trig	  //触发测距信号
);
//Parameter Declarations
	parameter CYCLE_MAX = 19'd300_000;

//Interrnal wire/reg declarations
	reg		[18:00]	cnt		; //Counter 
	wire			add_cnt ; //Counter Enable
	wire			end_cnt ; //Counter Reset 

//Logic Description	
	
	always @(posedge clk_us or negedge Rst_n)begin  
		if(!Rst_n)begin  
			cnt <= 'd0; 
		end  
		else if(add_cnt)begin  
			if(end_cnt)begin  
				cnt <= 'd0; 
			end  
			else begin  
				cnt <= cnt + 1'b1; 
			end  
		end  
		else begin  
			cnt <= cnt;  
		end  
	end 
	
	assign add_cnt = 1'b1; 
	assign end_cnt = add_cnt && cnt >= CYCLE_MAX - 9'd1; 
	
	assign trig = cnt < 15 ? 1'b1 : 1'b0;

endmodule 


数码管显示

/*================================================*\
		  Filename ﹕seg_driver.v
			Author ﹕Adolph
	  Description  ﹕对输入的数据译码,并驱动数码管显示对应数据
		 Called by ﹕seg_top.v
Revision History   ﹕ 2022-5-30 14:27:22
		  			  Revision 1.0
  			  Email﹕adolph1354238998@gmail.com
			Company﹕ 
\*================================================*/
module seg_driver(
	input			clk		,
	input			rst_n	,
	
	input	  [31:0]dis_data,//待显示的数据
	output wire [7:0]	dig_sel	,
	output wire [7:0]	dig_seg	 
);
//wire  [31:0]dis_data;


//	assign seg_r = 8'd0;
//	assign sel_r = 1'b0;
	localparam
		NUM_0  	= 8'hC0,
		NUM_1  	= 8'hF9,
		NUM_2  	= 8'hA4,
		NUM_3  	= 8'hB0,
		NUM_4  	= 8'h99,
		NUM_5  	= 8'h92,
		NUM_6  	= 8'h82,
		NUM_7  	= 8'hF8,
		NUM_8  	= 8'h80,
		NUM_9  	= 8'h90,
		NUM_A  	= 8'h88,
		NUM_B  	= 8'h83,
		NUM_C  	= 8'hC6,
		NUM_D  	= 8'hA1,
		NUM_E  	= 8'h86,
		NUM_F  	= 8'h8E,
		LIT_ALL	= 8'h00,
		BLC_ALL	= 8'hFF;
	parameter CNT_REF = 25'd1000;
	
	reg	[9:0]	cnt_20us; //20us计数器
	reg	[3:0] 	data_tmp; //用于取出不同位选的显示数据
	
reg [7:0] seg_r;
reg [7:0] sel_r;
//	assign dis_data = 32'hABCD_4413;
//描述位选信号切换
	//描述刷新计数器
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			cnt_20us <= 25'd0;
		end
		else if(cnt_20us >= CNT_REF - 25'd1)begin
			cnt_20us <= 25'd0;
		end
		else begin
			cnt_20us <= cnt_20us + 25'd1;
		end
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			sel_r <= 8'hfe;//8'b1111_1110
		end
		else if(cnt_20us >= CNT_REF - 25'd1)begin
			sel_r <= {sel_r[6:0],sel_r[7]};
		end
		else begin
			sel_r <= sel_r;
		end
	end
	
//段选信号描述
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			data_tmp <= 4'd0;
		end
		else begin
			case(sel_r)
				8'b1111_1110:data_tmp <= dis_data[ 3-:4];
				8'b1111_1101:data_tmp <= dis_data[ 7-:4];
				8'b1111_1011:data_tmp <= dis_data[11-:4];
				8'b1111_0111:data_tmp <= dis_data[15-:4];
				8'b1110_1111:data_tmp <= dis_data[19-:4];
				8'b1101_1111:data_tmp <= dis_data[23-:4];
				8'b1011_1111:data_tmp <= dis_data[27-:4];
				8'b0111_1111:data_tmp <= dis_data[31-:4];
				default: data_tmp <= 4'hF;
			endcase
		end
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			seg_r <= BLC_ALL;
		end
		else begin
			case(data_tmp)
				4'h0 : seg_r <= NUM_0;
				4'h1 : seg_r <= NUM_1;
				4'h2 : seg_r <= NUM_2;
				4'h3 : seg_r <= NUM_3;
				4'h4 : seg_r <= NUM_4;
				4'h5 : seg_r <= NUM_5;
				4'h6 : seg_r <= NUM_6;
				4'h7 : seg_r <= NUM_7;
				4'h8 : seg_r <= NUM_8;
				4'h9 : seg_r <= NUM_9;
				4'hA : seg_r <= NUM_A;
				4'hB : seg_r <= NUM_B;
				4'hC : seg_r <= NUM_C;
				4'hD : seg_r <= NUM_D;
				4'hE : seg_r <= NUM_E;
				4'hF : seg_r <= NUM_F;
				default: ;
			endcase 
		end
	end

assign dig_seg = seg_r;
assign dig_sel = sel_r;

endmodule 

顶层文件

module HC_SR04_TOP (
    input       wire        clk,
    input       wire        rst_n,
    input       wire        echo,

    output      wire        trig,
    output      wire [7:0]   sel,
    output      wire [7:0]   seg
);

wire clk_us;
wire [31:0] data;

clk_div clk_div_inst(
	.		Clk		(clk), //system clock 50MHz
	.		Rst_n	(rst_n), //reset ,low valid

	.		clk_us 	 (clk_us) //
);

hc_sr_trig hc_sr_trig_inst(
	.		clk_us	(clk_us), //system clock 1MHz
	.		Rst_n	(rst_n), //reset ,low valid

	. 		trig	 (trig) //触发测距信号
);

hc_sr_echo hc_sr_echo_inst(
	.Clk		(clk), //clock 50MHz
	.clk_us	(clk_us), //system clock 1MHz
	.Rst_n	(rst_n), //reset ,low valid

	.echo	(echo), //
	.data_o	 (data) //检测距离,保留3位小数,*1000实现
);

seg_driver seg_driver_inst(
	.clk	(clk)	,
	.rst_n	(rst_n),
	
	.dis_data (data),//待显示的数据
	.dig_sel    (sel),
	.dig_seg	(seg)
);

endmodule //top

仿真测试

/*================================================*\
		  Filename ﹕tb_hc_sr.v
			Author ﹕Adolph
	  Description  ﹕超声波驱动测试文件
		 Called by ﹕
Revision History   ﹕ mm/dd/202x
		  			  Revision 1.0
  			  Email﹕ 
			Company﹕ 
\*================================================*/
`timescale 1ns/1ns 		//仿真系统时间尺度定义

`define clk_period 20  	//时钟周期参数定义	

module tb_hc_sr(); 
//激励信号定义  
	reg				clk		; 
	reg				rst_n	; 
	reg				echo; //
	
//响应信号定义	  
	wire	 		trig	;
	
	wire[7:0]       seg     ;

    wire[7:0]       sel     ;            
//实例化
	HC_SR04_TOP		HC_SR04_TOP(
		/*input  		*/.clk		(clk		), //system clock 50MHz
		/*input   		*/.rst_n	(rst_n		), //reset ,low valid
		
		/*input   		*/.echo		(echo		), //
		/*output   		*/.trig		(trig		), //触发测距信号
		
		/*output   		*/.seg		(seg		), //
		/*output   		*/.sel		(sel		) //触发测距信号
	);

//产生时钟							       		 
	initial clk = 1'b0;		       		 
	always #(`clk_period / 2) clk = ~clk;  		 

//产生激励	 
	initial  begin	 
		rst_n = 1'b0;	 
		echo  = 1'b0;
		#(`clk_period * 20 + 3);	 
		rst_n = 1'b1;	 
		#(`clk_period * 20); 
		
		wait(HC_SR04_TOP.hc_sr_echo_inst.cnt == 240);
		echo = 1'b1;//测试超声波信号发送完成,echo拉高
		
		#(50 * `clk_period * 2500 + 7);
		echo = 1'b0;
		
		#(`clk_period * 200);
		$stop(2); 
	end	 

endmodule

参考链接
https://blog.csdn.net/qq_43546203/article/details/125281386
https://blog.csdn.net/qq_43546203/article/details/125282050

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

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

相关文章

驱动开发--字符设备驱动

目录 1.驱动模块 hello.c Makefile 2.内核中的打印函数&#xff08;编写第一个驱动程序&#xff09; Source Insight 使用&#xff1a; 3.打印函数编写 分析 4、驱动的多文件编译 5、模块传递参数 6、安装好驱动之后如何传参&#xff1f; 7、字符设备驱动 8、字符设…

云上VPC网络规划实战

新钛云服已累计为您分享750篇技术干货 什么是VPC 虚拟专有网络&#xff08;Virtual Private Cloud&#xff0c;简称VPC&#xff09;是阿里云提供的一种云上私有网络&#xff0c;为用户提供独立且可控的网络环境。用户可以自主定义VPC的IP地址范围、配置路由表和网关等&#xff…

chatgpt赋能python:Python在Win7上的安装教程

Python在Win7上的安装教程 如果你是一名Win7用户&#xff0c;并且打算开始学习或者使用Python编程语言&#xff0c;那么本文将会为你提供一个简单易懂的Python安装教程。 1. 下载Python 在安装Python之前&#xff0c;你需要先去Python的官方网站&#xff08;https://www.pyt…

chatgpt赋能python:Python输出0到9:从基础到高阶

Python 输出 0 到 9&#xff1a;从基础到高阶 在Python中&#xff0c;输出0到9这样的数字非常简单&#xff0c;你可以使用内置的range()函数或循环进行实现。在本篇文章中&#xff0c;我们将介绍几种不同的方法来输出0到9的数字。 使用range()函数输出0到9 range()函数是Pyt…

夜天之书 #84 国产开源社群的运营,为何总是画风奇特?

在过去几年的投入和关注下&#xff0c;国产开源社群如雨后春笋一般冒了出来。今天&#xff0c;以 GPT 为首的 AI 新势力接过话题度的接力棒&#xff0c;我们可以在降温周期里回顾一下过去几年间冒出来的国产开源社群都有什么样的成绩&#xff0c;有些什么样共性的问题可以改进。…

苹果宣布最新操作系统:visionOS

今天凌晨&#xff0c;WWDC23 全球开发者大会正式开幕。 大会上&#xff0c;苹果展示了包括 iOS 17、iPadOS 17、watchOS 10 和 macOS Sonoma 在内的新系统。硬件方面&#xff0c;苹果发布了 15 英寸的 MacBook Air、搭载 M2 Ultra 的 Mac Studio 以及 Mac Pro。 此外&#xff0…

sqlserver练习----涉及多个表的连接查询

等值联接 多表查询语句中的连接条件使用的是等号,例&#xff1a;Student.SnoSC.Sno 例&#xff1a; Student 学号 Sno 姓名 Sname 性别 Ssex 年龄 Sage 所在系 Sdept 202015121李勇男20CS202015122刘晨女10 CS 202015123 王敏女18 MA 202015125张力男19IS SC: 学号 Sn…

秋招面试腹稿

1、自我介绍 你好&#xff0c;我叫熊志君&#xff0c;是就读于电子信息专业的24届研究生。在校期间获得过两次一等奖学金、两次省级竞赛一等奖&#xff0c;英语过了6级&#xff0c;我的研究方向是水下slam多传感器融合方向&#xff0c;用过c/c/python三种编程语言。 2、系统移植…

如何缓解高考前紧张的情绪,ChatGPT这么说......

明天就要高考了&#xff0c;看到家长有各种打气的做法&#xff0c;既有上灵隐寺的&#xff0c;也有穿着旗袍希望旗开得胜的&#xff0c;还有说什么失败了不要紧的......&#xff0c;反正都是焦虑的不行。 面对高考&#xff0c;大多考生都会紧张&#xff0c;但适度的紧张对发挥出…

解码器 | 基于 Transformers 的编码器-解码器模型

基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶。本文简要介绍了神经编码器-解码器模型的历史&#xff0c;更多背景知识&#xff0c;建议读者阅读由 Sebastion Ruder 撰写的这篇精彩 博文。此外&#xff0c;建议读者对 自注意力 (…

Mocha AE:AdjustTrack 模块

跟踪时由于缺乏细节或有障碍物阻挡&#xff0c;跟踪点会发生漂移&#xff0c;此时可考虑使用 AdjustTrack &#xff08;调整跟踪&#xff09;模块手动设置表面区域 Planar Surface关键帧来获得更可靠的表面跟踪数据。 但是&#xff0c;如果需要设置较多的关键帧时&#xff0c;建…

Linux计划任务

常见的计划任务&#xff1a;进行日志的轮替&#xff08;log rotate&#xff09;&#xff1b;日志文件分析&#xff08;logwatch&#xff09;任务&#xff1b;建立locate数据库&#xff1b;man page查询数据库的建立&#xff1b;RPM软件登录文件的建立&#xff1b;移除暂存档&am…

尺度悖论解析费米悖论:从夜郎自大到揭秘宇宙中智慧生命的谜团

费米悖论是一个引人入胜的问题&#xff0c;它引发了人们对宇宙中是否存在其他智慧生命体的思考。然而&#xff0c;尺度悖论提供了一个可能的解释角度&#xff0c;即我们对宇宙的观测和推断尺度可能太小&#xff0c;无法涵盖整个宇宙范围。下面深入探讨尺度悖论以及费米悖论的具…

Linux系统一般用来干嘛

Linux系统是一种开源的操作系统&#xff0c;广泛应用于服务器、嵌入式设备、超级计算机等领域。它具有高度的稳定性、安全性和灵活性&#xff0c;可以用来进行各种各样的任务&#xff0c;例如&#xff1a; 1、服务器操作系统 Linux系统在服务器领域应用广泛&#xff0c;可以用…

Maven继承

Maven 在设计时&#xff0c;借鉴了 Java 面向对象中的继承思想&#xff0c;提出了 POM 继承思想。 当一个项目包含多个模块时&#xff0c;可以在该项目中再创建一个父模块&#xff0c;并在其 POM 中声明依赖&#xff0c;其他模块的 POM 可通过继承父模块的 POM 来获得对相关依赖…

微信小程序自定义导航栏

微信小程序自定义导航栏 业务需求&#xff1a; 点击小房子进行跳转指定的页面 、更改小房子的样式、或者是自定义导航栏 首先我们需要找到pages.json这个文件 如果是原生的微信小程序文件名字是 app.json其实就是找到配置路由的文件在代码里面添加属性"navigationStyle&qu…

java设计模式(十四)模板方法

目录 定义模式结构角色职责代码实现适用场景优缺点 定义 模板方法模式(Template Method Pattern)&#xff0c;又叫模板模式(Template Pattern)&#xff0c; 指在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现&#xff0c;但调用将以抽象类中定义的…

1. Hadoop 入门

1. Hadoop 入门 1. 大数据概述 1. 大数据相关说明 大数据由来&#xff1a; 传统数据处理应用软件不足以处理&#xff08;存储和计算&#xff09;它们大而复杂的数据集 大数据面临的两大问题&#xff1a; 针对海量数据的 存储、计算 大数据的特性&#xff1a;容量大、种类多…

VFP使用BLOB字段存取图片到SQL2000,显示出来也EASY

首先来看一下BLOB这个数据类型的介绍&#xff1a; 大二进制对象(Blob)数据类型&#xff0c;若要存储一个任何种类的二进制数据&#xff0c;如 ASCII 码文本、一个可执行文件(.exe) 或一个带有不确定长度的字节字符串&#xff0c;可使用大二进制对象数据类型。对于从 SQL Serve…

c++11 标准模板(STL)(std::bitset)(六)

定义于头文件 <bitset> template< std::size_t N > class bitset; 类模板 bitset 表示一个 N 位的固定大小序列。可以用标准逻辑运算符操作位集&#xff0c;并将它与字符串和整数相互转换。 bitset 满足可复制构造 (CopyConstructible) 及可复制赋值 (CopyAssign…