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


    废话不多说。

    超声波测距模块有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
  • 相关阅读:
    Python 面向对象
    Python __str__()
    数据降维
    高并发相关概念
    centos7下安装kubernetes1.18
    OB-运行日志
    OB-租户(Tenant)管理
    OB-资源管理(Resource Unit/Pool)
    [转载]-基于 VMWARE Oracle Linux7.9 安装 Oracle19c RAC 详细配置方案
    OB-管理oceanbase集群参数
  • 原文地址:https://www.cnblogs.com/nwpuxuezha/p/4254822.html
Copyright © 2020-2023  润新知