HC-SR04 超声波测距模块可提供 2cm-400cm 的非接触式距离感测功能,测距精度可达高到 3mm;模块包括超声波发射器、接收器与控制电路。
基本工作原理:
(1)采用 IO 口 TRIG 触发测距,给最少 10us 的高电平信呈。
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声
波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。
VCC 供 5V电源,GND 为地线,TRIG 触 发 控 制 信 号 输入,ECHO 回响信号输出等四个接口端。
以上时序图表明你只需要提供一个 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﹕[email protected]
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