【FPGA】超声波测距
超声波测距设计思路
超声波测距整体思路:
通过超声波模块发送超声波来检测与前方障碍物的距离并将计算结果传回FPGA,并操作数据通过数码管或显示屏等模块进行显示。
一、模块简介
超声波模块:
超声波模块引脚:
- VCC: 工作电压5V
- GND: 接地
- TRIG(控制端): 控制口发一个 10US 以上的高电平
- ECHO(接收端): 当超声波模块完成发送8个周期的高电平,读取ECHO端的高电平持续时间并计算出与前方的检测距离。
超声波时序图:
模块工作原理:
- 采用 IO 触发测距,给至少 10us 的高电平信号;
- 模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
- 有信号返回,通过 IO 输出一高电平,高电平持续的时间就是
- 超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2;
二、超声波测距实现步骤
1.编写TRIG模块
原理:
由上述超声波模块的原理可知,模块需要对超声波发送一个高电平为10us以上时间的高电平。
代码如下:
`timescale 1ns / 1ps
module Trig(
input sysclk ,
input rst_n ,
output trig
);
parameter DELAY = ( 70 * 50_000 ) + 15 * 50;//发送时钟周期(70ms+15us)
reg [20:0] cnt;
//---------------count----------------//
always@(posedge sysclk)
if(!rst_n)
cnt <= 0;
else if(cnt == DELAY - 1)
cnt <= 0;
else
cnt <= cnt + 1;
//---------------initial trig--------------//
assign trig = (( cnt > 0) && (cnt < 15 * 50 )) ? 1 : 0;
endmodule
2.编写ECHO模块
原理:
当检测到高电平时,计数器开始计时,当再次检测到低电平时计数器清零同时将计数结果赋值到二级寄存器当中并通过公式计算出距离。(高电平时间 * 20) / 58 /1000 (厘米)
状态图:
代码如下(示例):
`timescale 1ns / 1ps
module ECHO(
input sysclk ,
input rst_n ,
input echo ,
output [13:0] dis //distance
);
//————————state——————//
parameter IDLE = 3'b001,
s1 = 3'b010,
s2 = 3'b100;
reg [2:0] cur_state;
reg [2:0] next_state;
reg [31:0] cnt;
reg [31:0] cnt_reg;
//————————first————————//
always@(posedge sysclk)
if(!rst_n)
cur_state <= IDLE;
else
cur_state <= next_state;
//————————second————————//
always@(*)
case(cur_state)
IDLE :begin//空闲状态
if(echo == 1)
next_state = s1;
else
next_state = IDLE;
end
s1 :begin//
if(echo == 0)
next_state = s2;
else
next_state = s1;
end
s2 :begin
next_state = IDLE;
end
default:next_state = IDLE;
endcase
//——————————third——————————//
always@(posedge sysclk)
if(!rst_n)
begin
cnt <= 0;
cnt_reg <= 0;
end
else
case(cur_state)
IDLE :begin
cnt <= 0;
cnt_reg <= cnt_reg;
end
s1 :begin
cnt <= cnt + 1;
cnt_reg <= cnt_reg;
end
s2 :begin
cnt_reg <= cnt;
cnt <= 0;
end
default:begin
cnt <= 0;
cnt_reg <= 0;
end
endcase
//————————distance——————————//
assign dis = (cnt_reg * 20)/58/1000;
endmodule
3.编写顶层模块
原理:
将TRIG模块与ECHO模块例化并可以将距离显示在数码管或显示屏上。
代码实现:
`timescale 1ns / 1ps
module TOP(
input sysclk ,
input rst_n ,
input echo ,
output trig ,
output [13:0] dis
);
Trig trg(
.sysclk (sysclk ) ,
.rst_n (rst_n ) ,
.trig (trig )
);
ECHO echo_u(
.sysclk (sysclk ) ,
.rst_n (rst_n ) ,
.echo (echo ) ,
.dis (dis )
);
endmodule
三、总结及拓展
可以自行编写数码管驱动程序并封装成IP直接调用,并将距离实时显示在数码管上实现超声波测距或连接蜂鸣器等固定距离报警装置。