一、說明
實(shí)現(xiàn)平臺(tái):Vivado2018.3
二、內(nèi)容
1. 使用按鍵KEY0和KEY_1分別控制LED0和LED1兩個(gè)LED燈的閃爍方式;
2. 當(dāng)沒有按鍵按下時(shí),兩個(gè)LED燈均不亮;
3. 當(dāng)按鍵KEY0按下后,LED0燈閃爍,當(dāng)按鍵KEY0再次按下后則LED1燈閃爍,如此循環(huán)往復(fù);
4. 當(dāng)按鍵KEY1按下后,LED0和LED1交替閃爍,當(dāng)按鍵KEY1再次按下后則LED0和LED1同時(shí)閃爍,如此循環(huán)往復(fù);
5.?在內(nèi)容3中若按鍵KEY1按下,則執(zhí)行內(nèi)容4操作;在內(nèi)容4中若按鍵KEY0按下,則執(zhí)行內(nèi)容3操作。
三、步驟
(1)設(shè)計(jì)要求
- ? ?時(shí)鐘頻率為50MHZ;
- ? ?按鍵KEY0和KEY1;
- ? ?LED燈LED0和LED1。
(2)設(shè)計(jì)思路
本實(shí)驗(yàn)設(shè)計(jì)可分為四個(gè)模塊:
- ? ?計(jì)數(shù)器模塊:用于計(jì)數(shù)LED燈閃爍間隔;
- ?? LED閃爍狀態(tài)控制模塊:用于改變LED燈狀態(tài);
- ? 按鍵邊緣檢測(cè)模塊:用于檢測(cè)按鍵按下的狀態(tài);
- ? 按鍵控制閃爍實(shí)現(xiàn)模塊:使用兩個(gè)狀態(tài)機(jī),分別實(shí)現(xiàn)KEY0和KEY1的LED燈閃爍控制。
(3)具體實(shí)現(xiàn)
0.相關(guān)信號(hào)聲明:
module key_led(
input sys_clk,
input sys_rst_n,
input [1:0] key,
output reg [1:0] led
);
reg [24:0] cnt;
reg led_ctrl;
reg [1:0] key_edg0; //邊緣檢測(cè)
reg [1:0] key_edg1;
reg [1:0] state_key0; //按鍵狀態(tài)
reg [1:0] state_key1;
wire [1:0] key_en; //控制小燈閃爍
1.?計(jì)數(shù)器模塊實(shí)現(xiàn):
其中cnt計(jì)滿為25_000_000,時(shí)鐘頻率為50MHZ,25_000_000/50_000_000 = 0.5s=500ms
//計(jì)數(shù)器
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
cnt <= 25'd0;
else if(cnt < 25'd25_000_000) //計(jì)數(shù)500ms
// else if(cnt < 25'd25) //仿真用
cnt <= cnt + 1'b1;
else
cnt <= 0;
end
2. LED閃爍狀態(tài)控制模塊:
//每隔500ms就更改LED的閃爍狀態(tài)
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
led_ctrl <= 1'b0;
else if(cnt == 25'd25_000_000)
// else if(cnt == 25'd25) //仿真用
led_ctrl <= ~led_ctrl;
end
3.按鍵邊緣檢測(cè)模塊:
其中使用該模塊的原因主要是實(shí)現(xiàn)按鍵僅按一下即實(shí)現(xiàn)相關(guān)操作的功能,而無(wú)需一直按住按鍵才能執(zhí)行相關(guān)操作。代碼中檢測(cè)上升沿或下降沿均可。
assign key_en[0] = (~key_edg0[0]) & key_edg1[0]; //按鍵0下降沿檢測(cè)
assign key_en[1] = (~key_edg0[1]) & key_edg1[1]; //按鍵1下降沿檢測(cè)
//PL_KEY邊緣檢測(cè)
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_edg0 <= 0;
key_edg1 <= 0;
end
else begin
key_edg0 <= key;
key_edg1 <= key_edg0;
end
end
4.按鍵控制閃爍實(shí)現(xiàn)模塊:
此處使用兩個(gè)狀態(tài)機(jī),狀態(tài)機(jī)1控制KEY0實(shí)現(xiàn)對(duì)應(yīng)的LED燈閃爍;狀態(tài)機(jī)2控制KEY1實(shí)現(xiàn)對(duì)應(yīng)的LED燈閃爍。
//兩個(gè)狀態(tài)機(jī),根據(jù)按鍵KEY0來(lái)控制LED的閃爍
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
state_key0 <= 2'd0;
state_key1 <= 2'd0;
led <= 0;
end
else begin
case(state_key0) //狀態(tài)機(jī)1
2'd0 : begin
led <= led; //默認(rèn)保持原狀態(tài)
state_key0 <= (key_en[0]) ? 2'd1:2'd0;
end
2'd1 : begin
led[0] <= (led_ctrl) ? 1'b1:1'b0; //LED0閃爍
led[1] <= 0; //LED1不亮
if (key_en[0])
state_key0 <= 2'd2; //切換到下一狀態(tài)
else if(key_en[1]) //若按鍵1按下,則返回狀態(tài)機(jī)2
state_key1 <= 2'd1;
else
state_key0 <= 2'd1;
end
2'd2 : begin
led[1] <= (led_ctrl) ? 1'b1:1'b0; //LED1閃爍
led[0] <= 0; //LED0不亮
if (key_en[0])
state_key0 <= 2'd1; //返回上一狀態(tài)
else if(key_en[1]) //若按鍵1按下,則返回狀態(tài)機(jī)2
state_key1 <= 2'd1;
else
state_key0 <= 2'd2;
end
default:state_key0 <= 2'd0;
endcase
case(state_key1) //狀態(tài)機(jī)2
2'd0 : begin
state_key1 <= (key_en[1]) ? 2'd1:2'd0;
end
2'd1 : begin
led <= (led_ctrl) ? 2'b01:2'b10; //LED0和1交替閃爍
state_key1 <= (key_en[1]) ? 2'd2:2'd1; //切換到下一狀態(tài)
if (key_en[1])
state_key1 <= 2'd2; //切換到下一狀態(tài)
else if(key_en[0])begin //若按鍵0按下,則返回狀態(tài)機(jī)1
state_key0 <= 2'd1;
state_key1 <= 2'd0;
end
else
state_key1 <= 2'd1;
end
2'd2 : begin
led <= (led_ctrl) ? 2'b11:2'b00; //LED0和1同時(shí)閃爍
if (key_en[1])
state_key1 <= 2'd1; //切換到上一狀態(tài)
else if(key_en[0])begin //若按鍵0按下,則返回狀態(tài)機(jī)1
state_key0 <= 2'd1;
state_key1 <= 2'd0;
end
else
state_key1 <= 2'd2;
end
default:state_key1 <= 2'd0;
endcase
end
end
5.testbenc仿真測(cè)試程序
此處我們模擬按鍵操作,分別按一下KEY0,再按一下KEY0,查看是否實(shí)現(xiàn)了LED0和LED1的切換閃爍操作;之后按KEY1,再按一下KEY1,查看時(shí)候?qū)崿F(xiàn)了兩個(gè)LED燈的交替以及同時(shí)閃爍;最后再仿真按下兩次KEY0操作,查看是否實(shí)現(xiàn)了按鍵切換的操作。
其中為了防止仿真時(shí)間過長(zhǎng),主程序文件的cnt計(jì)數(shù)可以改的小一些,方便仿真。
`timescale 1ns / 1ns
module tb_key_led();
//輸入
reg sys_clk;
reg sys_rst_n;
reg [1:0] key;
//輸出
wire [1:0] led;
//信號(hào)初始化
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
key = 2'b11;
#200
sys_rst_n = 1'b1;
#200
key = 2'b10;
#100
key = 2'b11;
#2000
key = 2'b10;
#100
key = 2'b11;
#2000
key = 2'b01;
#100
key = 2'b11;
#2000
key = 2'b01;
#100
key = 2'b11;
#2000
key = 2'b10;
#100
key = 2'b11;
#2000
key = 2'b10;
#100
key = 2'b11;
#2000
$finish;
end
//生成時(shí)鐘
always #10 sys_clk = ~sys_clk;
//例化待測(cè)設(shè)計(jì)
key_led u_key_led(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key (key),
.led (led)
);
endmodule
四、仿真結(jié)果
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-817925.html
?從仿真圖可以看出,左邊白框部分實(shí)現(xiàn)了LED0(01,00,01,00)和LED1(00,10,00,10)的閃爍功能;中間框部分則實(shí)現(xiàn)了LED等交替閃爍和同時(shí)閃爍的功能;最后右邊藍(lán)框部分,其實(shí)現(xiàn)功能和白框部分一樣,實(shí)現(xiàn)了按鍵的切換實(shí)現(xiàn)LED燈閃爍功能,表明實(shí)驗(yàn)成功。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-817925.html
五、完整程序代碼
//`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/06/20 08:28:10
// Design Name:
// Module Name: key_led
// Project Name:
// Target Devices:
// Tool Versions:
// Description:使用PL_KEY0和PL_KEY_1來(lái)控制底板上的PL_LED0和PL_LED1兩個(gè)LED的閃爍方式。
// 沒有按鍵按下時(shí),兩個(gè)LED不亮,若按鍵0按下,則LED0閃爍,若再次按下則LED1閃爍,再按
// 下則LED0閃爍,如此交替;若1按下,則兩個(gè)LED交替閃爍,再次按下則兩個(gè)LED同時(shí)閃爍,如此反復(fù)。
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module key_led(
input sys_clk,
input sys_rst_n,
input [1:0] key,
output reg [1:0] led
);
reg [24:0] cnt;
reg led_ctrl;
reg [1:0] key_edg0; //邊緣檢測(cè)
reg [1:0] key_edg1;
reg [1:0] state_key0; //按鍵狀態(tài)
reg [1:0] state_key1;
wire [1:0] key_en; //控制小燈閃爍
//計(jì)數(shù)器
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
cnt <= 25'd0;
else if(cnt < 25'd25_000_000) //計(jì)數(shù)500ms
// else if(cnt < 25'd25) //仿真用
cnt <= cnt + 1'b1;
else
cnt <= 0;
end
//每隔500ms就更改LED的閃爍狀態(tài)
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
led_ctrl <= 1'b0;
else if(cnt == 25'd25_000_000)
// else if(cnt == 25'd25) //仿真用
led_ctrl <= ~led_ctrl;
end
assign key_en[0] = (~key_edg0[0]) & key_edg1[0]; //按鍵0下降沿檢測(cè)
assign key_en[1] = (~key_edg0[1]) & key_edg1[1]; //按鍵1下降沿檢測(cè)
//PL_KEY邊緣檢測(cè)
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_edg0 <= 0;
key_edg1 <= 0;
end
else begin
key_edg0 <= key;
key_edg1 <= key_edg0;
end
end
//兩個(gè)狀態(tài)機(jī),根據(jù)按鍵KEY0來(lái)控制LED的閃爍
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
state_key0 <= 2'd0;
state_key1 <= 2'd0;
led <= 0;
end
else begin
case(state_key0) //狀態(tài)機(jī)1
2'd0 : begin
led <= led; //默認(rèn)保持原狀態(tài)
state_key0 <= (key_en[0]) ? 2'd1:2'd0;
end
2'd1 : begin
led[0] <= (led_ctrl) ? 1'b1:1'b0; //LED0閃爍
led[1] <= 0; //LED1不亮
if (key_en[0])
state_key0 <= 2'd2; //切換到下一狀態(tài)
else if(key_en[1]) //若按鍵1按下,則返回狀態(tài)機(jī)2
state_key1 <= 2'd1;
else
state_key0 <= 2'd1;
end
2'd2 : begin
led[1] <= (led_ctrl) ? 1'b1:1'b0; //LED1閃爍
led[0] <= 0; //LED0不亮
if (key_en[0])
state_key0 <= 2'd1; //返回上一狀態(tài)
else if(key_en[1]) //若按鍵1按下,則返回狀態(tài)機(jī)2
state_key1 <= 2'd1;
else
state_key0 <= 2'd2;
end
default:state_key0 <= 2'd0;
endcase
case(state_key1) //狀態(tài)機(jī)2
2'd0 : begin
state_key1 <= (key_en[1]) ? 2'd1:2'd0;
end
2'd1 : begin
led <= (led_ctrl) ? 2'b01:2'b10; //LED0和1交替閃爍
state_key1 <= (key_en[1]) ? 2'd2:2'd1; //切換到下一狀態(tài)
if (key_en[1])
state_key1 <= 2'd2; //切換到下一狀態(tài)
else if(key_en[0])begin //若按鍵0按下,則返回狀態(tài)機(jī)1
state_key0 <= 2'd1;
state_key1 <= 2'd0;
end
else
state_key1 <= 2'd1;
end
2'd2 : begin
led <= (led_ctrl) ? 2'b11:2'b00; //LED0和1同時(shí)閃爍
if (key_en[1])
state_key1 <= 2'd1; //切換到上一狀態(tài)
else if(key_en[0])begin //若按鍵0按下,則返回狀態(tài)機(jī)1
state_key0 <= 2'd1;
state_key1 <= 2'd0;
end
else
state_key1 <= 2'd2;
end
default:state_key1 <= 2'd0;
endcase
end
end
endmodule
到了這里,關(guān)于LED燈閃爍拓展實(shí)驗(yàn)——單按鍵控制LED燈不同閃爍方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!