【 FPGA 】超声波测距小实验(一)

版权声明:本博客内容来自于个人学习过程中的总结,参考了互联网、数据手册、帮助文档、书本以及论文等上的内容,仅供学习交流使用,如有侵权,请联系,我会重写!转载请注明地址! https://blog.csdn.net/Reborn_Lee/article/details/86546143

超声波测距原理:

超声波测距原理是在超声波发射装置发出超声波,它的根据是接收器接到超声波时的时间差,与雷达测距原理相似。 超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。

(超声波在空气中的传播速度为340m/s,根据计时器记录的时间t(秒),就可以计算出发射点距障碍物的距离(s),即:s=340t/2)

è¿éåå¾çæè¿°

计算公式可近似为:s=340t/2(精确的情况稍微不同)

实验所用超声波测距实物为:

è¶å£°æ³¢æµè·æ¨¡å

超声波测距时序图:

触发信号是一个持续10us的高电平脉冲,检测到触发信号后,超声波测距模块将发出8个40KHz的脉冲并检测回波信号,一旦检测到回波信号则此模块输出回响信号,回响信号的脉冲长度与测试距离成正比。

计算公式近似为:s=340t/2

下面是FPGA实现的功能框图:

如上图,回波信号echo作为输入信号输入到FPGA的Chipscope进行采集,来查看echo信号的长度,由此来得出测量距离。

引用特权的程序吧,虽然有的部分不太喜欢,但总体还是能提供一个思路:

/////////////////////////////////////////////////////////////////////////////
//工程硬件平台: Xilinx Spartan 6 FPGA
//每10us产生一个持续时间为40ns的高脉冲
/////////////////////////////////////////////////////////////////////////////
module clkdiv_generation(
				input clk,		//外部输入25MHz时钟信号
				input rst_n,	//外部输入复位信号,低电平有效
				output clk_100khz_en	//100KHz频率的一个时钟使能信号,即每10us产生一个时钟脉冲
			);															
						
//-------------------------------------------------
//时钟分频产生
reg[7:0] cnt;	//时钟分频计数器,0-249

	//1s定时计数
always @(posedge clk or negedge rst_n)
	if(!rst_n) cnt <= 8'd0;
	else if(cnt < 8'd249) cnt <= cnt+1'b1;
	else cnt <= 8'd0;

assign clk_100khz_en = (cnt == 8'd249) ? 1'b1:1'b0;		//每10us产生一个40ns的高脉冲				

endmodule
/////////////////////////////////////////////////////////////////////////////
//工程硬件平台: Xilinx Spartan 6 FPGA
/////////////////////////////////////////////////////////////////////////////
module ultrasound_controller(
				input clk,		//外部输入25MHz时钟信号
				input rst_n,	//外部输入复位信号,低电平有效
				input clk_100khz_en,	//100KHz频率的一个时钟使能信号,即每10us产生一个时钟脉冲
				output ultrasound_trig,	//超声波测距模块脉冲激励信号,10us的高脉冲
				input ultrasound_echo		//超声波测距模块回响信号
			);															
						
//-------------------------------------------------
//1s定时产生逻辑
reg[16:0] timer_cnt;	//1s计数器,以100KHz(10us)为单位进行计数,计数1s需要的计数范围是0~99999

	//1s定时计数
always @(posedge clk or negedge rst_n)
	if(!rst_n) timer_cnt <= 17'd0;
	else if(clk_100khz_en) begin
		if(timer_cnt < 17'd99_999) timer_cnt <= timer_cnt+1'b1;
		else timer_cnt <= 17'd0;
	end
	else ;

assign ultrasound_trig = (timer_cnt == 17'd1) ? 1'b1:1'b0;		//10us高脉冲生成						

endmodule

下面是主模块,调用上面的两个模块:

/////////////////////////////////////////////////////////////////////////////
//工程硬件平台: Xilinx Spartan 6 FPGA
/////////////////////////////////////////////////////////////////////////////
//每秒产生1个超声波测距模块所需的10us高脉冲激励,并用chipscope pro查看回响信号
module sp6(
			input ext_clk_25m,	//外部输入25MHz时钟信号
			input ext_rst_n,	//外部输入复位信号,低电平有效
			output ultrasound_trig,	//超声波测距模块脉冲激励信号,10us的高脉冲
			input ultrasound_echo,		//超声波测距模块回响信号
			output[0:0] led		//D2指示灯
		);													

//-------------------------------------
//PLL例化
wire clk_12m5;	//PLL输出12.5MHz时钟
wire clk_25m;	//PLL输出25MHz时钟
wire clk_50m;	//PLL输出50MHz时钟
wire clk_100m;	//PLL输出100MHz时钟
wire sys_rst_n;	//PLL输出的locked信号,作为FPGA内部的复位信号,低电平复位,高电平正常工作

  pll_controller uut_pll_controller
   (// Clock in ports
    .CLK_IN1(ext_clk_25m),      // IN
    // Clock out ports
    .CLK_OUT1(clk_12m5),     // OUT
    .CLK_OUT2(clk_25m),     // OUT
    .CLK_OUT3(clk_50m),     // OUT
    .CLK_OUT4(clk_100m),     // OUT
    // Status and control signals
    .RESET(~ext_rst_n),// IN
    .LOCKED(sys_rst_n));      // OUT		
		
//-------------------------------------
//25MHz时钟进行分频,产生一个100KHz频率的时钟使能信号
wire clk_100khz_en;	//100KHz频率的一个时钟使能信号,即每10us产生一个时钟脉冲

clkdiv_generation	uut_clkdiv_generation(
				.clk(clk_25m),		//时钟信号
				.rst_n(sys_rst_n),	//复位信号,低电平有效
				.clk_100khz_en(clk_100khz_en)	//100KHz频率的一个时钟使能信号,即每10us产生一个时钟脉冲
			);			
		
//-------------------------------------
//每秒产生一个10us的高脉冲作为超声波测距模块的激励

ultrasound_controller	uut_ultrasound_controller(
				.clk(clk_25m),		//时钟信号
				.rst_n(sys_rst_n),	//复位信号,低电平有效
				.clk_100khz_en(clk_100khz_en),	//100KHz频率的一个时钟使能信号,即每10us产生一个时钟脉冲
				.ultrasound_trig(ultrasound_trig),	//超声波测距模块脉冲激励信号,10us的高脉冲
				.ultrasound_echo(ultrasound_echo)		//超声波测距模块回响信号
			);	

//-------------------------------------
//input信号必须经过IBUF后,才能作为chipscope中查看			
wire ultrasound_echo_r;
			
   IBUF #(
     .IOSTANDARD("DEFAULT")    // Specify the input I/O standard
   )IBUF_inst (
      .O(ultrasound_echo_r),     // Buffer output
      .I(ultrasound_echo)      // Buffer input (connect directly to top-level port)
   );
		
assign led[0] = ultrasound_echo_r;

		
endmodule

可以用Chipscope来查看回响信号的长度,这里省略,下篇博文,添加一个数码管动态扫描显示模块,将回响信号在数码管上显示出来。

超声波测距小实验(二):数码管显示回响信号脉冲宽度

猜你喜欢

转载自blog.csdn.net/Reborn_Lee/article/details/86546143
今日推荐