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 [18: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 [18: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
时间: 2024-03-19 07:41:10 浏览: 9
这是一个 Verilog HDL 的模块,名称为 hc_sr_echo,用于实现 HC-SR04 超声波测距模块的驱动。它有以下输入输出端口:
输入端口:
- Clk:时钟信号,频率为 50MHz。
- clk_us:系统时钟信号,频率为 1MHz。
- Rst_n:异步复位信号,低电平有效。
- echo:超声波接收信号,高电平表示接收到超声波信号。
输出端口:
- data_o:测量到的距离数据,保留 3 位小数,单位为毫米。
该模块通过计数来测量超声波信号的传播时间,从而得到距离数据。具体实现过程为:
1. 在时钟上升沿或复位信号下降沿时,记录上一次的 echo 信号和当前的 echo 信号,得到 echo_pos 和 echo_neg 信号,用于检测超声波信号的上升沿和下降沿。
2. 在系统时钟上升沿或复位信号下降沿时,根据 echo_pos 和 echo_neg 信号,通过计数器 cnt 记录超声波信号的传播时间,并判断是否超出最大测量范围(510cm)。
3. 在时钟上升沿或复位信号下降沿时,根据 echo_neg 信号和计数器 cnt 的值,计算出测量到的距离数据,输出到 data_o 端口。
相关问题
module e_and_t( input wire Clk , //system clock 100MHz input wire Rst_n , //reset ,low valid input wire echo , // output wire trig , //触发测距信号 output wire [9:00] data_o //检测距离,保留3整数,单位:cm ); //Interrnal wire/reg declarations wire clk_us; // //Module instantiations , self-build module clk_div clk_div( /*input wire */.Clk (Clk ), //system clock 100MHz /*input wire */.Rst_n (Rst_n ), //reset ,low valid /*output wire */.clk_us (clk_us ) // ); hc_sr_trig hc_sr_trig( /*input wire */.clk_us (clk_us ), //system clock 1MHz /*input wire */.Rst_n (Rst_n ), //reset ,low valid /*output wire */.trig (trig ) //触发测距信号 ); hc_sr_echo hc_sr_echo( /*input wire */.Clk (Clk ), //clock 100MHz /*input wire */.clk_us (clk_us ), //system clock 1MHz /*input wire */.Rst_n (Rst_n ), //reset ,low valid /*input wire */.echo (echo ), // /*output reg [9:00]*/.data_o (data_o ) //检测距离,保留3位整数,*1000实现 ); //Logic Description endmodule
这段代码是一个 Verilog HDL 的模块 e_and_t,它实现了 HC-SR04 超声波测距模块的驱动。模块有四个输入信号:系统时钟 Clk,复位信号 Rst_n,回声信号 echo,以及一个输出信号 trig,它的作用是触发 HC-SR04 开始测距。此外,模块还有一个 10 位的输出信号 data_o,它是通过 HC-SR04 返回的脉冲宽度计算得到的距离值,单位为 cm,保留了 3 位整数部分。模块内部实例化了两个自定义模块 clk_div 和 hc_sr_trig,它们的作用是将系统时钟 Clk 分频到 1 MHz,并生成 HC-SR04 的触发信号 trig。另外,模块还实例化了一个自定义模块 hc_sr_echo,它通过回声信号 echo 和分频后的时钟 clk_us 计算 HC-SR04 返回的脉冲宽度,并将距离值输出到 data_o。
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 [18: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 [18: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请详细解释这段代码
这段代码是一个 Verilog HDL 的模块,用于实现超声波测距模块 HC-SR04 的回波信号处理。以下是代码的详细解释:
1. 模块输入输出说明
```Verilog
module hc_sr_echo(
input wire Clk, // 时钟信号,50MHz
input wire clk_us, // 系统时钟,1MHz
input wire Rst_n, // 复位信号,低电平有效
input wire echo, // 超声波回波信号
output wire [18:0] data_o // 检测距离,保留3位小数,*1000实现
);
```
2. 模块内部参数定义
```Verilog
parameter T_MAX = 16'd60_000; // 510cm 对应计数值
```
T_MAX 定义了最大计数值,即最大测量距离为 510cm。
3. 模块内部信号定义
```Verilog
reg r1_echo, r2_echo; // 边沿检测
wire echo_pos, echo_neg; //
reg [15:0] cnt; // 计数器
wire add_cnt; // 计数器使能
wire end_cnt; // 计数器复位
reg [18:0] data_r; // 逻辑输出
```
其中,r1_echo 和 r2_echo 用于检测超声波回波信号的上升沿和下降沿;cnt 是计数器;add_cnt 和 end_cnt 控制计数器的启动和复位;data_r 是输出的距离测量值。
4. 边沿检测
```Verilog
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
```
这段代码使用了 always 块和 if 语句,实现了超声波回波信号的边沿检测,即检测上升沿和下降沿。
5. 计数器
```Verilog
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
cnt <= 'd0;
end
end
```
这段代码使用了 always 块和 if 语句,实现了计数器的功能。当 add_cnt 为 1 时,计数器开始计数,直到 cnt 达到 T_MAX - 1 或 end_cnt 为 1,计数器复位为 0。
6. 距离测量
```Verilog
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 块和 if 语句,根据计数器的值计算出距离测量值并输出到 data_r。
7. 输出信号
```Verilog
assign data_o = data_r >> 1;
```
这段代码使用了 assign 语句,将 data_r 的值右移 1 位后输出到 data_o,得到最终的距离测量值,单位为毫米。