8个LED闪烁两次→向右流水灯→向左跑马灯→两边向内流水→如此循环往复...
2)实际效果如视频所示:
3)程序代码如下,还未进一步精简:
//LED花样彩灯
//holdmyhand 10月28日 16:09:43
module led_hy(sys_clk, sys_rstn, led);
input sys_clk;
input sys_rstn;
output [7:0] led;
reg [7:0] led;
reg [31:0] delay_cnt; //延时计数器
reg [31:0] counter; //计数变量
reg [1:0] current_state, next_state; //LED当前状态,下一状态
reg [3:0] led_h, led_l;
parameter ALL_ON=8'b00000000, ALL_OFF=8'b11111111; //参数定义 符号常量
parameter S0=2'b00, S1=2'b01, S2=2'b10, S3=2'b11;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
delay_cnt <= 32'd0;
else
begin
if(delay_cnt==32'd24999999)
delay_cnt <= 32'd0;
else
delay_cnt <= delay_cnt + 1'b1;
end
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
begin
led <= ALL_OFF;
counter <= 32'd0;
current_state <= S0;
led_h <= 4'b0111;
led_l <= 4'b1110;
end
else
begin
if(delay_cnt==32'd24999999)
begin
case(current_state)
S0:begin
counter <= counter + 1'b1;
if(counter<32'd3)
led <= ~led;
else
begin
counter <= 32'd0;
led <= 8'b01111111;
next_state <= S1;
end
end
S1:begin
led <= led >> 1; //右移
if(led==ALL_ON)
begin
led <= 8'b11111110;
next_state <= S2;
end
end
S2:begin
led <= {led[6:0], led[7]}; //移位寄存器左移一位操作
if(led==8'b01111111)
begin
led <= {led_h, led_l};
next_state <= S3;
end
end
S3:begin
led_h <= led_h >> 1;
led_l <= led_l << 1;
led <= {led_h, led_l};
if(led==ALL_ON)
begin
led_h <= 4'b0111;
led_l <= 4'b1110;
led <= ALL_OFF;
next_state <= S0;
end
end
default:led <= led;
endcase
end
else
led <= led;
current_state <= next_state;
end
end
endmodule
1) 数码管静态显示、动态显示及模为60的计数器显示效果如下:
2) 模为60的计数器,功能实现代码如下:
module modulo_60(sys_clk, sys_rstn, sm_seg, sm_bit);
//输入输出信号
input sys_clk;
input sys_rstn;
output [7:0] sm_seg;
output [7:0] sm_bit;
//寄存器定义
reg [7:0] sm_seg;
reg [7:0] sm_bit;
reg [3:0] tens; //十位数
reg [3:0] units; //个位数
reg [3:0] dataout_buf;
reg [31:0] scan_cnt; //扫描延时计数器
reg [31:0] delay_cnt; //延时计数器
reg disp_dat;
//逻辑部分
always @(posedge sys_clk or negedge sys_rstn)//动态扫描延时
begin
if(!sys_rstn)
scan_cnt <= 32'd0;
else
begin
if(scan_cnt==32'd49999)
scan_cnt <= 32'd0;
else
scan_cnt <= scan_cnt + 1'b1;
end
end
always @(posedge sys_clk or negedge sys_rstn)//模计数延时
begin
if(!sys_rstn)
delay_cnt <= 32'd0;
else
begin
if(delay_cnt==32'd49999999)
delay_cnt <= 32'd0;
else
delay_cnt <= delay_cnt + 1'd1;
end
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
disp_dat <= 1'b0;
else
begin
if(scan_cnt==32'd49999)
disp_dat <= disp_dat + 1'b1;
else
disp_dat <= disp_dat;
end
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
begin
units = 4'h0;
tens = 4'h0;
end
else
begin
if(delay_cnt==32'd49999999)
begin
units = units + 1'b1;
if(units==4'ha)
begin
units = 4'h0;
tens = tens + 1'b1;
if(tens==4'h6)
tens = 4'h0;
end
end
else
begin
units = units;
tens = tens;
end
end
end
always @(disp_dat)
begin
case(disp_dat)
1'b0: sm_bit = 8'b1111_1110;
1'b1: sm_bit = 8'b1111_1101;
default:
sm_bit = 8'b1111_1110;
endcase
end
always @(sm_bit)
begin
case(sm_bit)
8'b1111_1110: dataout_buf = units;
8'b1111_1101: dataout_buf = tens;
default:dataout_buf = 4'ha;
endcase
end
always @(dataout_buf)
begin
case(dataout_buf)
4'h0: sm_seg = 8'hc0;
4'h1: sm_seg = 8'hf9;
4'h2: sm_seg = 8'ha4;
4'h3: sm_seg = 8'hb0;
4'h4: sm_seg = 8'h99;
4'h5: sm_seg = 8'h92;
4'h6: sm_seg = 8'h82;
4'h7: sm_seg = 8'hf8;
4'h8: sm_seg = 8'h80;
4'h9: sm_seg = 8'h90;
4'ha: sm_seg = 8'h88;
default:
sm_seg = 8'hc0;
endcase
end
endmodule
5.8课后作业
按键消抖控制1位数码管循环显示0-9,代码如下:
module key_dt(sys_clk,
sys_rstn,
key_in,
sm_seg,
sm_bit);
input sys_clk;
input sys_rstn;
input key_in;
output [7:0] sm_seg; //段码
output [7:0] sm_bit; //位码
reg [7:0] sm_seg;
wire [7:0] sm_bit;
reg [3:0] disp_dat; //显示数据寄存器
reg [19:0] delay_cnt;
wire key_scan;
wire key_low;
reg key_samp;
reg key_samp_r;
reg key_rst;
reg key_rst_r;
//按键脉冲边沿检测
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_samp <= 1'b1;
else
key_samp <= key_in;
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_samp_r <= 1'b1;
else
key_samp_r <= key_samp;
end
assign key_scan = key_samp_r & (~key_samp);
//20ms延时,再次检测
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
delay_cnt <= 20'h0;
else if(key_scan)
delay_cnt <= 20'h0;
else
delay_cnt <= delay_cnt + 1'b1;
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_rst <= 1'b1;
else if(delay_cnt==20'hfffff)
key_rst <= key_in;
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
key_rst_r <= 1'b1;
else
key_rst_r <= key_rst;
end
assign key_low = key_rst_r & (~key_rst);
//按键控制1位数码管循环显示0-9
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
disp_dat <= 4'd0;
else if(key_low)
begin
disp_dat <= disp_dat + 1'b1;
if(disp_dat==4'h9)
disp_dat <= 4'd0;
end
else
disp_dat <= disp_dat;
end
always @(disp_dat)
begin
case(disp_dat)
4'h0: sm_seg = 8'hc0;
4'h1: sm_seg = 8'hf9;
4'h2: sm_seg = 8'ha4;
4'h3: sm_seg = 8'hb0;
4'h4: sm_seg = 8'h99;
4'h5: sm_seg = 8'h92;
4'h6: sm_seg = 8'h82;
4'h7: sm_seg = 8'hf8;
4'h8: sm_seg = 8'h80;
4'h9: sm_seg = 8'h90;
endcase
end
assign sm_bit = 8'b0111_1111;
endmodule
回复
有奖活动 | |
---|---|
【有奖活动——B站互动赢积分】活动开启啦! | |
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |