基于DE2 115开发板FPGA超声波测距

实验仪器

硬件:DE2 115FPGA开发板、HC-SR04超声波测距模块
软件:Quartus 、Modelsim

实验目的

使用DE2开发板驱动HC_SR04测距模块,并将所测得数据显示到开发板上的数码管。

实验原理

1、超声波原理:

(1) 主控设备给 Trig 脚提供一个 10us 的脉冲信号。
(2) HC-SR04 接收到信号,开始发送超声波,并把 Echo置为高电平,然后准备接收返回的超声波。
(3) HC-SR04 接收到返回的超声波,把 Echo 置为低电平。
(4) Echo 高电平持续的时间就是超声波从发射到返回的时间间隔。
如果超声波模块前方没有障碍物,约4米之内,那当Trig引脚被提供10μs以上脉冲触发信号后,该模块内部发射(transmit)8个40kHz的超声波脉冲并检测回波,Echo引脚收到一个高电平并持续38毫秒,之后就会处于低电平状态,所以当得到38ms这个值时,我们就知道前方没有检测到障碍物了。
如果前方有障碍物,那在发射超声波脉冲后,信号就会反射回来,Echo引脚就会在接收到信号时立即切换到低电平状态,此时Echo引脚在高电平状态保持的时间就是信号发射并返回的所花的时间。
我们知道距离=速度 * 时间,要求出超声波模块到障碍物之间的距离,我们就需要知道速度和时间。速度就是340m/s,也就是声音在空气中传播的速度,转换城cm/μs单位就是0.034 cm/μs。时间的话,由于我们得到的是信号从发射到返回的时间值,所以需要除以2。最终得到的计算公式为:距离 = 0.034 cm/μs * 时间(μs) / 2

2、静态显示原理

根据硬件原理图所示,发光二极管,所有的阳极都接通3.3V的正电压,也即—高电平,所以如果我们想要
发光二极管导通的话,需要在阴极接通低电平,就可以让LED亮起来。

实验设计

1、时钟设计部分

module 	clk_div(
	input  wire			Clk		, //system clock 50MHz
	input  wire 		Rst_n	, //reset ,low valid
		   
	output wire  		clk_us 	  //
);
//Parameter Declarations
	parameter CNT_MAX = 19'd50;//1us的计数值为 50 * Tclk(20ns)

//Interrnal wire/reg declarations
	reg		[5:00]	cnt		; //Counter 
	wire			add_cnt ; //Counter Enable
	wire			end_cnt ; //Counter Reset 
	
//Logic Description
	
	always @(posedge Clk or negedge Rst_n)begin  
		if(!Rst_n)begin  
			cnt <= 'd0; 
		end  
		else if(add_cnt)begin  
			if(end_cnt)begin  
				cnt <= 'd0; 
			end  
			else begin  
				cnt <= cnt + 1'b1; 
			end  
		end  
		else begin  
			cnt <= cnt;  
		end  
	end 
	
	assign add_cnt = 1'b1; 
	assign end_cnt = add_cnt && cnt >= CNT_MAX - 19'd1;
	
	assign clk_us = end_cnt;
	

endmodule 

2、超声波测距模块设计部分

触发模块
module 	hc_sr_trig(
	input  wire
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
// // Permission: // // Terasic grants permission to use and modify this code for use // in synthesis for all Terasic Development Boards and Altera Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited. // // Disclaimer: // // This VHDL/Verilog or C/C++ source code is intended as a design reference // which illustrates how these types of functions can be implemented. // It is the user's responsibility to verify their design for // consistency and functionality through the use of formal // verification methods. Terasic provides no warranty regarding the use // or functionality of this code. // // -------------------------------------------------------------------- // // Terasic Technologies Inc // 356 Fu-Shin E. Rd Sec. 1. JhuBei City, // HsinChu County, Taiwan // 302 // // web: http://www.terasic.com/ // email: support@terasic.com // // -------------------------------------------------------------------- // // Major Functions: DE2_115_PS2 Mouse Controller // // -------------------------------------------------------------------- // // Revision History : // -------------------------------------------------------------------- // Ver :| Author :| Mod. Date :| Changes Made: // V1.0 :| Johnny FAN,HdHuang :| 05/16/10 :| Initial Revision // -------------------------------------------------------------------- module ps2( iSTART, //press the button for transmitting instrucions to device; iRST_n, //FSM reset signal; iCLK_50, //clock source; PS2_CLK, //ps2_clock signal inout; PS2_DAT, //ps2_data signal inout; oLEFBUT, //left button press display; oRIGBUT, //right button press display; oMIDBUT, //middle button press display; oX_MOV1, //lower SEG of mouse displacement display for X axis. oX_MOV2, //higher SEG of mouse displacement display for X axis. oY_MOV1, //lower SEG of mouse displacement display for Y axis. oY_MOV2 //higher SEG of mouse displacement display for Y axis. ); //interface; //======================================================= // PORT declarations //======================================================= input iSTART; input iRST_n; input iCLK_50; inout PS2_CLK; inout PS2_DAT; output oLEFBUT; output oRIGBUT; output oMIDBUT; output [6:0] oX_MOV1; output [6:0] oX_MOV2; output [6:0] oY_MOV1; output [6:0] oY_MOV2; //instantiation SEG7_LUT U1(.oSEG(oX_MOV1),.iDIG(x_latch[3:0])); SEG7_LUT U2(.oSEG(oX_MOV2),.iDIG(x_latch[7:4])); SEG7_LUT U3(.oSEG(oY_MOV1),.iDIG(y_latch[3:0])); SEG7_LUT U4(.oSEG(oY_MOV2),.iDIG(y_latch[7:4])); //instruction define, users can charge the instruction byte here for other purpose according to ps/2 mouse datasheet. //the MSB is of parity check bit, that's when there are odd number of 1's with data bits, it's value is '0',otherwise it's '1' instead. parameter enable_byte =9'b011110100; //======================================================= // REG/WIRE declarations //======================================================= reg [1:0] cur_state,nex_state; reg ce,de; reg [3:0] byte_cnt,delay; reg [5:0] ct; reg [7:0] x_latch,y_latch,cnt; reg [8:0] clk_div; reg [9:0] dout_reg; reg [32:0] shift_reg; reg leflatch,riglatch,midlatch; reg ps2_clk_in,ps2_clk_syn1,ps2_dat_in,ps2_dat_syn1; wire clk,ps2_dat_syn0,ps2_clk_syn0,ps2_dat_out,ps2_clk_out,flag; //======================================================= // PARAMETER declarations //======================================================= //state define parameter listen =2'b00, pullclk=2'b01, pulldat=2'b10, trans =2'b11; //======================================================= // Structural coding //======================================================= //clk division, derive a 97.65625KHz clock from the 50MHz source; always@(posedge iCLK_50) begin clk_div <= clk_div+1; end assign clk = clk_div[8]; //tristate output control for PS2_DAT and PS2_CLK; assign PS2_CLK = ce?ps2_clk_out:1'bZ; assign PS2_DAT = de?ps2_dat_out:1'bZ; assign ps2_clk_out = 1'b0; assign ps2_dat_out = dout_reg[0]; assign ps2_clk_syn0 = ce?1'b1:PS2_CLK; assign ps2_dat_syn0 = de?1'b1:PS2_DAT; // assign oLEFBUT = leflatch; assign oRIGBUT = riglatch; assign oMIDBUT = midlatch; //multi-clock region simple synchronization always@(posedge clk) begin ps2_clk_syn1 <= ps2_clk_syn0; ps2_clk_in <= ps2_clk_syn1; ps2_dat_syn1 <= ps2_dat_syn0; ps2_dat_in <= ps2_dat_syn1; end //FSM shift always@(*) begin case(cur_state) listen :begin if ((!iSTART) && (cnt == 8'b11111111)) nex_state = pullclk; else nex_state = listen; ce = 1'b0; de = 1'b0; end pullclk :begin if (delay == 4'b1100) nex_state = pulldat; else nex_state = pullclk; ce = 1'b1; de = 1'b0; end pulldat :begin nex_state = trans; ce = 1'b1; de = 1'b1; end trans :begin if (byte_cnt == 4'b1010) nex_state = listen; else nex_state = trans; ce = 1'b0; de = 1'b1; end default : nex_state = listen; endcase end //idle counter always@(posedge clk) begin if ({ps2_clk_in,ps2_dat_in} == 2'b11) begin cnt <= cnt+1; end else begin cnt <= 8'd0; end end //periodically reset ct; ct counts the received data length; assign flag = (cnt == 8'hff)?1:0; always@(posedge ps2_clk_in,posedge flag) begin if (flag) ct <= 6'b000000; else ct <= ct+1; end //latch data from shift_reg;outputs is of 2's complement; //Please treat the cnt value here with caution, otherwise wrong data will be latched. always@(posedge clk,negedge iRST_n) begin if (!iRST_n) begin leflatch <= 1'b0; riglatch <= 1'b0; midlatch <= 1'b0; x_latch <= 8'd0; y_latch <= 8'd0; end else if (cnt == 8'b00011110 && (ct[5] == 1'b1 || ct[4] == 1'b1)) begin leflatch <= shift_reg[1]; riglatch <= shift_reg[2]; midlatch <= shift_reg[3]; x_latch <= x_latch+shift_reg[19 : 12]; y_latch <= y_latch+shift_reg[30 : 23]; end end //pull ps2_clk low for 100us before transmit starts; always@(posedge clk) begin if (cur_state == pullclk) delay <= delay+1; else delay <= 4'b0000; end //transmit data to ps2 device;eg. 0xF4 always@(negedge ps2_clk_in) begin if (cur_state == trans) dout_reg <= {1'b0,dout_reg[9:1]}; else dout_reg <= {enable_byte,1'b0}; end //transmit byte length counter always@(negedge ps2_clk_in) begin if (cur_state == trans) byte_cnt <= byte_cnt+1; else byte_cnt <= 4'b0000; end //receive data from ps2 device; always@(negedge ps2_clk_in) begin if (cur_state == listen) shift_reg <= {ps2_dat_in,shift_reg[32:1]}; end //FSM movement always@(posedge clk,negedge iRST_n) begin if (!iRST_n) cur_state <= listen; else cur_state <= nex_state; end endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值