数字电路期末课程设计总结(二) ——超声波测距模块

废话不多说。

超声波测距模块有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

 

posted @ 2015-01-28 03:11  法师漂流  阅读(1505)  评论(0编辑  收藏  举报