FPGA零基础之Vivado-超声波驱动设计

时间:2025-06-17  作者:Diven  阅读:0

一、简介

FPGA零基础之Vivado-超声波驱动设计

声音是我们日常生活中不可缺少的信号,在传递信息的也在生活中的各个领域有较多的应用。根据声音的频率,我们将声音大致划分为三个阶段,人耳的听力范围,一般在20Hz~20000Hz之间。低于这个范围,我们称之为次声波;高于这个范围,称之为超声波。超声波的应用比较,比如:超声波检查、超声波碎石、超声波清洗、超声波测速、超声波测距等等。此次我们就来研究一下其中一项应用:超声波测距。

我们用到的试验模块为HC-SR04超声波模块,测量距离在2cm~400cm之间。测量精度在3mm左右。模块包含了超声波的发射器、接收器和控制电路。超声波发射器在启动后会发出固定频率的方波,用声波去测量距离,不需要我们接触被测物体,在空间上使得我们测距变得方便很多。

二、工作原理

1、采用IO口TRIG触发测距,给至少10us的高电平信号,测量周期建议在60ms以上,以防止发射的信号对回响信号造成影响。

2、模块会自动发送8个40Khz的方波信号,接收器自动检测是否有回响信号返回。

3、有信号返回时,通过IO口ECHO输出一个高电平信号,高电平持续的时间就是方波从发射到返回的时间。测量距离=(高电平时间*声速(340m/s))/2;

在此需要我们注意的事,发射器是自动发送方波信号的,而且会自动检测是否有信号返回,这让我们省去了一大部分工作,使得测量变得简单。在计算测量距离时,我们要将计算出来的结果除以2,因为我们测得的时间是往返的时间,也就是双倍的路程。

三、实物图

四、电气参数

五、超声波时序图

在时序图中,我们可以看出,我们需要生成一个周期至少为60ms,且高电平维持时间至少为10us的一个触发信号。

六、实验要求

此次设计,要求能够正常驱动模块,计算出的距离,计算其平均值以保证准确性。数码管上显示出距离,单位为m,精确到mm。并且,蜂鸣器能够根据距离响出不同频率的报警声音,距离越近,响声频率越频繁。

七、设计框架

八、设计实现

在计算回响信号的时间时,我们可以检测回响信号的上升沿和下降沿来作为计时器的开始和结束。在我们计算出距离之后,可以每三个数据计算一次平均值。然后将数据输出给其模块。

我们新建工程。

选择新建文件,然后先新建顶层文件

按照我们所画框架,写入顶层端口。

重复上述新建文件的过程,新建ultrasonIC_driver文件,代码如下: 

 

1 Module ultrasonIC_driver(2 3 input wire clk,4 input wire rst_n,5 input wire echo,6 output reg trig,7 output reg [11:0] distance,8 output reg data_valid9 );10 11 parameter t = 3_000_000;12 13 reg [21:0] cnt;14 reg state;15 reg echo_r, echo_rr;16 reg [20:0] echo_cnt;17 reg [20:0] cnt_temp;18 wire [11:0] d_r;19 reg [35:0] temp;20 reg data_valid_r;21 22 always @ (posedge clk) echo_r <= echo;23 always @ (posedge clk) echo_rr <= echo_r;24 25 always @ (posedge clk, negedge rst_n)26 begin27 if(rst_n == 1'b0)28 cnt <= 22'd0;29 else if(cnt == t - 1)30 cnt <= 22'd0;31 else32 cnt <= cnt + 1'b1;33 end34 35 always @ (posedge clk, negedge rst_n)36 begin37 if(rst_n == 1'b0)38 trig <= 1'b0;39 else if(cnt < 1000)40 trig <= 1'b1;41 else42 trig <= 1'b0;43 end44 45 always @ (posedge clk, negedge rst_n)46 begin47 if(rst_n == 1'b0)48 begin49 echo_cnt <= 21'd0;50 state <= 1'd0;51 data_valid_r <= 1'b0;52 echo_cnt <= 21'd0;53 end54 else55 case(state)56 1'd0 : begin57 if(echo_r & (~echo_rr))58 state <= 1'd1;59 else60 begin61 state <= 1'd0;62 data_valid_r <= 1'b0;63 end64 end65 1'd1 : begin66 if((~echo_r) & echo_rr)67 begin68 state <= 1'd0;69 echo_cnt <= 21'd0;70 cnt_temp <= echo_cnt;71 data_valid_r <= 1'b1;72 end73 else74 begin75 state <= 1'd1;76 echo_cnt <= echo_cnt + 1'b1;77 cnt_temp <= cnt_temp;78 end79 end80 endcase81 end82 83 assign d_r = cnt_temp * 34 / 10_000;84 85 always @ (posedge clk, negedge rst_n)86 begin87 if(rst_n == 1'b0)88 temp <= 36'd0;89 else if(data_valid_r)90 temp <= {temp[23:0],d_r};91 else92 temp <= temp;93 end94 95 always @ (posedge clk) data_valid <= data_valid_r;96 97 always @ (posedge clk, negedge rst_n)98 begin99 if(rst_n == 1'b0)100 distance <= 12'd0;101 else if(data_valid)102 distance <= (temp[35:24] + temp[23:12] + temp[11:0]) / 3;103 else104 distance <= distance;105 end106107 endModule

 

在完成测距时,输出一个valid信号,这个信号要作为后续我们保存数据以及计算平均值的标志信号。

数码管代码如下:

 

1 module seven_tube_driver(2 3 input wire clk,4 input wire rst_n,5 input wire [11:0] data, 6 7 output reg [5:0] sel,8 output wire [7:0] seg9 );10 11 parameter t = 50000;12 13 reg [15:0] cnt;14 reg [3:0] show_data;15 reg [7:0] seg_r;16 17 always @ (posedge clk, negedge rst_n)18 begin19 if(rst_n == 1'b0)20 cnt <= 16'd0;21 else if(cnt == t - 1)22 cnt <= 16'd0;23 else24 cnt <= cnt + 1'b1;25 end26 27 always @ (posedge clk, negedge rst_n)28 begin29 if(rst_n == 1'b0)30 sel <= 6'b111_110;31 else if(cnt == t - 1)32 sel <= {sel[4:0],sel[5]};33 else34 sel <= sel;35 end36 37 always @ (*)38 begin39 case(sel)40 6'b111_110 : show_data = 4'hf;41 6'b111_101 : show_data = 4'hf;42 6'b111_011 : show_data = data/1000;43 6'b110_111 : show_data = data/100%10;44 6'b101_111 : show_data = data/10%10;45 6'b011_111 : show_data = data%10;46 default : show_data = 4'd0;47 endcase48 end49 50 always @ (*)51 begin52 case(show_data)53 4'd0 : seg_r = 8'b1100_0000;54 4'd1 : seg_r = 8'b1111_1001;55 4'd2 : seg_r = 8'b1010_0100;56 4'd3 : seg_r = 8'b1011_0000;57 4'd4 : seg_r = 8'b1001_1001;58 4'd5 : seg_r = 8'b1001_0010;59 4'd6 : seg_r = 8'b1000_0010;60 4'd7 : seg_r = 8'b1111_1000;61 4'd8 : seg_r = 8'b1000_0000;62 4'd9 : seg_r = 8'b1001_0000;63 default: seg_r = 8'd0;64 endcase65 end66 67 assign seg = (sel == 6'b111_011) ? (seg_r & 8'b0111_1111) : seg_r;68 69 endmodule

 

第67行的作用是为了在显示时,显示一个小数点,这样数码管显示的数值单位就为米,精确度为毫米。

蜂鸣器模块中,蜂鸣器的响声为“嘀嘀”的响声,我们可以根据距离的大小,让蜂鸣器响声的快慢作出改变。

我们根据距离改变计数器的最大计数次数,以达到两次“嘀嘀”响声的时间间隔发生变化。

写好代码之后,我们做一下仿真,代码如下:

 

1 `timescale 1ns / 1ps2 3 module ultrasonic_tb;4 5 reg clk;6 reg rst_n;7 reg echo;8 wire trig;9 wire [5:0] sel;10 wire [7:0] seg;11 wire beep;12 13 defparam ultrasonic_inst.ultrasonic_driver_inst.t = 3000;14 15 initial begin16 clk = 1'b0;17 rst_n = 1'b0;18 echo = 1'b0;19 #105;20 rst_n = 1'b1;21 #1000;22 23 repeat(10) begin24 @ (negedge trig);25 #1002;26 echo = 1'b1;27 #20000;28 echo = 1'b0;29 end30 #10000;31 $stop;32 end33 34 always #10 clk = ~clk;35 36 ultrasonic ultrasonic_inst(37 .clk (clk ),38 .rst_n (rst_n ),39 .echo (echo ),40 .trig (trig ),41 .sel (sel ),42 .seg (seg ),43 .beep (beep )44 );45 46 endmodule

 

仿真图如下:

从图中我们可以看出,距离在多次采样之后达到了稳定值。由于我们仿真时间给的较短,所以距离的数值不大,但是已经足够看出结果。
审核编辑:刘清
 

猜您喜欢

2017-01-27 00:00:00

吸盘天线是常见的无线通信设备,应用于汽车、家庭和办公环境中。其规格尺寸通常因制造商和具体用途而异,但常见的吸盘天线直径在10厘米到20厘米之间,厚度则在1厘米到...
2009-05-08 00:00:00

硅电容是新型电容器。用硅材料制作,性能优越。许多电子设备中都能见到。接下来,我们将详细介绍硅电容的特点和应用。硅电容的基本原理硅电容工作原理简单。利用硅的半导体...
2025-03-27 18:01:07

在气象环境监测、产品质量检测等领域,经常需要测定浊度。浊度表征了无色透明液体中悬浮物和胶体物质对光线透射所产生的阻碍程度。在理想的状况下,浊度可以通过理论计算获...
2018-04-13 16:05:00

0402贴片电阻的标准功率是1/16瓦,也就是0.0625瓦。 需要注意的是,这只是一个典型值,实际功率会受到多种因素的影响,例如环境温度、散热条件以及电阻本身...
2025-04-14 15:03:49

现代电力系统和电子设备中,开关电源被应用,其高效的电能转换能力和稳定的输出性能,为各类设备提供了可靠的能量支持。无论是工程师还是对电力电子感兴趣的一般受众,掌握...
2024-10-18 00:00:00

TT Electronics 作为英国知名的制造商,很好的升功率电阻系列闻名于世。该系列电阻不仅性能稳定,而且具备极高的可靠性,应用于各种电子设备中。本文将详细...
2017-10-31 12:05:30


PDIP8_9.59X6.35MM是一个在电子元件领域中常见的封装类型,其尺寸和结构使其在各种应用中广泛使用。本文将深入探讨PDIP8_9.59X6.35MM的...
2025-02-21 12:25:32

贴片电阻,顾名思义,就是贴装在电路板表面的一种电阻器。它体积微小,通常只有几毫米大小,却在电子电路中扮演着至关重要的角色。贴片电阻最基本的作用是限制电流的流动。...
2024-11-26 11:29:13