数字电路期末课程设计总结(二) ——超声波测距模块
废话不多说。
超声波测距模块有5个引脚,这里我们只用4个。
超声波测距模块引脚如上所示,Trig为触发信号输入,Echo为回响信号输出,这两个引脚为实现测距功能的核心功能引脚。
时序图如下:
超声波模块的工作原理为:采用触发测距,每次触发给至少10μS高电平信号,收到高电平信号后,模块自动发送8个40kHz方波的超声波信号,并自动检测是否有信号返回;若有信号范围,通过Echo输出一个高电平,高电平持续时间就是超声波从发射到返回所用的时间。
由超声波模块工作时序图可以看出,每次测量时,给Trig控制端发送10μS的TTL高电平信号,则模块自动工作产生回响电平,回响电平脉冲宽度与检测距离成比例,由此通过回响脉宽可以计算并得到距离。
公式:距离=高电平时间*声速/2;
该模块每次按键即通过模块Trig输出10μSTTL高电平信号给超声波测距模块,同时启动Echo模块的检测功能,将超声波测距模块传回的Echo信号计数输出为data;在PreDecode模块中将data经计算后,分位输出为形如x.xxx m的距离数据distance。
为了做测试,我在写这个模块时加入了数码管显示部分。
这是顶层文件:
1 module test(clock,reset,button,echo,trig,dot,seg); 2 3 input clock; 4 input reset; 5 input button; 6 input echo; 7 8 output trig; 9 output[3:0] dot; 10 output[27:0] seg; 11 12 /***********************************************************/ 13 14 wire x_trig; 15 16 Trig U1(button,clock,reset,x_trig); 17 18 assign trig = x_trig; 19 /***********************************************************/ 20 21 wire SegDecodeEnable; 22 wire[31:0] data; 23 24 Echo U2(button,echo,clock,reset,SegDecodeEnable,data); 25 /***********************************************************/ 26 27 wire[15:0] distance; 28 29 PreDecode U3(SegDecodeEnable,data,distance,reset); 30 /***********************************************************/ 31 32 wire[27:0] segout; 33 wire[3:0] x_dotout; 34 35 SegDecode U4(distance,reset,segout,x_dotout); 36 37 assign seg = segout; 38 assign dot = x_dotout; 39 /***********************************************************/ 40 41 endmodule 42
这是Trig端口控制模块。里面我用了状态机描述系统的状态。
1 module Trig(button,clock,reset,q); 2 3 input button,clock,reset; 4 output q; 5 6 reg rq; 7 reg[9:0] i; 8 reg[1:0] state; 9 10 11 // `define ButtonLow 2'd1 12 // `define SignalOn 2'd2 13 // `define SignalOff 2'd3 14 15 16 always@(posedge clock or negedge reset) 17 if(!reset) 18 begin 19 i <= 10'd0; 20 rq <= 1'b0; 21 state <= 2'd3; 22 end 23 else 24 begin 25 case(state) 26 2'd1:// ButtonLow: 27 begin 28 i<=10'd0; 29 if(button==1)state <= 2'd2 ; 30 else rq <= 1'b0; 31 end 32 2'd2:// SignalOn : 33 begin 34 rq<=1'b1; 35 if(i==500)state <= 2'd3 ; //10us计时 36 else i<=i+1'b1; 37 end 38 2'd3:// SignalOff : 39 begin 40 rq <= 1'b0; 41 i<=10'd0; 42 if(button==0)state <= 2'd1 ; 43 end 44 45 endcase 46 end 47 48 assign q = rq; 49 50 endmodule 51
这是Echo端口控制模块。里面同样是状态机。
1 module Echo(button,SignalIn,clock,reset,q,data); 2 3 input button,clock,reset,SignalIn; 4 output q; 5 output[31:0]data; 6 7 reg[31:0] i; 8 reg[9:0] j; // 10us计时变量 9 reg[2:0] state; 10 reg rq; 11 12 parameter stop = 3'd1; // 测距停止 13 parameter buttonlow = 3'd2; // 按键按下 14 parameter Wait = 3'd3; // 等待回响信号由低变高 15 parameter count = 3'd4; // 回响信号计数 16 parameter dataout = 3'd5; // 数据输出 17 18 19 always@(posedge clock or negedge reset) 20 if(!reset) 21 begin 22 i <= 32'd0; 23 rq <= 1'b0; 24 state <= stop; 25 j <= 10'd0; 26 end 27 else 28 begin 29 case(state) 30 stop: 31 begin 32 i<=32'd0; 33 if(button==0)state <= buttonlow ; 34 j <= 10'd0; 35 rq <= 1'b0; 36 end 37 buttonlow : 38 begin 39 i <= 32'd0; 40 if(button==1)state <= Wait ; 41 j <= 10'd0; 42 rq <= 1'b0; 43 end 44 Wait : 45 begin 46 if(SignalIn==1)state <= count ; 47 i <= 32'd0; 48 j <= 10'd0; 49 rq <= 1'b0; 50 end 51 count : 52 begin 53 if(SignalIn==0)state <= dataout; 54 i <= i+1'b1; 55 j <= 10'd0; 56 rq <= 1'b0; 57 end 58 dataout: 59 begin 60 if(j==499)state <= stop; 61 i <= i; 62 j <= j+1'b1; 63 rq <= 1'b1; 64 end 65 66 endcase 67 end 68 69 assign q = rq; 70 assign data = i; 71 endmodule 72
这是数据处理的前级,负责输出x.xxx m中的四个四位二进制数。这部分代码资源占用较多,可以继续优化的。
1 module PreDecode(enable,SignalIn,distance,reset); 2 3 input enable; 4 input reset; 5 input [31:0] SignalIn; 6 7 output[15:0] distance; 8 9 reg RegDot; 10 reg[15:0] RegDistance; 11 12 13 always@(posedge enable or negedge reset) 14 if(!reset) 15 begin 16 RegDistance <=16'd0; 17 end 18 else // 距离计算 19 begin 20 RegDistance[3:0] = (SignalIn *17/5000)%10; 21 RegDistance[7:4] = (SignalIn *17/50000)%10; 22 RegDistance[11:8] = (SignalIn *17/500000)%10; 23 RegDistance[15:12] = (SignalIn *17/5000000)%10; 24 end 25 26 assign distance = RegDistance; 27 28 endmodule 29 30
这是数据处理后级,负责把二进制数转换为共阳极数码管的显示码。
1 module SegDecode(SignalIn,reset,SignalOut,dotout); 2 3 input wire [15:0] SignalIn; 4 input wire reset; 5 output wire [27:0]SignalOut; 6 output wire [3:0]dotout; 7 8 decode U1(SignalIn[3:0],SignalOut[6:0]); 9 decode U2(SignalIn[7:4],SignalOut[13:7]); 10 decode U3(SignalIn[11:8],SignalOut[20:14]); 11 decode U4(SignalIn[15:12],SignalOut[27:21]); 12 13 assign dotout = 4'b0111; 14 endmodule 15 16 17 18 module decode(cin,cout); 19 20 input[3:0] cin; 21 output[6:0] cout; 22 23 reg[6:0] RegCout; 24 25 always@(cin) //写法有瑕疵 26 case(cin) 27 4'd0:RegCout=7'b0000001; 28 4'd1:RegCout=7'b1001111; 29 4'd2:RegCout=7'b0010010; 30 4'd3:RegCout=7'b0000110; 31 4'd4:RegCout=7'b1001100; 32 4'd5:RegCout=7'b0100100; 33 4'd6:RegCout=7'b0100000; 34 4'd7:RegCout=7'b0001111; 35 4'd8:RegCout=7'b0000000; 36 4'd9:RegCout=7'b0001100; 37 default:RegCout=7'b0000001; 38 endcase 39 assign cout = RegCout; 40 endmodule
testbench:
1 // Copyright (C) 1991-2013 Altera Corporation 2 // Your use of Altera Corporation's design tools, logic functions 3 // and other software and tools, and its AMPP partner logic 4 // functions, and any output files from any of the foregoing 5 // (including device programming or simulation files), and any 6 // associated documentation or information are expressly subject 7 // to the terms and conditions of the Altera Program License 8 // Subscription Agreement, Altera MegaCore Function License 9 // Agreement, or other applicable license agreement, including, 10 // without limitation, that your use is for the sole purpose of 11 // programming logic devices manufactured by Altera and sold by 12 // Altera or its authorized distributors. Please refer to the 13 // applicable agreement for further details. 14 15 // ***************************************************************************** 16 // This file contains a Verilog test bench template that is freely editable to 17 // suit user's needs .Comments are provided in each section to help the user 18 // fill out necessary details. 19 // ***************************************************************************** 20 // Generated on "01/10/2015 00:48:08" 21 22 // Verilog Test Bench template for design : test 23 // 24 // Simulation tool : ModelSim (Verilog) 25 // 26 27 `timescale 10 ns/ 1 ps 28 module test_vlg_tst(); 29 // constants 30 // general purpose registers 31 reg[31:0] i; 32 // test vector input registers 33 reg button; 34 reg clock; 35 reg echo; 36 reg reset; 37 // wires 38 wire SegDecodeEnable; 39 wire [31:0]data; 40 wire [15:0]distance; 41 wire dot; 42 wire [27:0] seg; 43 wire trig; 44 wire x_dot; 45 46 // assign statements (if any) 47 test i1 ( 48 // port map - connection between master ports and signals/registers 49 .SegDecodeEnable(SegDecodeEnable), 50 .button(button), 51 .clock(clock), 52 .data(data), 53 .distance(distance), 54 .dot(dot), 55 .echo(echo), 56 .reset(reset), 57 .seg(seg), 58 .trig(trig), 59 .x_dot(x_dot) 60 ); 61 62 initial 63 begin 64 65 reset=0;#10 reset=1; 66 clock=1;forever #1 clock=~clock; 67 68 end 69 70 always@(posedge clock or negedge reset) 71 if(!reset) 72 begin 73 i<=32'd0; 74 button<=1; 75 echo<=0; 76 end 77 else 78 begin 79 i<=i+1'b1; 80 //test1 81 if(i==1000)button<=0; 82 if(i==5000000)button<=1; 83 if(i==10001000)button<=0; 84 if(i==15001000)button<=1; 85 86 if(i==5500000)echo<=1; 87 if(i==6005000)echo<=0; 88 if(i==15000000)echo<=1; 89 if(i==16005000)echo<=0; 90 91 end 92 93 endmodule