目录
项目说明
- 使用 DE2-115 开发板驱动超声波模块(HC_SR04 ),
- 驱动数码管模块将数据显示到开发板模块上,
- 或者将数据用串口通信的方式将数据显示到笔记本串口助手上,
- 蜂鸣器根据数据大小鸣叫。
超声波测距模块
模块原理说明
如果超声波模块前方没有障碍物,约4米之内,那当Trig引脚被提供10μs以上脉冲触发信号后,该模块内部发射(transmit)8个40kHz的超声波脉冲并检测回波,Echo引脚收到一个高电平并持续38毫秒,之后就会处于低电平状态,所以当得到38ms这个值时,我们就知道前方没有检测到障碍物了。
如果前方有障碍物,那在发射超声波脉冲后,信号就会反射回来,Echo引脚就会在接收到信号时立即切换到低电平状态,此时Echo引脚在高电平状态保持的时间就是信号发射并返回的所花的时间。
我们知道距离 = 速度 X 时间,要求出超声波模块到障碍物之间的距离,我们就需要知道速度和时间。速度就是 340 m/s,也就是声音在空气中传播的速度,转换城cm/μs单位就是0.034 cm/μs。时间的话,由于我们得到的是信号从发射到返回的时间值,所以需要除以 2 。最终得到的计算公式为:距离 = 0.034 cm/μs * 时间(μs) / 2
超声波模块(正面)
超声波模块(反面)
从上图我们可以看到超声波模块的4个引脚,它们的作用罗列如下:
-
VCC: 电源引脚,超声波模块工作电压为5伏。
-
Trig: 是Trigger(触发)这个单词的缩写,该引脚用于触发超声波脉冲。
-
Echo: 该引脚会在高电平和低电平之间转换,当检测到障碍物时,在高电平保持的时间就表示信号发射出去并反射回来的时间。
-
GND: 接地引脚。
模块工作过程
(1) 主控设备给 Trig 脚提供一个 10us 的脉冲信号。
(2) HC-SR04 接收到信号,开始发送超声波,并把 Echo置为高电平,然后准备接收返回的超声波。
(3) HC-SR04 接收到返回的超声波,把 Echo 置为低电平。
(4) Echo 高电平持续的时间就是超声波从发射到返回的时间间隔。
模块工作时序图
以上时序图表明你只需要提供一个10uS 以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。公式: uS/58=厘米或者uS/148=英寸;或是:距离=高电平时间*声速(340M/S)/2;建议测量周期为60ms 以上,以防止发射信号对回响信号的影响。
模块电气参数
图源:HC-SR04超声波测距模块说明书(by深圳市捷深科技有限公司)
模块驱动代码
module distance_drive (
input wire clk,
input wire clk_1,
input wire rst_n,
input wire echo,
output reg trig,
output wire data_out_vld,
output wire [ 23:0 ] distance_data
);
localparam MAX_DISTANCE = 117647; //最大距离 4m
parameter s_idle = 0;//空闲状态
parameter s_send = 1;//发送触发信号
parameter s_wait = 2;//等待内部发送脉冲
parameter s_accept = 3;//检测回响信号
parameter s_accept_wait = 4;//延时等待
reg echo_r0 ;
reg echo_r1 ;
reg [ 2:0 ] s_current ;
reg [ 2:0 ] s_next ;
reg [ 22 :0 ] cnt ;
reg [ 22:0 ] cnt_wait ;
reg [ 22:0 ] cnt_max ;
reg [ 16:0 ] cnt_distance ;
// reg [ 25:0 ] cnt_distance_r1 ;
// reg [ 19:0 ] cnt_distance_r2 ;
wire accept_start_sig ;
wire accept_stop_sig ;
wire idle_sig ;
wire send_sig ;
// wire wait_sig ;
wire flag_clear_cnt ;
wire flag_clear_cnt_wait ;
reg [ 19:0 ] distance_data_r ;
wire [ 23:0 ] distance_data_r1 ;
assign idle_sig = s_current == s_idle;
assign send_sig = s_current == s_send && flag_clear_cnt;
// assign wait_sig = s_current == s_wait && flag_clear_cnt_wait;
assign accept_wait_sig = s_current == s_accept_wait && flag_clear_cnt_wait;
assign accept_start_sig = s_current == s_wait && echo_r0 && ~echo_r1;
assign accept_stop_sig = s_current == s_accept && (~echo_r0 && echo_r1);
// always @(posedge clk or negedge rst_n) begin
// if(!rst_n) begin
// cnt_distance_r1 <= 0;
// // cnt_distance_r2 <= 0;
// end
// else begin
// cnt_distance_r1 <= cnt_distance * 340 / 100;
// // cnt_distance_r2 <= cnt_distance_r1 >> 4;
// end
// end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
echo_r0 <= 0;
echo_r1 <= 0;
end
else begin
echo_r0 <= echo;
echo_r1 <= echo_r0;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
s_current <= s_idle;
end
else begin
s_current <= s_next;
end
end
always @(*) begin
case (s_current)
s_idle : begin
if(idle_sig) begin
s_next = s_send;
end
else begin
s_next = s_idle;
end
end
s_send : begin
if(send_sig) begin
s_next = s_wait;
end
else begin
s_next = s_send;
end
end
s_wait : begin
if(accept_start_sig) begin
s_next = s_accept;
end
else begin
s_next = s_wait;
end
end
s_accept : begin
if(accept_stop_sig) begin
s_next = s_accept_wait;
end
else begin
s_next = s_accept;
end
end
s_accept_wait : begin
if(accept_wait_sig) begin
s_next <= s_idle;
end
else begin
s_next <= s_accept_wait;
end
end
default: s_next = s_idle;
endcase
end
//距离
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
distance_data_r <= 0;
end
else if(accept_stop_sig) begin
distance_data_r <= cnt_distance * 340 / 200;
end
end
//转BCD码
assign distance_data_r1[3:0] = distance_data_r % 10;
assign distance_data_r1[7:4] = distance_data_r / 10 % 10;
assign distance_data_r1[11:8] = distance_data_r / 100 % 10;
assign distance_data_r1[15:12] = distance_data_r / 1000 % 10;
assign distance_data_r1[19:16] = distance_data_r / 10000 % 10;
assign distance_data_r1[23:20] = distance_data_r / 100000 % 10;
assign data_out_vld = accept_wait_sig;
assign distance_data = distance_data_r1;
//回响信号计数器
always @(posedge clk_1 or negedge rst_n) begin
if(!rst_n) begin
cnt_distance <= 0;
end
else if(accept_start_sig) begin
cnt_distance <= 0;
end
else if(s_current == s_accept) begin
cnt_distance <= cnt_distance + 1;
end
else begin
cnt_distance <= 0;
end
end
//发送触发信号
always @(posedge clk_1 or negedge rst_n) begin
case (s_current)
s_idle : begin
trig <= 0;
end
s_send : begin
trig <= 1;
end
s_wait : begin
trig <= 0;
end
s_accept : begin
trig <= 0;
end
s_accept_wait : begin
trig <= 0;
end
default: begin
trig <= 0;
end
endcase
end
//等待发送玩脉冲
always @( posedge clk_1 or negedge rst_n ) begin
if ( !rst_n ) begin
cnt <= 0;
end
else if ( s_current == s_send ) begin
if ( flag_clear_cnt == 9 ) begin
cnt <= 0;
end
else begin
cnt <= cnt + 1;
end
end
else begin
cnt <= 0;
end
end
assign flag_clear_cnt = cnt == 9;
//延时计数器
always @( posedge clk_1 or negedge rst_n ) begin
if ( !rst_n ) begin
cnt_wait <= 0;
end
else if ( s_current == s_accept_wait ) begin
if ( flag_clear_cnt_wait ) begin
cnt_wait <= 0;
end
else begin
cnt_wait <= cnt_wait + 1;
end
end
else begin
cnt_wait <= 0;
end
end
assign flag_clear_cnt_wait = cnt_wait == 250_000;
endmodule //distance
串口通信模块
该模块实现将采集到的测距数据通过串口将数据输出显示到笔记本的串口助手上的功能。
串口发送模块
module uart_tx(input wire clk,
input wire rst_n,
input wire tx_enable, // 发送使能
input wire [ 07:0 ] data_in, // 需要发送的数据
input wire [ 19:0 ] tx_bps, // 发送的波特率
output wire data, // 发送的数据
output wire tx_done);
localparam MAX_BIT = 10;
reg [ 09:0 ] data_r ; // 数据寄存器
reg [ 12:0 ] cnt_bps ; // 波特率计数器
reg [ 03:0 ] cnt_bit ; // 数据位计数器
wire [ 12:0 ] max_bps ; // 波特率对应频率
wire flag_clear_cnt_bps ; // 计数器归零
wire flag_add_cnt_bit ; // 计数器+1
wire flag_clear_cnt_bit ;
reg flag_send_data ; //发送数据标志
//输入数据寄存
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
data_r <= 10'b0;
end
else if(tx_enable) begin
data_r <={1'b1, data_in, 1'b0};
end
end
// 波特率计数器
always @( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cnt_bps <= 0;
end
else if ( flag_send_data ) begin
if ( flag_clear_cnt_bps ) begin
cnt_bps <= 0;
end
else begin
cnt_bps <= cnt_bps + 1;
end
end
else begin
cnt_bps <= 0;
end
end
assign flag_clear_cnt_bps = cnt_bps >= max_bps -1;
assign max_bps = 50_000_000 / tx_bps;
// 数据位计数器
always @( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cnt_bit <= 0;
end
else if ( flag_send_data ) begin
if ( flag_clear_cnt_bit ) begin
cnt_bit <= 0;
end
else if ( flag_add_cnt_bit )begin
cnt_bit <= cnt_bit + 1;
end
else begin
cnt_bit <= cnt_bit;
end
end
else begin
cnt_bit <= 0;
end
end
assign flag_add_cnt_bit = flag_clear_cnt_bps;
assign flag_clear_cnt_bit = cnt_bit >= MAX_BIT - 1 && flag_add_cnt_bit ;
//发送数据标志
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
flag_send_data <= 0;
end
else if(tx_enable) begin
flag_send_data <= 1;
end
else if(flag_clear_cnt_bit) begin
flag_send_data <= 0;
end
else begin
flag_send_data <= flag_send_data;
end
end
//发送数据
assign data = flag_send_data ? data_r[cnt_bit]:1;
assign tx_done = ~flag_send_data ;
endmodule
串口发送控制模块
串口控制模块把接受到的24位BCD码转换成ASSIC码,并且清除高位零位和添加单位和小数点。把处理好的数据加入FIFO中,再通过串口发送模块进行发送。
该模块不在本次学习的重点,且原理笔者之前的文章介绍过,本次不做详细描述。
module uart_drive (
input wire clk,
input wire rst_n,
input wire [ 23:0 ] distance_data,
input wire data_vld,
output wire rx_data,
output wire tx_data
);
reg [ 23:0 ] distance_data_r ;
reg [ 7:0 ] data ;
reg [ 3:0 ] cnt_byte ;
reg send_flag ;
wire [ 7:0 ] distance ;
wire rdreq ;
wire wrreq ;
wire empty ;
wire full ;
wire [ 7:0 ] data_in ;
reg flag ;
//串口
uart_tx u_uart_tx(
.clk ( clk ),
.rst_n ( rst_n ),
.tx_enable ( rdreq ),
.data_in ( data_in ),
.tx_bps ( 115200 ),
.data ( tx_data ),
.tx_done ( tx_done )
);
assign rdreq = tx_done && ~empty;
assign wrreq = ~full && send_flag && (cnt_byte > 0) && flag;
assign distance = data;
tx_fifo tx_fifo_inst (
.aclr ( ~rst_n ),
.clock ( clk ),
.data ( distance ),
.rdreq ( rdreq ),
.wrreq ( wrreq ),
.empty ( empty ),
.full ( full ),
.q ( data_in ),
.usedw ( usedw_sig )
);
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
send_flag <= 0;
end
else if(cnt_byte == 9) begin
send_flag <= 0;
end
else if(data_vld) begin
send_flag <= 1;
end
end
//数据计数器
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt_byte <=0;
end
else if(cnt_byte == 9) begin
cnt_byte <= 0;
end
else if(send_flag) begin
cnt_byte <= cnt_byte + 1;
end
end
//寄存数据
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
distance_data_r <=0;
end
else if(data_vld) begin
distance_data_r <= distance_data;
end
end
//去除前面的不必要的0
always @(*) begin
if(!rst_n) begin
flag = 0;
end
else if(!send_flag) begin
flag <= 0;
end
else if(cnt_byte > 3 || data> 48) begin
flag = 1;
end
else begin
flag <= flag;
end
end
//发送距离
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
data <=0;
end
else if(send_flag) begin
case (cnt_byte)
0 : data <= distance_data_r[23:20] + 48;
1 : data <= distance_data_r[19:19] + 48;
2 : data <= distance_data_r[15:12] + 48;
3 : data <= distance_data_r[11:8 ] + 48;
4 : data <= 46; // .
5 : data <= distance_data_r[7 : 4] + 48;
6 : data <= distance_data_r[3 : 0] + 48;
7 : data <= 99 ; //c
8 : data <= 109; //m
default: data <=0;
endcase
// data <= distance_data_r[(4 * (6-cnt_byte) -1) -:4] + 48;
end
end
endmodule //uart_drive
运行效果
蜂鸣器模块
蜂鸣器模块把接受到的数据去掉低两位,也就是精度变成厘米级别。当处理完后的数据在设定的最大值MAX_DISTANCE和最小值MIN_DISTANCE之间,则会根据数据的大小调整蜂鸣器鸣叫间隔,使得蜂鸣器的鸣叫频率随着距离的减少越来越高,当数据小于MIN_DISTANCE时则会一直处在鸣叫状态。
该模块不在本次学习的重点,且原理笔者之前的文章介绍过,本次不做详细描述。
module beep_dirve (
input wire clk,
input wire rst_n,
input wire beep_vld,
input wire data_vld,
input wire [ 23:0 ] distance_data,
output reg beep
);
parameter MAX_DISTANCE = 20;
parameter MIN_DISTANCE = 10;
parameter MAX_TIME = 50_000_000;
reg [ 27:0 ] cnt ;
wire [ 27:0 ] delay ;
wire [ 19:0 ] distance ;
reg [ 23:0 ] distance_data_r ;
// wire [ 19:0 ] distance_r ;
//寄存数据
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
distance_data_r <= 0;
end
else if(data_vld) begin
distance_data_r <= distance_data;
end
end
// 根据距离设置翻转频率
assign distance = distance_data_r[11:8] + distance_data_r[15:12] * 10 + distance_data_r[19:16] * 100 + distance_data_r[23:20] *1000;
assign delay = ((distance ) + 1) * 200_000;
// // led
always @( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cnt <= 0;
end
else if ( cnt >= delay ) begin
cnt <= 0;
end
else begin
cnt <= cnt + 1;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
beep <= 1;
end
else if(~beep_vld) begin
beep <= 1;
end
else if(distance <= MAX_DISTANCE && distance >= MIN_DISTANCE && cnt == 1 && beep_vld) begin
beep <= ~ beep;
end
else if(distance < MIN_DISTANCE && beep_vld) begin
beep <= 0;
end
else if(distance > MAX_DISTANCE) begin
beep <= 1;
end
else begin
beep <= beep;
end
end
endmodule //beep_dirve
数码管显示模块
所谓段选信号,就是给七段数码管的每一段灯管赋值,实现控制显示输出的效果。而位选信号,则是直接给整个七段数码管赋值,实现显示输出的效果。
数码管段选控制
根据位选信号来显示对应位置的数字。理解:seg(segment)
module seg_drive(input wire clk,
input wire rst_n,
input wire data_vld,
input wire [ 23:0 ] display_data,
input wire [ 5:0 ] sel,
output reg [ 7:0 ] seg);
localparam ZERO = 7'b100_0000;
localparam ONE = 7'b111_1001;
localparam TWO = 7'b010_0100;
localparam THREE = 7'b011_0000;
localparam FOUR = 7'b001_1001;
localparam FIVE = 7'b001_0010;
localparam SIX = 7'b000_0010;
localparam SEVEN = 7'b111_1000;
localparam EIGHT = 7'b000_0000;
localparam NINE = 7'b001_0000;
localparam N = 7'b010_1011;
localparam P = 7'b000_1111;
reg [ 23:0 ] display_data_r ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
display_data_r <= 0;
end
else if(data_vld) begin
display_data_r <= display_data;
end
end
reg dot;
reg [ 3:0 ] num;
always@( * ) begin
case( sel )
6'b111_110: begin
// num = display_data / 100000 % 10;
num = display_data_r[23 :20];
dot = 1;
end
6'b111_101: begin
// num = display_data / 10000 % 10;
num = display_data_r[19 : 16];
dot = 1;
end
6'b111_011: begin
// num = display_data / 1000 % 10;
num = display_data_r[15 : 12];
dot = 1;
end
6'b110_111: begin
// num = display_data / 100 % 10;
num = display_data_r[11 :8];
dot = 0;
end
6'b101_111: begin
//num = display_data / 10 % 10;
num = display_data_r[7 :4];
dot = 1;
end
6'b011_111: begin
//num = display_data % 10;
num = display_data_r[3 :0];
dot = 1;
end
default num = 4'hf;
endcase
end
always @ ( * ) begin
case( num )
4'd0: seg = {dot,ZERO}; // 匹配到后参考共阳极真值表
4'd1: seg = {dot,ONE};
4'd2: seg = {dot,TWO};
4'd3: seg = {dot,THREE};
4'd4: seg = {dot,FOUR};
4'd5: seg = {dot,FIVE};
4'd6: seg = {dot,SIX};
4'd7: seg = {dot,SEVEN};
4'd8: seg = {dot,EIGHT};
4'd9: seg = {dot,NINE};
default : seg = {1'b0,ZERO};
endcase
end
endmodule
数码管位选控制
该模块每20000ns刷新一次数码管。
module sel_drive(
input clk,
input rst_n,
output reg [5:0] sel
);
localparam state0 = 3'd0;
localparam state1 = 3'd1;
localparam state2 = 3'd2;
localparam state3 = 3'd3;
localparam state4 = 3'd4;
localparam state5 = 3'd5;
parameter MAX_NUM = 1_000;
reg [2:0] current_state;
reg [2:0] next_state;
reg [20:0] cnt; //时钟分频计数器
reg flag;
//计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
flag <= 1'b0;
cnt <= 0;
end
else if(cnt == 0)begin//一轮计数完毕
flag <= 1'b1;
cnt <= 1;
end
else begin
flag <= 1'b0;
cnt <= (cnt + 1'b1) % MAX_NUM;//循环+1
end
end
// 状态跳转
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
current_state <= state0;
end
else if(flag) begin
current_state <= next_state;
end
end
//状态判断
always @(*) begin
if(!rst_n) begin
next_state <= state0;
end
else if(flag) begin
case(current_state)
state0: begin
next_state <= state1;
end
state1: begin
next_state <= state2;
end
state2: begin
next_state <= state3;
end
state3: begin
next_state <= state4;
end
state4: begin
next_state <= state5;
end
state5: begin
next_state <= state0;
end
default:begin
next_state <= state0;
end
endcase
end
else begin
next_state <= next_state;
end
end
//状态输出
always@(current_state) begin
case (current_state)
state0: begin
sel <= 6'b011111;
end
state1: begin
sel <= 6'b101111;
end
state2: begin
sel <= 6'b110111;
end
state3: begin
sel <= 6'b111011;
end
state4: begin
sel <= 6'b111101;
end
state5: begin
sel <= 6'b111110;
end
default:begin
sel <= 6'b111111;
end
endcase
end
endmodule
数码管显示效果
顶层文件设计
由于数码管需要25M时钟,超声波测距需要1M时钟,通过PLL分频得到对应的时钟。
RTL视图
module distance_top (
input wire clk,
input wire rst_n,
input wire echo,
output wire trig,
output wire [ 5:0 ] sel,
output wire [ 7:0 ] seg,
output reg [ 3:0 ] led,
output wire beep,
input wire key,
output wire h_sync,
output wire v_sync,
output wire [ 4:0 ] rgb_r,
output wire [ 5:0 ] rgb_g,
output wire [ 4:0 ] rgb_b,
input wire rx_data,
output wire tx_data
);
wire clk_50 ;
wire clk_1 ;
wire clk_25 ;
wire [ 23:0 ] distance_data ;
wire data_out_vld ;
reg beep_vld ;
wire key_out ;
wire [ 15:0 ] rgb_data ;
wire [ 11:0 ] addr_h;
wire [ 11:0 ] addr_v;
pll pll_inst (
.areset ( ~rst_n ),
.inclk0 ( clk ),
.c0 ( clk_50 ),
.c1 ( clk_1 ),
.c2 ( clk_25 )
);
//vga
vga_dirve u_vga_dirve(
.clk ( clk_25 ),
.rst_n ( rst_n ),
.rgb_data ( rgb_data ),
.vga_clk ( vga_clk ),
.h_sync ( h_sync ),
.v_sync ( v_sync ),
.addr_h ( addr_h ),
.addr_v ( addr_v ),
.rgb_r ( rgb_r ),
.rgb_g ( rgb_g ),
.rgb_b ( rgb_b )
);
//vag数据
data_drive u_data_drive(
.clk (clk),
.vga_clk ( vga_clk ),
.rst_n ( rst_n ),
.addr_h ( addr_h ),
.addr_v ( addr_v ),
.data_vld ( data_out_vld ),
.distance_data ( distance_data ),
.rgb_data ( rgb_data )
);
//数码管
seg_drive u_seg_drive(
.clk ( clk ),
.rst_n ( rst_n ),
.data_vld ( data_out_vld ),
.display_data ( distance_data),
.sel ( sel ),
.seg ( seg )
);
sel_drive u_sel_drive(
.clk ( clk_50 ),
.rst_n ( rst_n ),
.sel ( sel )
);
//测距
distance_drive u_distance(
.clk ( clk ),
.clk_1 (clk_1),
.rst_n ( rst_n ),
.echo ( echo ),
.trig ( trig ),
.data_out_vld ( data_out_vld ),
.distance_data ( distance_data )
);
//串口
uart_drive u_uart_drive(
.clk ( clk ),
.rst_n ( rst_n ),
.distance_data ( distance_data ),
.data_vld ( data_out_vld ),
.rx_data ( rx_data ),
.tx_data ( tx_data )
);
//蜂鸣器
beep_dirve u_beep_dirve(
.clk ( clk ),
.rst_n ( rst_n ),
.beep_vld ( beep_vld ),
.data_vld ( data_out_vld ),
.distance_data ( distance_data ),
.beep ( beep )
);
//按键消抖
key_debounce#(.KEY_W ( 1 )) u_key_debounce(
.clk ( clk ),
.rst_n ( rst_n ),
.key_in ( key ),
.key_out ( key_out )
);
//控制蜂鸣器使能
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
beep_vld <= 0;
end
else if(key_out) begin
beep_vld <= ~beep_vld;
end
end
reg [ 27:0 ] cnt ;
// led
always @( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cnt <= 0;
end
else if ( cnt == 50_000_000 - 1 ) begin
cnt <= 0;
end
else begin
cnt <= cnt + 1;
end
end
always @( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
led <= 4'b0000;
end
else if ( cnt == 50_000_000 -1 )begin
led <= ~led;
end
else begin
led <= led;
end
end
endmodule //distance_top
总结
本次实验的综合性较强,结合了企业实训学过的蜂鸣器、数码管、模块,同时复习了上学期串口通信原理的知识,本次实验可以拓展通过VGA接口在显示屏上进行打点输出,有兴趣的读者可以进行实验。
参考连接:
https://blog.csdn.net/qq_43546203/article/details/125281386
https://blog.csdn.net/qq_43546203/article/details/125282050
https://blog.csdn.net/qq_45659777/article/details/124717655
https://blog.csdn.net/qq_47281915/article/details/125592938