FPGA学习(三)——LED流水灯
FPGA学习(三)——LED流水灯
文章目录
- FPGA学习(三)——LED流水灯
- 一、DE2-115时钟源
- 二、控制一个LED灯闪烁
- 1、代码实现
- 2、引脚配置
- 3、实现效果
- 三、控制6个LED灯流水灯
- 1、代码实现
- 2、引脚配置
- 3、实现效果
- 四、LED灯流水灯模块化代码
- 1、分频模块 (fenpin.v)
- 2、显示控制模块 (display.v)
- 3、顶层模块 (LedBlink.v)
一、DE2-115时钟源
DE2-115板子包含一个50MHz的石英晶体振荡器,通过一个时钟缓冲器产生3路抖动低的50MHz时钟信号送到FPGA的时钟输入引脚,如下图所示:
对应到DE2-115板子上的引脚分配为下图所示:
二、控制一个LED灯闪烁
1、代码实现
module led(
input clk, // 输入时钟信号,开发板晶振频率为50MHz
input rst_n, // 复位信号,低电平有效(下降沿触发复位)
output reg ld // 输出信号,连接到LED灯,高电平点亮
);
reg [25:0] cnt; // 26位寄存器,用于存储计数器值
// 计时器模块:在时钟上升沿或复位信号下降沿触发
always@(negedge rst_n or posedge clk) begin
if (!rst_n) begin
// 如果复位信号有效(低电平),则初始化计数器和LED状态
cnt <= 26'd0; // 初始化计数器为0
ld <= 1'b1; // 初始化LED灯为高电平(假设高电平点亮)
end else if (cnt == 26'd50_000_000 - 1) begin
// 当计数器达到50,000,000(即1秒)时,重置计数器并翻转LED状态
cnt <= 26'd0; // 重置计数器为0
ld <= ~ld; // 翻转LED状态(如果原来是高电平,则变为低电平,反之亦然)
end else begin
// 在其他情况下,继续增加计数器,并保持LED状态不变
cnt <= cnt + 26'd1; // 增加计数器
ld <= ld; // 保持LED状态不变
end
end
endmodule
2、引脚配置
3、实现效果
FPGA(三)
三、控制6个LED灯流水灯
1、代码实现
module LedBlink(
input wire clk, // 50MHz时钟输入
input wire rst_n, // 复位信号,低电平有效
input wire stop_n, //停止信号
output reg [5:0] led // 6个LED灯输出
);
reg [25:0] cnt; // 26位计数器,用于计数1秒周期
// 计数器模块
always @(posedge clk or negedge rst_n or negedge stop_n) begin // posedge是指clk的上升沿 negedge是指rst_n的下降沿
if (!rst_n) begin
cnt <= 26'd0; // 复位时,计数器从0开始计数
led <= 6'b000001; // 复位时,第一个LED亮
end
else if (!stop_n) begin
cnt <= cnt;
led <= led;
end
else if (cnt == 50_000_000 - 1) begin // 计数到50,000,000 - 1
cnt <= 26'd0; // 重置计数器
led <= {led[4:0], led[5]}; // 循环右移一位,保持流水灯效果
end
else begin
cnt <= cnt + 1; // 增加计数器
end
end
endmodule
2、引脚配置
3、实现效果
LED流水灯
四、LED灯流水灯模块化代码
1、分频模块 (fenpin.v)
用于将输入时钟分频至每秒触发一次的信号。
module fenpin (
input clk, // 输入时钟(如50MHz)
output reg tick // 每秒触发信号
);
parameter MAX_COUNT = 25_000_000; // 对于50MHz时钟,计数到25M得到1Hz输出
reg [24:0] count = 0;
always @(posedge clk) begin
if (count == MAX_COUNT - 1) begin
count <= 0;
tick <= ~tick; // 每秒翻转一次
end else begin
count <= count + 1;
end
end
endmodule
2、显示控制模块 (display.v)
控制6个LED依次亮起,实现跑马灯效果。
module display (
input clk, // 来自分频器的每秒脉冲
output reg [5:0] led // 控制6个LED的状态
);
reg [2:0] state = 0; // 状态机状态
always @(posedge clk) begin
state <= state + 1; // 每秒改变状态
case(state)
3'b000: led = 6'b000001; // 第1个LED亮
3'b001: led = 6'b000010; // 第2个LED亮
3'b010: led = 6'b000100; // 第3个LED亮
3'b011: led = 6'b001000; // 第4个LED亮
3'b100: led = 6'b010000; // 第5个LED亮
3'b101: led = 6'b100000; // 第6个LED亮
default: led = 6'b000001; // 默认回到第1个LED亮
endcase
end
endmodule
// 备注:根据输入信号,顺序点亮6个LED中的一个。
3、顶层模块 (LedBlink.v)
整合分频和显示控制模块。
module LedBlink (
input clk, // 输入时钟信号
output [5:0] led // 输出至6个LED
);
wire tick; // 连接分频器和显示控制器的信号
fenpin fenpin_use (
.clk(clk),
.tick(tick)
);
display display_use (
.clk(tick), // 使用分频后的信号作为显示控制器的时钟
.led(led)
);
// 备注:顶层模块连接分频器和显示控制器,实现完整的跑马灯功能。
endmodule