xzy610030

一起探讨,一起进步,一起分享!

【红色飓风Nano二代测评】超声波检测

0
阅读(2765)

针对上次小车项目的方案,首先进行的超声波的检测。

1.原理:DYP-ME007超声波测距模块可提供3cm--3.5m的非接触式距离感测功能,图为DYP-ME007外观,包括超声波发射器、接收器与控制电路。其基本工作原理为给予此超声波测距模块一触发信号后发射超声波,当超声波投射到物体而反射回来时,模块输出一回响信号,以触发信号和回响信号间的时间差,来判定物体的距离。

clip_image002

2.模块接线: +5V 接VCC

触发信号输入(10us的TTL脉冲) Trig

回响信号输出(输出TTL电平信号,与射程成比例)

OUT不接

GND接地

注意:不要带电连接。

3. 模块时序图

clip_image004

需要提供一个短期的10us脉冲触发信号。该模块内部将发出8个40Khz周期电平并检测回波。一旦检测到有回波信号则输出回响信号,它是一个脉冲的宽度成正比的距离对象,为了保证发射信号对回响信号的影响,触发信号的周期最好去60ms,太小了有影响,太大了测的不准。

计算公式:回响电平的宽度为某us,计算为us/58=cm,即将测得的回响电平的宽度(us单位),除以58,就得到了障碍物的距离。这个公式很好理解,其实就是我们在初中物理的一个回声的公式s=ct/2,我计算过了,和上面的公式是基本一致的。

4.FPGA设计

小插曲:由于对xilinx的软件不熟悉,添加ip核都捣鼓了几分钟,这个做个记录。Xilinx的IP核的添加方法不能像Altera那样,需要new source 选择IP核类型就可以选择添加IP核了,如果直接Core Generator的话全是灰色的。这里需要除法的IP核,dividend为被除数,divisor为除数,quotient为商,fractional为余数。生成以后,选择ip核,

clip_image006

clip_image008

4.1Verilog代码,由于之前在Altera做过类似的,因此,一个晚上基本上实现了测距。代码如下:

综合一下,没有错误的就进行行为仿真。(利用自带的工具ISim)。具体步骤如下:

4.2Project-》new source

clip_image010

Next,选择顶层文件

clip_image012

Next,finish即可。

这样就会生成一个模板,我们在这个模板上添加仿真代码即可。

Verilog测试如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    18:52:06 04/02/2014 
// Design Name: 
// Module Name:    ultrasonic 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module ultrasonic(
    input clk,
    input rst_n,
    input echo,
    output trig,
    output led
//	 output [23 : 0] distance
    );

//产生周期60ms,10us脉冲的触发信号trig,clk为50M
reg [21:0]cnt;
always @(posedge clk)
begin
	if(!rst_n)
		cnt<=0;
	else	if(cnt==22'd2999999)
				cnt<=0;
			else
				cnt<=cnt+1'b1;
end
assign trig=((cnt>=22'd100) & (cnt<=22'd599)) ? 1:0;

//测量echo的长度
reg echo_reg1,echo_reg2;
wire start,finish;
always @(posedge clk)
begin
	if(!rst_n)
		begin
			echo_reg1<=0;
			echo_reg2<=0;
		end
	else
		begin
			echo_reg1<=echo;
			echo_reg2<=echo_reg1;
		end
end
//这里还不完善,外一有扰动就悲剧了
assign start=echo_reg1 & (~echo_reg2);   //捕捉上升沿
assign finish=(~echo_reg1) & echo_reg2;   //捕捉下降沿
//测量从start到finish这段时间
reg [23:0]distance_cnt;
reg [23:0]distance_temp;
parameter idle=2'b00;
parameter state1=2'b01;
parameter state2=2'b10;
reg [1:0]state;
always @(posedge clk)
begin
	if(!rst_n)
		begin	
			state<=idle;
			distance_cnt<=0;
			distance_temp<=0;
		end
	else	
		begin
			case(state)
			idle: 	begin
							if(start)
								state<=state1;
							else
								state<=idle;
						end
			state1:	begin
							if(finish)
								state<=state2;
							else
								begin
									distance_cnt<=distance_cnt+1'b1;
									state<=state1;
								end
						end
			state2:  begin
							distance_cnt<=0;
							distance_temp<=distance_cnt;
							state<=idle;
						end
			default: state<=idle;
			endcase
		end
end
wire [23 : 0] distance;
//根据公式 us: 20*distance_temp/1000,分母为58,总的来说就是 s=distance_temp/2900,调用ip核
wire [11:0] divisor;  //除数
assign divisor=12'd2900;
wire [11 : 0] fractional; //省去
wire rfd;
//除法器例化
div div (
	.clk(clk), // input clk
	.rfd(rfd), // output rfd ready for data和ip核设置有关,这里没什么关系
	.dividend(distance_temp), // input [23 : 0] dividend
	.divisor(divisor), // input [11 : 0] divisor
	.quotient(distance), // output [23 : 0] quotient
	.fractional(fractional)); // output [11 : 0] fractional
	
//led指示状态,30-40cm认为是有障碍物
reg led_state;
always @(posedge clk)
begin
	if(!rst_n)
		led_state<=0;
	else	if((distance>=24'd30)&(distance<=24'd40))
				led_state<=1;
			else
				led_state<=0;
end
assign led=led_state;
endmodule


切换到Simulation ,执行Simulate Behavioral Model

clip_image013

缩小,以便观察:

clip_image015

验证:echo的长度为500 000ns =500us利用公式500/58=8.62cm,由于我在verilog中把余数也省了,就是仿真中的8了。由于这个要比较大的时间,这里只测试了一次,在用chipscope来看看实际的情况。

4.3 chipscope在线调试

编写UCF文件

NET rst_n   LOC =P7;
NET clk     LOC =M9; 
NET echo  	LOC =C16 | IOSTANDARD=LVCMOS33;#RM3_IO1

NET trig  LOC =C15 | IOSTANDARD=LVCMOS33;  #RM3_IO0
NET led   LOC =M12 | IOSTANDARD=LVCMOS33;


上面为了仿真,把distance作为输出,这里就不作为输出了,不然要添加很多约束的管教,直接wire型,添加chipscope(过程就不叙述了,之前一直用的是signaltap,正好借这个机会熟悉一下chipscope怎么使用,大体来说是有些类似的),

然后就是痛苦的产生bit流文件的时刻了,电脑太差,太慢太慢了。。。

该结束的终归是要结束的,在某个时间终于完成了,然后双击Analyze Design Using ChipScope,下载bit流文件,中间省略一些步骤了,我都是参考书上的,这样就可以用chipscope来看看是否正确了。

无遮挡时:

clip_image017

当我把一本书挡住的时候,约30多cm的时候

clip_image019

clip_image021

可以发现那个有个led是亮的,这个是指示用的,当我一下靠近一下远离的时候,这个灯闪的厉害,距离比较合适吧,我设置的是30-40的时候,这个led就会亮,通过仿真和chipscope可以看出,超声波测距的基本任务是完成了的,继续下一步小车项目的工作。

Ps:虽然玩过一段时间的zynq,但对于xilinx的FPGA的开发还是太不熟悉,这次试用,给了自己一些学习的动力和压力,使用Isim仿真,添加IP核,使用Chipscope,这些都是这次试用带来的收获吧。不过感觉xilinx的软件编译起来真要费好长的时间,altera的似乎是没有这么长时间的。