一.实验任务
操作 | 功能 |
---|---|
按下KEY[0] | 自右向左流水灯 |
按下KEY[1] | 自左向右流水灯 |
按下KEY[2] | LED灯持续闪烁 |
按下KEY[3] | LED灯全亮 |
- 本次不涉及按键消抖,按下按键时需要持续按住,松开按键则效果消失。
二.原理
2.1按键种类
- 开关分为两种:轻触式按键和自锁式按键。轻触式按键按下施加压力则开关打开,松开时对按键撤销压力则自动断开。自锁式按键按压一次则开关打开,松开不会断开,需要再按压一次开关断开。开发板上的电源按键就是典型的自锁式按键。本次实验中用到的是轻触式按键。
2.2按键原理
-
按键原理图如下
-
由图分析可得,按下按键时KEY的值为0
三.设计思路
- 先设计0.5s计数器,自增1,每由0计至24_999_999清零;由于共4个灯,所以需要设计状态计数,共4个状态,状态自增1的条件应为计数器计满。再设计LED模式选择,以key[] == 0为条件,用case语句判别状态的取值,并且显示每个状态的输出应该如何。
四.代码
module key_led (
input clk,
input rst_n,
input wire [3:0] key,
output reg [3:0] led
);
parameter MAX = 26'd25_000_000;
reg [26:0] cnt;
reg [1:0] state;
//0.5s计数器
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin//初始计数为0
cnt <= 26'd0;
end
else if (cnt == MAX - 1'd1) begin//计满归零
cnt <= 1'd0;
end
else begin
cnt <= cnt + 1'd1;//剩余状况自增1
end
end
//状态
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= 2'd0;//初始状态为0
end
else if (cnt == MAX - 1'd1) begin//计数器计满一次0.5s则状态自增1
state <= state + 2'd1;
end
else begin
state = state;//其余情况不变
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
led <= 4'b0000;//led全灭
end
else if(key[0] == 0)begin//右边第1个按键按下,自右向左流水灯
case(state)
2'd0: led <= 4'b0001;
2'd1: led <= 4'b0010;
2'd2: led <= 4'b0100;
2'd3: led <= 4'b1000;
default:;
endcase
end
else if(key[1] == 0)begin//右边第2个按键按下,自左向右流水灯
case(state)
2'd0: led <= 4'b1000;
2'd1: led <= 4'b0100;
2'd2: led <= 4'b0010;
2'd3: led <= 4'b0001;
default:;
endcase
end
else if(key[2] == 0)begin//右边第3个按键按下,led灯闪烁
case(state)
2'd0: led <= 4'b1111;
2'd1: led <= 4'b0000;
2'd2: led <= 4'b1111;
2'd3: led <= 4'b0000;
default:;
endcase
end
else if(key[3] == 0)begin//右边第4个按键按下,全亮
led <= 4'b1111;
end
else begin
led <= 4'b0000;
end
end
endmodule
五.引脚分配
元件 | 管脚 |
---|---|
clk | E1 |
LED0 | G15 |
LED1 | F16 |
LED2 | F15 |
LED3 | D16 |
KEY0 | E15 |
KEY1 | E16 |
KEY2 | M16 |
KEY3 | M15 |