项目信息
名称:超声测距显示与蜂鸣报警 Verilog QuartusII
软件:QuartusII
语言:Verilog
代码功能
该工程实现超声测距的三种输出形态:1)测得的距离在LCD屏上显示;2)同一距离值在数码管上动态显示;3)当距离低于阈值(默认100mm)时启动蜂鸣器报警。系统对回波信号做上升沿检测,统计两次上升沿之间的主时钟计数,并对多次测量做平均与线性校准后输出更稳定的距离结果。
代码实现思路
测距部分采用状态机:等待起始沿后开始计数,等待结束沿后锁存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
141