超声波测距#倒车雷达#DE10-Lite
一、项目背景与目标
HC‑SR04 是一款常用的超声波测距模块,通过测量回波时间来计算距离。
相比单片机,FPGA 具有并行处理能力强、时序控制精确的优势。
本设计的主要目标包括三点:
1. 产生符合要求的 trig 触发信号(>10us);
2. 精确测量 echo 回波的高电平时间;
3. 将计算得到的距离通过数码管实时显示。
4. 蜂鸣器根据距离远近产生不响,慢响,快响,常响效果;
5. led灯条显示距离远近。
二、系统总体结构框图
系统以
50MHz 系统时钟为基准。
sig_gen 模块产生
trig 信号,启动超声波模块;
回波信号 echo 进入 ultrasound 顶层模块;
内部通过计数器测量 echo 高电平宽度,得到 distance;
随后经过 bin2bcd 转换为 BCD 码;
最后由四个 hex4_7 模块驱动数码管显示。
三、Trig 信号生成(sig_gen)
由于系统时钟为 50MHz,一个周期
20ns。
在 sig_gen 模块中,我们通过参数设置:
PWM_N = 1000,对应
1000 × 20ns = 20µs,
满足 HC‑SR04 至少 10µs 的触发脉宽要求。
同时,设置 CLK_N =
5,000,000,使得
trig 的发送周期为 100ms,
符合模块的最小测量间隔要求。
parameter[11:0] PWM_N=1000; //high 20us parameter[23:0] CLK_N=5_000_000; //test time 100ms reg [23:0] count; always @(posedge clk,negedge rst) begin if(~rst) count<=0; else if(count==CLK_N) count<=0; else count<=count+1; end assign trig=((count>=100)&&(count<100+PWM_N))?1:0;
四、Echo 回波测量原理
在
echo 回波测量部分,我们采用了两级寄存器同步,避免亚稳态问题。
在 echo 高电平期间,计数器不断累加;
当检测到 echo 下降沿时,将计数值锁存到
distance;
在空闲状态下,计数器清零,准备下一次测量。
这种状态机方式能够较准确地反映回波持续时间。
五、距离计算公式推导
有了计数值之后,就可以计算距离。
根据声速公式,距离等于回波时间乘以声速再除以 2。
考虑到我们的时钟周期是 20ns,经过化简可以得到:
距离(cm)= 17 × distance
÷ 5000
这个公式完全避免了浮点运算,非常适合 FPGA 实现。
begin echo_reg1<=echo; echo_reg2<=echo_reg1; case({echo_reg2,echo_reg1}) 2'b01:count=count+1; 2'b11:count=count+1; 2'b10:distance=count; 2'b00:count=0; endcase end
assign data_bin=17*distance/5000;//=distance/294
六、BIN → BCD 转换
为了方便显示,我们将二进制距离转换为 BCD 码。
这里调用了一个通用的
bin2bcd 模块,
输入为 16 位二进制数,输出为 4 位 BCD 数据,
分别对应个位、十位、百位和千位。
always @(bin) begin for(i=0;i<=W+(W-4)/3;i=i+1) bcd[i]=0; bcd[W-1:0]=bin; for(i=0;i<=W-4;i=i+1) for(j=0;j<=i/3;j=j+1) if(bcd[W-i+4*j-:4]>4) bcd[W-i+4*j-:4]=bcd[W-i+4*j-:4]+4'd3; end
七、数码管显示(hex4_7)
BCD 数据通过 hex4_7 模块驱动数码管。
每个模块负责一位数字,
内部通过查表方式将 4 位 BCD 转换为 7 段显示码,
采用共阴极接法,显示效果稳定清晰。
led灯条
always @* begin if (dist_mm > 1500) LEDR = 10'b0000000000; else if (dist_mm > 1200) LEDR = 10'b0000000001; else if (dist_mm > 900) LEDR = 10'b0000000011; else if (dist_mm > 600) LEDR = 10'b0000000111; else if (dist_mm > 400) LEDR = 10'b0000001111; else if (dist_mm > 250) LEDR = 10'b0000011111; else if (dist_mm > 150) LEDR = 10'b0000111111; else LEDR = 10'b1111111111; end
蜂鸣器控制
always @(posedge clk, negedge rst) begin if (!rst) beep_mode <= 2'b00;//不响 else if (dist_mm > 1500) beep_mode <= 2'b00;//不响 else if (dist_mm > 800) beep_mode <= 2'b01;//慢响 else if (dist_mm > 300) beep_mode <= 2'b10;//快响 else beep_mode <= 2'b11;//一直响 end
always @(posedge clk, negedge rst) begin if (!rst) begin cnt <= 0;//PWM 从 0 开始 top <= 16'd50000;//默认慢响 beep_n <= 1'b1;//蜂鸣器关闭 end else begin case(beep_mode) 2'b00: begin cnt <= 0; beep_n <= 1'b1;//关闭蜂鸣器 end 2'b01: top <= 16'd50000;//慢响 2'b10: top <= 16'd20000;//快响 2'b11: begin cnt <= 0; beep_n <= 1'b0;//紧急 end endcase //PWM 生成逻辑 if (beep_mode != 2'b00 && beep_mode != 2'b11) begin cnt <= (cnt==top)?0:cnt+1; beep_n <= (cnt < top/2) ? 1'b0 : 1'b1;//PWM 占空比 50% end end end
八、关键模块接口汇总
|
模块 |
输入 |
输出 |
|
sig_gen |
clk, rst |
trig |
|
ultrasound |
echo |
distance |
|
bin2bcd |
data_bin |
BCD |
|
hex4_7 |
BCD |
7 段 |
九、设计特点总结
✅ 纯 Verilog RTL 设计
✅ 无 CPU、全硬件并行
✅ 参数化设计,易移植
✅ 符合 HC‑SR04 时序规范
浙公网安备 33010602011771号