今天继续昨天的流水灯实验,不过今天尝试加入按键来进行控制,通过按键来控制LED的显示效果。
1 实验内容
此次实验中我将使用芯路恒AC620开发板进行实验,通过开发板上的两个按键来控制4个LED灯。不同按键按下时,LED灯显示不同的效果。
2 硬件电路设计
图 2.1 按键电路原理图
如图所示,当按键未按下时,输出高电平,按键按下时,输出低电平。本次实验用到的管脚分配如下表所示:
端口名称
I/0
功能描述
对应管脚
Clk50M
input
模块的工作时钟,频率为50Mhz
PIN_E1
Rst_n
input
模块复位,低电平复位
PIN_E16
led[0]
output
低电平时LED亮
PIN_A2
led[1]
output
低电平时LED亮
PIN_B3
led[2]
output
低电平时LED亮
PIN_A4
led[3]
output
低电平时LED亮
PIN_A3
key[0]
input
按键输入
PIN_M16
key[1]
input
按键输入
PIN_E15
图2.2 按键控制LED实验管脚分配图
3 程序设计
在本次实验中,最终的实验结果是:1、当无按键按下时,4个LED灯全部点亮;2、按键key0按下时,LED灯显示从左至右的流水效果;3、按键key1按下时,LED灯显示从右至左的流水效果。LED灯流水效果时间间隔均为0.5s,因此同上一个实验一样,需要先定义一个0.5s的计数器,也要定义一个状态计数器。根据当前按键的状态来选择不同的LED灯显示效果,不同显示模式下LED灯的亮灭随状态计数器的改变而改变。下图为本次实验的系统框图:
图3.1 系统框图
按键控制LED灯模块代码如下:
module counter(
input Clk50M, //系统时钟
input Rst_n, //全局复位 低电平复位
input [1:0] key, //按键输入信号
output reg [3:0] led //led 输出
);
reg [24:0]cnt;//定义25位寄存器
reg [1:0]led_control;//定义LED控制状态方式
//计数器计数进程
always@(posedge Clk50M or negedge Rst_n)//对一组反复执行的活动进行建模
if(Rst_n == 1'b0)
cnt <= 25'b0;
else if(cnt == 25'd24_999_999)
cnt <= 25'b0;
else
cnt <= cnt + 1'b1;
//LED灯状态的选择
always@(posedge Clk50M or negedge Rst_n) begin
if(!Rst_n)
led_control <= 2'b00;
else if(cnt == 25'd24_999_999)
led_control = led_control + 1'b1;
else
led_control <= led_control;
end
//识别按键,切换显示模式
always@(posedge Clk50M or negedge Rst_n) begin
if(!Rst_n) begin
led <= 4'b0000;
end
else if(key[0] == 0) //从左至右流水显示
case (led_control)
2'b00 :led <= 4'b0111;
2'b01 :led <= 4'b1011;
2'b10 :led <= 4'b1101;
2'b11 :led <= 4'b1110;
default:led <= 4'b1111;
endcase
else if(key[1] == 0) //从右至左流水显示
case (led_control)
2'b00 :led <= 4'b1110;
2'b01 :led <= 4'b1101;
2'b10 :led <= 4'b1011;
2'b11 :led <= 4'b0111;
default:led <= 4'b1111;
endcase
else //无按键按下时,LED灯全亮
led <= 4'b0000;
end
endmodule
代码分析:
代码主要分为三大部分,首先采用计数器对系统时钟计数,当计数时间达0.5s时,计数器清零,同时使led_control在四个状态(00,01,10,11)内依次变化。接着利用case语句实现对按键状态的检测,当不同的按键按下时,led随着led_control的变化,被赋予不同的值。 啦啦啦。。。又完成了一个小实验,我将一直将FPGA这个系列的博客更新下去,让它成为我学习FPGA的一个记录。