扫码加入

  • 方案介绍
  • 附件下载
  • 相关推荐
申请入驻 产业图谱

超声测距显示与蜂鸣报警的设计Verilog代码Quartus MINI_FPGA 开发板

22小时前
266
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

2-2601161GI24K.docx

共1个文件

名称:超声测距显示与蜂鸣报警的设计Verilog代码Quartus  MINI_FPGA 开发板

软件:QuartusII

语言:Verilog

代码功能

该工程实现超声测距的三种输出形态:1)测得的距离在LCD屏上显示;2)同一距离值在数码管上动态显示;3)当距离低于阈值(默认100mm)时启动蜂鸣器报警。系统对回波信号做上升沿检测,统计两次上升沿之间的主时钟计数,并对多次测量做平均与线性校准后输出更稳定的距离结果。

FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com

本代码已在MINI_FPGA 开发板验证,MINI_FPGA 开发板如下,其他开发板可以修改管脚适配:

MINI_FPGA 开发板.png

演示视频:

设计文档:

代码实现思路

测距部分采用状态机:等待起始沿后开始计数,等待结束沿后锁存Time_Count;为了降低抖动,将16次测量结果累加后取平均,再用线性模型k、b对结果做校准(代码中以定点放大倍数实现,最终右移恢复实际距离)。显示部分把距离值先转换为BCD码,再交由数码管扫描模块输出;LCD部分通过封装好的FPGA_LCD与SPI发送模块,在初始化完成后按指定坐标绘制字符/数字。报警部分则用简单的分频方波作为蜂鸣器驱动,在距离小于阈值时使能。

代码结构

顶层Main模块集成测距、数码管显示、蜂鸣器与LCD显示:前端用同步寄存器把异步回波信号同步到主时钟域并做边沿检测;中间用状态机与计数器计算平均后的距离并转换为BCD;后端分别连接Digitron_TimeDisplay_module进行数码管动态显示,连接FPGA_LCD完成LCD初始化与图文显示,连接beep_ctrl实现距离阈值报警。整体结构从“采样→计算→显示/告警”清晰分层。

文件/模块一览

radar_LCD_newDigitron_TimeDisplay_module.v:Digitron_TimeDisplay_module

radar_LCD_newFPGA_LCD.v:FPGA_LCD

radar_LCD_newMain.v:Main

radar_LCD_newSPI_TX.v:SPI_TX

radar_LCD_newbeep_ctrl.v:beep_ctrl

radar_LCD_newbinary2bcd.v:binary2bcd

radar_LCD_newblock_rom.v:block_rom

radar_LCD_newlcd_funcmod.v:lcd_funcmod

部分代码

radar_LCD_newMain.v

module Main(            input Main_CLK,         input RSTn,          input [1:0]Radar_Receiver,          output [7:0] Digitron_Out,          output [5:0] DigitronCS_Out,          output beep,//蜂鸣器          output LCD_RESET,          output LCD_BLK,          output LCD_DC,          outputCS,    outputMOSI,          outputSCK             );          localparam IDLE       = 0;          localparam Start      = 1;          localparam Count      = 2;          localparam Wait_Multi = 3;//等待乘法器完成          localparam Cal        = 4;          //颜色          parameter Red = 16'h07FF ;          parameter White = 16'h0000 ;          parameter Black = 16'hFFFF ;          parameter Green = 16'hF81F ;          parameter Yellow = 16'h001F ;          parameter Brown = 16'h43BF ;          parameter Blue = 16'hFFE0 ;          reg count_begin ;// 第一个信号过来,开始计时          reg count_end ;// 第二个信号过来,结束计时          reg Radar_Start_Temp ;          reg Radar_End_Temp ;          reg [1:0]Radar_Receiver_Reg ;          always@(posedge Main_CLK) //把异步信号转成同步,防止竞争冒险          begin                        Radar_Receiver_Reg <= Radar_Receiver ;          end          always@(posedge Main_CLK)          begin                        Radar_Start_Temp <= Radar_Receiver_Reg[0] ;              if(Radar_Receiver_Reg[0] == 1'b1 && Radar_Start_Temp==1'b0) //检测到上升沿                        begin                                      count_begin <=1'b1 ;                        end                        else                                      count_begin <=1'b0 ;              end          always@(posedge Main_CLK)          begin                        Radar_End_Temp <= Radar_Receiver_Reg[1] ;              if(Radar_Receiver_Reg[1] == 1'b1 && Radar_End_Temp==1'b0) //检测到上升沿                        begin                                      count_end <=1'b1 ;                        end                        else                                      count_end <=1'b0 ;              end          reg[3:0]state ;          reg[18:0]Time_Count /* synthesis preserve */; //记录雷达两个上升沿之间的主时钟计数          reg [4:0]Ave_Count /* synthesis preserve */;//用于平均操作的计数器,平均16次          reg[22:0] Distance_Sum /* synthesis preserve */; //存储累加16次的Time_Count          reg[21:0] b = 22'd2761201;//计算公式里的b,放大了65536倍          reg[8:0] k = 9'd233 ;               //计算公式里的k,放大了65536倍          reg[27:0] Distance_Cal /* synthesis preserve */;//校准后的距离值,跟随k,b的放大倍数,放大了65536倍          wire done ;          reg [3:0]wait_time ; //等待乘法器完成的节拍          always@(posedge Main_CLK or negedge RSTn)          begin                        if(!RSTn)              begin                            state <= IDLE ;              end              else              begin                                    case(state)                  IDLE:                  begin                         state <= Start ;                         Time_Count <= 19'd0 ;             //              div1_start <= 1'b1 ;                         Ave_Count <= 5'd0 ;                         Distance_Sum <= 23'd0 ;                         wait_time <= 4'd0 ;                  end                  Start:                  begin                                if(count_begin==1'b1)                      begin                                    state <= Count ;                                    Time_Count <= 19'd0 ;                      end                              end                  Count:                  begin                                if(count_end==1'b0)                                              Time_Count <= Time_Count + 1'b1 ;                      else                      begin                                      if(Ave_Count<5'd16)                          begin                                        Distance_Sum <= Distance_Sum + Time_Count ;                              Ave_Count <= Ave_Count + 1'b1 ;                              state <= Start ;                          end                          else                          begin                                        state <= Wait_Multi ;                               Distance_Cal <=Distance_Sum[22:4]*k - b ;                          end                                           end                              end                  Wait_Multi:                  begin                                if(wait_time<4'd4)                                              wait_time <= wait_time + 1'b1 ;                      else                                    state <= Cal ;                  end                  Cal:                  begin                                      state <= IDLE ;                   end                  endcase              end          end          wire[11:0] Distance; // 实际的距离值          //Distance_Cal被放大了65536倍,因此这次右移16位,相当于除以65536;          assign Distance = Distance_Cal[27:16];           wire [11:0]Distance_bcd ; // 转换成BCD码显示到数码管上binary2bcd U2                        (                        .a(Distance),                         .b(Distance_bcd)                        );                               Digitron_TimeDisplay_module U3              (                            .clk(Main_CLK),                                       .data_display(Distance_bcd[11:0]),//BCD_Display                            .Digitron_Out(Digitron_Out),                             .DigitronCS_Out(DigitronCS_Out)              );                        beep_ctrl i_beep_ctrl(          . clk(Main_CLK),           . Distance(Distance), // 实际的距离值          . beep(beep)          );                        reg [23:0]data_integer ;          always@(Distance_bcd )           begin                        case(Distance_bcd[11:8])                  0:           begin data_integer[23:16] = " "; end        1:           begin data_integer[23:16] = "1";end        2:           begin data_integer[23:16] = "2";end        3:           begin data_integer[23:16] = "3";end                                  4:           begin data_integer[23:16] = "4";end        5:           begin data_integer[23:16] = "5";end        6:           begin data_integer[23:16] = "6";end        7:           begin data_integer[23:16] = "7";end                      8:           begin data_integer[23:16] = "8";end        9:           begin data_integer[23:16] = "9";end                       endcase                        case(Distance_bcd[7:4])                  0:           begin data_integer[15:8] = "0"; end        1:           begin data_integer[15:8] = "1";end        2:           begin data_integer[15:8] = "2";end        3:           begin data_integer[15:8] = "3";end

 

 

 

  • 2-2601161GI24K.docx
    下载

相关推荐