基于 ZYNQ ECO开发板 超声波模块

超声波模块

`timescale 1ns / 1ps
module SR_04(
        input               clk     ,
        input               rst_n   ,
        input               echo    ,   //接收端,判断端口返回值
        output     [15:0]   dis     ,   //最终距离
        output              trig        //脉冲发出
    );
    
    parameter   delay = (50*15) + (50*1000*100);    //60ms以上的周期
    parameter   s1 = 0;         //空闲
    parameter   s2 = 1;         //echo开始计时
    parameter   s3 = 2;         //计时结束
    
    reg     [31:0]  cnt_trig;
    reg     [31:0]  cnt_echo;
    reg     [31:0]  cnt_echo_reg;
    reg [2:0]   c_state;
    reg [2:0]   n_state;
    
    
    always @(posedge clk)
        if(!rst_n)
            cnt_trig <= 0;
        else if(cnt_trig == delay -1)
            cnt_trig <= 0;
        else
            cnt_trig <= cnt_trig +1
            ;
    assign  trig = ((cnt_trig >0) && (cnt_trig<(50*15))) ? 1:0;
    
    
    always  @(posedge clk)
        if(!rst_n)
            c_state <= s1;
        else
            c_state <= n_state;
            
     always @(*)
        case(c_state)
            s1: begin
                if(echo == 1)
                    n_state = s2;
                else
                    n_state = s1;
                 end
            s2: begin 
                if(echo == 0)
                    n_state = s3;
                else
                    n_state = s2;
            end
            s3: begin
                n_state = s1;
             end
         endcase
    
    
always @(posedge clk)
    if(!rst_n)begin
        cnt_echo<=0;
        cnt_echo_reg <= 0;
    end
    else    begin
            case(c_state)
                s1: begin
                    cnt_echo<=0;
                    cnt_echo_reg <= cnt_echo_reg;
                    end
                s2: begin
                    cnt_echo<=cnt_echo +1;
                    cnt_echo_reg <= cnt_echo_reg;
                   end
                s3: begin
                    cnt_echo<=cnt_echo;
                    cnt_echo_reg <= cnt_echo;
                    end
            endcase
     end
        
        
assign  dis = (cnt_echo_reg * 20)/1000/58;
 
endmodule

模块的输入包括时钟信号clk、复位信号rst_n、echo信号(接收端返回值);输出包括距离信号dis和脉冲发出信号trig。

该模块定义了一些参数和寄存器用于跟踪计数。delay参数定义了周期的延迟时间,s1、s2和s3分别表示状态机的三个状态。

在时钟信号上升沿触发的always块中,根据复位信号的状态设置计数器cnt_trig的值。当cnt_trig达到delay-1时,将其重置为0。根据cnt_trig的值,将trig输出设置为1或0,以控制脉冲发出。

另一个时钟信号上升沿触发的always块中,根据复位信号和状态机的当前状态设置计数器cnt_echo和cnt_echo_reg的值。根据状态机的状态,cnt_echo的值会进行递增或保持不变。cnt_echo_reg保存上一个状态的计数器值。

最后,通过组合逻辑,将cnt_echo_reg乘以20,除以1000,再除以58,得到距离值dis。

这个超声波模块的功能是通过计数器实现超声波测距。它通过测量超声波从发射到接收的时间,然后将时间转换为距离值。相当于我们可以在其他地方得到超声波距离。

输出dis单位为 cm

LED

`timescale 1ns / 1ps
 
module led_mk(
    input               clk         ,
    input               rst_n       ,
    input   [4:0]       led_zt      ,
    output  reg[3:0]    led
    );
    parameter led1 = 0;
    parameter led2 = 1;
    parameter led3 = 2;
    parameter led4 = 3;
    parameter led5 = 4;
    
    reg [3:0]   c_led;
    reg [3:0]   n_led;
    
    always @(posedge clk)
        if(!rst_n)
            c_led <= led1;
        else
            c_led <= n_led;
        
    always @(*)
        if(!rst_n)
            n_led = 0;
        else begin
            case(led_zt)
                led1: begin
                    n_led = led1;
                    end
                led2:begin
                     n_led = led2;
                    end
                led3:begin
                     n_led = led3;
                    end
                led4:begin
                     n_led = led4;
                    end
                led5:begin
                     n_led = led5;
                    end
                default:
                    n_led =  n_led;
              endcase
        end
                
       always @(posedge clk)
            if(!rst_n)
                led <= 0;
            else begin
                case(c_led)
                led1: begin
                        led <= 4'b0000;
                    end
                led2:begin
                        led <= 4'b0001;
                    end
                led3:begin
                        led <= 4'b0011;
                    end
                led4:begin
                        led <= 4'b0111;
                    end
                led5:begin
                        led <= 4'b1111;
                    end
                default:
                    led <= led;
                 endcase
            end
endmodule

这里通过输入的led_zt来控制ed显示的状态

超声波测距

`timescale 1ns / 1ps
module sr_led(
        input       clk     ,
        input       rst_n   ,
        input               echo    ,   //接收端,判断端口返回值
        output              trig    ,   //脉冲发出
        output  reg [3:0]       led
    );
    wire    [15:0]  dis;
    wire     [3:0]   led_dd;
    reg     [4:0]   led_zt;
    
    always  @(posedge clk)
        if(!rst_n)  begin
            led <= 0;
            end
        else
            led <= led_dd;
            
    parameter csb0 = 0;
    parameter csb1 = 2;
    parameter csb2 = 4;
    parameter csb3 = 6;
    parameter csb4 = 8;
    
    always @(posedge clk)
        if(!rst_n)
            led_zt <= 0;
        else  if (dis > csb4 )
            led_zt <= 4;
        else  if (dis > csb3 && dis <= csb4)
            led_zt <= 3;
        else  if (dis > csb2 && dis <= csb3)
            led_zt <= 2;
        else  if (dis > csb1 && dis <= csb2)
            led_zt <= 1;
        else  if (dis > csb0 && dis <= csb1)
            led_zt <= 0;
            
    
led_mk  kk(
    .    clk      (clk   )   ,
    .    rst_n    (rst_n )   ,
    .    led_zt   (led_zt)   ,
    .    led      (led_dd   )
    );
    
SR_04   sr(
        .   clk    (clk  ) ,
        .   rst_n  (rst_n) ,
        .   echo   (echo ) ,   //接收端,判断端口返回值
        .   dis    (dis  ) ,   //最终距离
        .   trig   (trig )     //脉冲发出
    );
endmodule

通过调用l超声波距离远近来控制led状态

本文原创,作者:FPGA小白,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/9114.html