基于FPGA的超声波显示水位距离
- 前言
- 一、整体框架
- 二、代码架构
- 1.超声波测距模块
- 2.蓝牙数据发送模块
- 3.数码管数据切换模块
- 4.数码管驱动模块
- 6.串口驱动
- 7.顶层模块
- 8.RAM ip核
- 仿真相关截图
前言
随着工业化进程的加速和环境保护意识的提升,对水资源管理和水位监测的需求日益迫切。传统的水位监测系统多采用单片机或PLC作为控制核心存在处理速度慢、实时性差、扩展性有限等问题。基于FPGA的水位监测系统以其强大的并行处理能力、高度的灵活性和可重配置性,为水位监测提供了新的解决方案。本课题旨在设计并实现一个基于FPGA的水位监测系统,通过实时采集水位数据,结合先进的数据处理算法,实现高效、准确的水位监测。
本课题聚焦于设计一个基于FPGA的水位监测系统,它通过部署在水源处的传感器精确获取水位信息,利用FPGA强大的并行处理能力实时分析数据一旦水位超限立即触发报警,并上传数据至监测中心进行记录和存储。
1)查找资料对水位监测技术进行了解,提出系统整体设计方案。
2)选择适合的传感器模块、FPGA模块、通信模块、显示块等进行系统硬件设计。
3)利用自顶向下的设计方法进行系统顶层设计,并分模块进行FPGA程序设进行软硬件系统调试。
一、整体框架
硬件需求:FPGA开发板、数码管模块、3个按键、1个复位按键、蓝牙模块、超声波测距模块、蜂鸣器模块
软件模块框架:
二、代码架构
(仿真不需要按键消抖,同时时间间隔缩小)
1.超声波测距模块
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/04/12 16:01:55
// Design Name:
// Module Name: HC_SR04
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module HC_SR04(
input sys_clk ,
input rst_n,
//signal
input Echo,
output wire [15:0] Distance,
output reg Trig_signal
);
parameter IDLE=4'd0;
parameter SEND=4'd1;
parameter RECIEVE=4'd2;
parameter OVER=4'd3;
parameter MAX_CNT=24'd500;
parameter time_1s=32'd50000000;
reg [3:0] state;
reg [3:0] state_1;
reg [23:0] cnt;
reg [31:0] time_cnt;
reg [23:0] distance_temp;
reg key_start;
assign Distance=distance_temp/1000;
always @(posedge sys_clk or negedge rst_n)begin
if(!rst_n)begin
time_cnt<=32'd0;
key_start<=1'b0;
end
else if(time_cnt<time_1s)begin
time_cnt<=time_cnt+1;
key_start<=1'b0;
end
else if(time_cnt==time_1s)begin
time_cnt<=32'd0;
key_start<=1'b1;
end
end
always @(posedge sys_clk or negedge rst_n)begin
if(!rst_n)begin
state<=IDLE;
Trig_signal<=1'b0;
state_1<=IDLE;
distance_temp<=24'd10000000;
cnt<=24'd0;
end
else begin
case(state)
IDLE:begin
cnt<=24'd0;
if(key_start==1'b1)begin
state<=SEND;
end
else begin
state<=IDLE;
end
end
SEND:begin
if(cnt<MAX_CNT)begin
cnt<=cnt+1;
Trig_signal<=1'b1;
state<=SEND;
end
else begin
cnt<=16'd0;
Trig_signal<=1'b0;
state<=RECIEVE;
end
end
RECIEVE:begin
case(state_1)
IDLE:begin
if(Echo==1'b1)begin
state_1<=RECIEVE;
end
else begin
state_1<=IDLE;
end
end
RECIEVE:begin
if(Echo==1'b1)begin
cnt<=cnt+1;
end
else begin
cnt<=cnt+1;
state_1<=OVER;
end
end
OVER:begin
state_1<=IDLE;
state<=OVER;
end
default:state_1<=IDLE;
endcase
end
OVER:begin
distance_temp<=cnt*34;
state<=IDLE;
end
default:state<=IDLE;
endcase
end
end
endmodule
2.蓝牙数据发送模块
module Bluetooth_data(
input clk,
input rst_n,
input [3:0] data_3,
input [3:0] data_2,
input [3:0] data_4,
input uart_tx_done,
input [7 :0] uart_rx_data,
input uart_rx_done,
output reg uart_tx_en,
output reg [7:0] uart_tx_data
);
parameter IDLE = 4'd0;
parameter WAIT_1s = 4'd1;
parameter SEND = 4'd2;
parameter OVER = 4'd3;
parameter count_max = 32'd50000000; //
//spo2:23.6 ----> 74 65 6D 70 3A 32 33 2E 36 0d 0a
//hert:23.6 ----> 68 75 6D 69 3A 32 33 2E 36 0d 0a
reg [87:0] cmd_temp ={8'h68,8'h20,8'h3a,8'h32,8'h32,8'h2e,8'h33,8'h63,8'h6d,8'h0d,8'h0a};
reg [87:0] cmd_humi ={8'h68,8'h20,8'h3a,8'h32,8'h32,8'h2e,8'h33,8'h63,8'h6d,8'h0d,8'h0a};
reg [3: 0] state;
reg [31:0] count;
reg [5 :0] tx_count;
reg [1: 0] tx_en_count;
reg uart_tx_en_temp;
reg [1 :0] change_count;
wire [7:0] bluedata_1;
wire [7:0] bluedata_2;
wire [7:0] bluedata_3;
assign bluedata_1=(data_4==4'd0)?8'h20:8'h30+data_4;
assign bluedata_2=8'h30+data_3;
assign bluedata_3=8'h30+data_2;
//����״̬tx_data
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
uart_tx_data <= 8'd0;
end
else if(change_count==2'd0)begin
if((state==SEND) && tx_count<8'd3 ) begin
uart_tx_data <= cmd_temp[87 - tx_count *8 -:8];
end
else if((state==SEND) && tx_count==8'd3 ) begin
uart_tx_data <= bluedata_1;
end
else if((state==SEND) && tx_count==8'd4 ) begin
uart_tx_data <= bluedata_2;
end
else if((state==SEND) && tx_count==8'd5 ) begin
uart_tx_data <= 8'h3a;
end
else if((state==SEND) && tx_count==8'd6 ) begin
uart_tx_data <= bluedata_3;
end
else if((state==SEND) && tx_count<8'd11 ) begin
uart_tx_data <= cmd_temp[87 - tx_count *8 -:8];
end
end
else if(change_count==2'd1)begin
if((state==SEND) && tx_count<8'd3 ) begin
uart_tx_data <= cmd_humi[87 - tx_count *8 -:8];
end
else if((state==SEND) && tx_count==8'd3 ) begin
uart_tx_data <= bluedata_1;
end
else if((state==SEND) && tx_count==8'd4 ) begin
uart_tx_data <= bluedata_2;
end
else if((state==SEND) && tx_count==8'd5 ) begin
uart_tx_data <= 8'h3a;
end
else if((state==SEND) && tx_count==8'd6 ) begin
uart_tx_data <= bluedata_3;
end
else if((state==SEND) && tx_count<8'd11 ) begin
uart_tx_data <= cmd_humi[87 - tx_count *8 -:8];
end
end
end
//tx_en time
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
tx_en_count <= 2'b0;
end
else if((state==SEND) && tx_en_count<2'd1 && tx_count==8'd0) begin
tx_en_count <=tx_en_count+ 1'd1;
end
else if((state==SEND) && tx_en_count==2'd1 && tx_count==8'd0) begin
tx_en_count <= 2'd3;
end
else if(state==OVER)begin
tx_en_count <= 2'd0;
end
else begin
tx_en_count <= tx_en_count;
end
end
//����״̬tx_count
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
tx_count <= 8'd0;
end
else if(state==SEND) begin
if(uart_tx_done==1'd1)
tx_count <= tx_count+1'b1;
end
else begin
tx_count <= 8'd0;
end
end
//����״̬data_tx_en
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
uart_tx_en_temp <= 1'b0;
uart_tx_en <= uart_tx_en_temp;
end
else if((state==SEND ) && tx_en_count==1) begin
uart_tx_en_temp <= 1'b1;
uart_tx_en <= uart_tx_en_temp;
end
else if((state==SEND ) && tx_count<8'd10 && uart_tx_done==1)begin
uart_tx_en_temp <= 1'b1;
uart_tx_en <= uart_tx_en_temp;
end
else begin
uart_tx_en_temp <= 1'b0;
uart_tx_en <= uart_tx_en_temp;
end
end
//state go
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
count <= 32'd0;
end
else if(state == WAIT_1s && count < count_max)begin
count <= count + 32'd1;
end
else if(state == WAIT_1s && count == count_max)begin
count <= 32'd0;
end
else begin
count <= count;
end
end
//state go
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
state <= IDLE;
change_count<=2'd0;
end
else begin
case(state)
IDLE:begin
state<=WAIT_1s;
end
WAIT_1s:begin
if(count==count_max)begin
state<=SEND;
end
else begin
state<=WAIT_1s;
end
end
SEND:begin
if(tx_count==6'd11)begin
state <= OVER;
end
else begin
state <= SEND;
end
end
OVER:begin
state <= IDLE;
if(change_count<2'd1)begin
change_count<=change_count+2'd1;
end
else if(change_count==2'd1)begin
change_count<=2'd0;
end
end
default:state <= IDLE;
endcase
end
end
endmodule
3.数码管数据切换模块
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/05/26 14:56:37
// Design Name:
// Module Name: display_data
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module display_data(
input sys_clk ,
input rst_n,
input change_key,
input [15:0] Distance,
input [15:0] data_out,
output wire [3:0] data_3,
output wire [3:0] data_2,
output wire [3:0] data_4,
output reg [3 :0] display_point,
output reg [15:0] display_data
);
wire [15:0] Distance_temp;
wire [15:0] data;
wire [3:0] data_1;
// wire [3:0] data_3;
// wire [3:0] data_2;
// wire [3:0] data_4;
reg [1:0] cnt;
function [15:0]Hex_to_Doc;
input [15:0] num_h;
begin
Hex_to_Doc = num_h[3:0] + num_h[7:4]*16 +num_h[11:8]*256 +num_h[15:12]*4096;
end
endfunction
assign data=(cnt==2'd0)?Distance:data_out;
assign Distance_temp=Hex_to_Doc(data);
assign data_1=Distance_temp%10;
assign data_2=(Distance_temp%100)/10;
assign data_3=(Distance_temp%1000)/100;
assign data_4=(Distance_temp/1000);
always @(posedge sys_clk or negedge rst_n)begin
if(!rst_n)begin
cnt<=2'd0;
end
else if(change_key && cnt<2'd1)begin
cnt<=cnt+1;
end
else if(change_key && cnt==2'd1)begin
cnt<=2'd0;
end
end
always @(*)begin
if(data_4==4'd0)begin
display_data<={4'he,data_3,data_2,data_1};
display_point<=4'b1111;
end
else begin
display_data<={data_4,data_3,data_2,data_1};
display_point<=4'b1111;
end
end
endmodule
4.数码管驱动模块
module seg_ctrl(
input clk ,
input rst_n ,
input [15:0] din ,//????6��???????????????��???????4��
input [3:0] point_n ,//????��????????��
output reg [3:0] sel ,//????��?
output reg [7:0] dig //???????
);
//---------<????????>---------------------------------------------------------
parameter TIME_1MS = 50_000;//1ms
//????????????????
localparam NUM_0 = 7'b100_0000,//0
NUM_1 = 7'b111_1001,//1
NUM_2 = 7'b010_0100,//
NUM_3 = 7'b011_0000,//
NUM_4 = 7'b001_1001,//
NUM_5 = 7'b001_0010,//
NUM_6 = 7'b000_0010,//
NUM_7 = 7'b111_1000,//
NUM_8 = 7'b000_0000,//
NUM_9 = 7'b001_0000,//
A = 7'b000_1000,//
B = 7'b000_0011,//b
C = 7'b100_0110,//
OFF = 7'b111_1111,//???
CROSS = 7'b011_1111,//????
//D = 7'b010_0001,//d
//E = 7'b000_0110,//
F = 7'b000_1110;//
//---------<?????????>-----------------------------------------------------
reg [15:0] cnt_1ms ;//1ms???????????????????????
wire add_cnt_1ms ;
wire end_cnt_1ms ;
reg [3:0] disp_data ;//??��??????????????
reg point_n_r ;//??��???????????��????
//****************************************************************
//--cnt_1ms
//****************************************************************
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_1ms <= 'd0;
end
else if(add_cnt_1ms)begin
if(end_cnt_1ms)begin
cnt_1ms <= 'd0;
end
else begin
cnt_1ms <= cnt_1ms + 1'b1;
end
end
end
assign add_cnt_1ms = 1'b1;//??????????
assign end_cnt_1ms = add_cnt_1ms && cnt_1ms == TIME_1MS - 1;
//****************************************************************
//--seg_sel
//****************************************************************
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
sel <= 4'b1_110;//?????��???????????��??????
end
else if(end_cnt_1ms)begin
sel <= {sel[2:0],sel[3]};//???????
end
end
//****************************************************************
//--disp_data
//****************************************************************
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
disp_data <= 'd0;
point_n_r <= 1'b1;
end
else begin
case (sel)
4'b1_110 : begin disp_data <= din[3:0] ; point_n_r <= point_n[0]; end//???��??????????????
4'b1_101 : begin disp_data <= din[7:4] ; point_n_r <= point_n[1]; end
4'b1_011 : begin disp_data <= din[11:8] ; point_n_r <= point_n[2]; end
4'b0_111 : begin disp_data <= din[15:12]; point_n_r <= point_n[3]; end
default: disp_data <= 'd0;
endcase
end
end
//****************************************************************
//--seg_dig
//****************************************************************
always @(*)begin
case (disp_data)
0 : dig = {point_n_r,NUM_0};
1 : dig = {point_n_r,NUM_1};
2 : dig = {point_n_r,NUM_2};
3 : dig = {point_n_r,NUM_3};
4 : dig = {point_n_r,NUM_4};
5 : dig = {point_n_r,NUM_5};
6 : dig = {point_n_r,NUM_6};
7 : dig = {point_n_r,NUM_7};
8 : dig = {point_n_r,NUM_8};
9 : dig = {point_n_r,NUM_9};
10 : dig = {point_n_r,A };
11 : dig = {point_n_r,B };
12 : dig = {point_n_r,C };
13 : dig = {point_n_r,CROSS};
14 : dig = {point_n_r,OFF };
15 : dig = {point_n_r,F };
default: dig = 8'hff;
endcase
end
endmodule
6.串口驱动
module uart_top_blue(
input sys_clk , //�ⲿ50MHzʱ��
input sys_rst_n, //ϵ�ⲿ��λ�źţ�����Ч
//UART�˿�
input uart_rxd , //UART���ն˿�
output uart_txd , //UART���Ͷ˿�
input uart_tx_en, //UART���������ź�
output wire uart_rx_done, //UART���������ź�
output wire uart_tx_done, //UART���������ź�
input [7:0] uart_tx_data, //UART��������
output wire [7:0] uart_rx_data //UART��������
);
//parameter define
parameter CLK_FREQ = 50000000; //����ϵͳʱ��Ƶ��
parameter UART_BPS = 9600 ; //���崮�ڲ�����
//wire define
//wire uart_rx_done; //UART���������ź�
//wire [7:0] uart_rx_data; //UART��������
//*****************************************************
//** main code
//*****************************************************
//���ڽ���ģ��
uart_rx_blue #(
.CLK_FREQ (CLK_FREQ),
.UART_BPS (UART_BPS)
)
u_uart_rx_blue(
.clk (sys_clk ),
.rst_n (sys_rst_n ),
.uart_rxd (uart_rxd ),
.uart_rx_done (uart_rx_done),
.uart_rx_data (uart_rx_data)
);
uart_tx_blue #(
.CLK_FREQ (CLK_FREQ),
.UART_BPS (UART_BPS)
)
u_uart_tx_blue(
.clk (sys_clk ),
.rst_n (sys_rst_n ),
.uart_tx_en (uart_tx_en),
.uart_tx_data (uart_tx_data),
.uart_tx_done (uart_tx_done),
.uart_txd (uart_txd ),
.uart_tx_busy ( )
);
endmodule
module uart_rx_blue(
input clk , //ϵͳʱ��
input rst_n , //ϵͳ��λ������Ч
input uart_rxd , //UART���ն˿�
output reg uart_rx_done, //UART���������ź�
output reg [7:0] uart_rx_data //UART���յ�������
);
//parameter define
parameter CLK_FREQ = 100000000; //ϵͳʱ��Ƶ��
parameter UART_BPS = 115200 ; //���ڲ�����
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //Ϊ�õ�ָ�������ʣ���ϵͳʱ�Ӽ���BPS_CNT��
//reg define
reg uart_rxd_d0;
reg uart_rxd_d1;
reg uart_rxd_d2;
reg rx_flag ; //���չ��̱�־�ź�
reg [3:0 ] rx_cnt ; //�������ݼ�����
reg [15:0] baud_cnt ; //�����ʼ�����
reg [7:0 ] rx_data_t ; //�������ݼĴ���
//wire define
wire start_en;
//*****************************************************
//** main code
//*****************************************************
//�������ն˿��½���(��ʼλ)���õ�һ��ʱ�����ڵ������ź�
assign start_en = uart_rxd_d2 & (~uart_rxd_d1) & (~rx_flag);
//�����첽�źŵ�ͬ������
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
uart_rxd_d0 <= 1'b0;
uart_rxd_d1 <= 1'b0;
uart_rxd_d2 <= 1'b0;
end
else begin
uart_rxd_d0 <= uart_rxd;
uart_rxd_d1 <= uart_rxd_d0;
uart_rxd_d2 <= uart_rxd_d1;
end
end
//�����ձ�־��ֵ
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
rx_flag <= 1'b0;
else if(start_en) //�����ʼλ
rx_flag <= 1'b1; //���չ����У���־�ź�rx_flag���
//��ֹͣλһ����ʱ�����չ��̽�������־�ź�rx_flag���
else if((rx_cnt == 4'd9) && (baud_cnt == BAUD_CNT_MAX/2 - 1'b1))
rx_flag <= 1'b0;
else
rx_flag <= rx_flag;
end
//�����ʵļ�������ֵ
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
baud_cnt <= 16'd0;
else if(rx_flag) begin //���ڽ��չ���ʱ�������ʼ�������baud_cnt������ѭ������
if(baud_cnt < BAUD_CNT_MAX - 1'b1)
baud_cnt <= baud_cnt + 16'b1;
else
baud_cnt <= 16'd0; //�����ﵽһ�����������ں�����
end
else
baud_cnt <= 16'd0; //���չ��̽���ʱ����������
end
//�Խ������ݼ�������rx_cnt�����и�ֵ
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
rx_cnt <= 4'd0;
else if(rx_flag) begin //���ڽ��չ���ʱrx_cnt�Ž��м���
if(baud_cnt == BAUD_CNT_MAX - 1'b1) //�������ʼ�����������һ������������ʱ
rx_cnt <= rx_cnt + 1'b1; //�������ݼ�������1
else
rx_cnt <= rx_cnt;
end
else
rx_cnt <= 4'd0; //���չ��̽���ʱ����������
end
//����rx_cnt��Ĵ�rxd�˿ڵ�����
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
rx_data_t <= 8'b0;
else if(rx_flag) begin //ϵͳ���ڽ��չ���ʱ
if(baud_cnt == BAUD_CNT_MAX/2 - 1'b1) begin //�ж�baud_cnt�Ƿ�����������λ���м�
case(rx_cnt)
4'd1 : rx_data_t[0] <= uart_rxd_d2; //�Ĵ����ݵ�����λ
4'd2 : rx_data_t[1] <= uart_rxd_d2;
4'd3 : rx_data_t[2] <= uart_rxd_d2;
4'd4 : rx_data_t[3] <= uart_rxd_d2;
4'd5 : rx_data_t[4] <= uart_rxd_d2;
4'd6 : rx_data_t[5] <= uart_rxd_d2;
4'd7 : rx_data_t[6] <= uart_rxd_d2;
4'd8 : rx_data_t[7] <= uart_rxd_d2; //�Ĵ����ݵĸߵ�λ
default : ;
endcase
end
else
rx_data_t <= rx_data_t;
end
else
rx_data_t <= 8'b0;
end
//�����������źźͽ��յ������ݸ�ֵ
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
uart_rx_done <= 1'b0;
uart_rx_data <= 8'b0;
end
//���������ݼ�����������ֹͣλ����baud_cnt������ֹͣλ���м�ʱ
else if(rx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX/2 - 1'b1) begin
uart_rx_done <= 1'b1 ; //��߽��������ź�
uart_rx_data <= rx_data_t; //����UART���յ������ݽ��и�ֵ
end
else begin
uart_rx_done <= 1'b0;
uart_rx_data <= uart_rx_data;
end
end
endmodule
module uart_tx_blue(
input clk , //ϵͳʱ��
input rst_n , //ϵͳ��λ������Ч
input uart_tx_en , //UART�ķ���ʹ��
input [7:0] uart_tx_data, //UARTҪ���͵�����
output reg uart_txd , //UART���Ͷ˿�
output reg [3:0] tx_cnt , //�������ݼ�����
output reg [15:0] baud_cnt , //�����ʼ�����
output reg uart_tx_done,
output reg uart_tx_busy //����æ״̬�ź�
);
//parameter define
parameter CLK_FREQ = 100000000; //ϵͳʱ��Ƶ��
parameter UART_BPS = 115200 ; //���ڲ�����
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //Ϊ�õ�ָ�������ʣ���ϵͳʱ�Ӽ���BPS_CNT��
//reg define
reg [7:0] tx_data_t; //�������ݼĴ���
//�����ʵļ�������ֵ
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
uart_tx_done<=1'b0;
else if(tx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX - 1) begin
uart_tx_done<=1'b1;
end
else
uart_tx_done<=1'b0; //�����̽���ʱ����������
end
//*****************************************************
//** main code
//*****************************************************
//��uart_tx_enΪ��ʱ���Ĵ������IJ������ݣ������BUSY�ź�
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
tx_data_t <= 8'b0;
uart_tx_busy <= 1'b0;
end
//����ʹ��ʱ���Ĵ�Ҫ���͵����ݣ������BUSY�ź�
else if(uart_tx_en) begin
tx_data_t <= uart_tx_data;
uart_tx_busy <= 1'b1;
end
//��������ֹͣλ����ʱ��ֹͣ������
else if(tx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX - 1) begin
tx_data_t <= 8'b0; //���շ������ݼĴ���
uart_tx_busy <= 1'b0; //�����BUSY�ź�
end
else begin
tx_data_t <= tx_data_t;
uart_tx_busy <= uart_tx_busy;
end
end
//�����ʵļ�������ֵ
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
baud_cnt <= 16'd0;
else if(uart_tx_en)
baud_cnt <= 16'd0;
//�����ڷ�����ʱ�������ʼ�������baud_cnt������ѭ������
else if(uart_tx_busy) begin
if(baud_cnt < BAUD_CNT_MAX - 1'b1)
baud_cnt <= baud_cnt + 16'b1;
else
baud_cnt <= 16'd0; //�����ﵽһ�����������ں�����
end
else
baud_cnt <= 16'd0; //�����̽���ʱ����������
end
//tx_cnt���и�ֵ
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
tx_cnt <= 4'd0;
else if(uart_tx_en)
tx_cnt <= 16'd0;
else if(uart_tx_busy) begin //���ڷ�����ʱtx_cnt�Ž��м���
if(baud_cnt == BAUD_CNT_MAX - 1'b1) //�������ʼ�����������һ������������ʱ
tx_cnt <= tx_cnt + 1'b1; //�������ݼ�������1
else
tx_cnt <= tx_cnt;
end
else
tx_cnt <= 4'd0; //�����̽���ʱ����������
end
//����tx_cnt���uart���Ͷ˿ڸ�ֵ
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
uart_txd <= 1'b1;
else if(uart_tx_busy) begin
case(tx_cnt)
4'd0 : uart_txd <= 1'b0 ; //��ʼλ
4'd1 : uart_txd <= tx_data_t[0]; //����λ����λ
4'd2 : uart_txd <= tx_data_t[1];
4'd3 : uart_txd <= tx_data_t[2];
4'd4 : uart_txd <= tx_data_t[3];
4'd5 : uart_txd <= tx_data_t[4];
4'd6 : uart_txd <= tx_data_t[5];
4'd7 : uart_txd <= tx_data_t[6];
4'd8 : uart_txd <= tx_data_t[7]; //����λ����λ
4'd9 : uart_txd <= 1'b1 ; //ֹͣλ
default : uart_txd <= 1'b1;
endcase
end
else
uart_txd <= 1'b1; //����ʱ���Ͷ˿�Ϊ�ߵ�ƽ
end
endmodule
7.顶层模块
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/04/20 09:30:52
// Design Name:
// Module Name: top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module top(
input sys_clk ,
input rst_n,
input save_key,
input read_key,
input change_key,
input Echo,
output wire Trig_signal,
input uart_rxd1 ,
output uart_txd1 ,
output wire [3:0] sel,
output wire [7:0] dig,
output wire sim_start,
output wire Beep
);
//seg signal
wire [15:0] display_data;
wire [15:0] Distance;
wire [3:0] data_3;
wire [3:0] data_2;
wire [3:0] data_4;
wire uart_tx_en1;
wire uart_rx_done1;
wire uart_tx_done1;
wire [7:0] uart_tx_data1;
wire [7:0] uart_rx_data1;
wire [15:0] data_out;
assign Beep=(Distance<16'd500)?1'b0:1'b1;
HC_SR04 u_HC_SR04(
.sys_clk(sys_clk) ,
.rst_n(rst_n) ,
.Echo(Echo) ,
.Distance(Distance) ,
.sim_start(sim_start),
.Trig_signal(Trig_signal)
);
display_data u_display_data(
.sys_clk(sys_clk) ,
.rst_n(rst_n) ,
.Distance(Distance) ,
.data_out(data_out) ,
.change_key(change_key) ,
.data_3(data_3) ,
.data_2(data_2) ,
.data_4(data_4) ,
.display_data(display_data)
);
ram u_ram (
.address ( 5'd1 ),
.clock ( sys_clk ),
.data ( Distance ),
.rden ( read_key ),
.wren ( save_key ),
.q ( data_out )
);
Bluetooth_data u_Bluetooth_data(
.clk(sys_clk),
.rst_n(rst_n),
.data_3(data_3) ,
.data_2(data_2) ,
.data_4(data_4) ,
.uart_rx_done (uart_rx_done1),
.uart_rx_data (uart_rx_data1),
.uart_tx_en (uart_tx_en1),
.uart_tx_data (uart_tx_data1),
.uart_tx_done (uart_tx_done1)
);
uart_top_blue u_uart_top_blue(
.sys_clk(sys_clk) ,
.sys_rst_n(rst_n),
.uart_rx_done (uart_rx_done1),
.uart_rx_data (uart_rx_data1),
.uart_tx_en (uart_tx_en1),
.uart_tx_data (uart_tx_data1),
.uart_tx_done (uart_tx_done1),
.uart_rxd(uart_rxd1) ,
.uart_txd(uart_txd1)
);
seg_ctrl u_seg_ctrl(
.clk(sys_clk) ,
.rst_n(rst_n) ,
.din(display_data),
.point_n(4'b1011) ,
.sel(sel) ,
.dig(dig)
);
endmodule
8.RAM ip核
仿真相关截图
仿真没有按键消抖,测距时间间隔缩短一点,其他正常。