【FPGA从0开始系列】在Quartus13.1下实现可调节奏的LED流水灯
1. 实验目标与硬件准备这次我们要在Quartus 13.1环境下用FPGA实现一个带速度调节功能的LED流水灯。相比基础流水灯实验这次增加了外部按键控制功能让LED流动速度可以实时调整。这个实验特别适合刚接触FPGA的朋友既能巩固Verilog基础语法又能学习人机交互设计。我用的是黑金AX4010开发板主控芯片EP4CE10F17C8N你需要准备安装好Quartus 13.1的电脑建议D盘新建英文路径文件夹存放工程USB-Blaster下载器开发板配套的电源线杜邦线用于连接按键引脚注意不同开发板的LED电路可能不同我的板子是共阴接法高电平点亮LED。记得先查看你的原理图确认电路结构。2. 工程创建与模块设计2.1 新建Quartus工程打开Quartus点击File→New Project Wizard工程路径选择之前创建的英文文件夹芯片型号选择EP4CE10F17C8N取消勾选Add Files我们后续手动添加2.2 设计关键模块这次需要两个核心模块分频计数器将50MHz系统时钟分频为可调节的低频信号按键检测识别外部按键动作并调整分频系数新建Verilog文件时建议使用有意义的命名比如led_flow_speed.v。我见过新手直接命名为test.v结果后期找文件时特别混乱。3. Verilog代码实现3.1 顶层模块设计module led_flow_speed ( input clk, // 50MHz系统时钟 input rst_n, // 复位信号低有效 input key_speed, // 速度调节按键 output reg [3:0] led // LED输出 ); // 参数定义 parameter FAST_SPEED 24_999_999; // 快节奏计数上限 parameter SLOW_SPEED 49_999_999; // 慢节奏计数上限 // 内部信号 reg [31:0] counter; reg [31:0] speed_set FAST_SPEED; // 默认快速 wire key_pressed;3.2 按键消抖模块机械按键会有抖动问题需要做消抖处理// 按键消抖逻辑20ms延时 reg [19:0] key_delay; always (posedge clk or negedge rst_n) begin if (!rst_n) begin key_delay 20d0; end else begin key_delay {key_delay[18:0], key_speed}; end end assign key_pressed (key_delay 20hFFFFF);3.3 速度调节逻辑通过按键切换两种速度模式always (posedge clk or negedge rst_n) begin if (!rst_n) begin speed_set FAST_SPEED; end else if (key_pressed) begin speed_set (speed_set FAST_SPEED) ? SLOW_SPEED : FAST_SPEED; end end3.4 LED流水控制always (posedge clk or negedge rst_n) begin if (!rst_n) begin counter 32d0; led 4b0001; end else begin if (counter speed_set) begin counter 32d0; led {led[2:0], led[3]}; // 循环左移 end else begin counter counter 1; end end end4. 引脚分配与下载4.1 引脚约束根据原理图分配引脚信号名引脚号说明clkE150MHz时钟输入rst_nM15复位按键key_speedP11速度调节按键led[0]N3LED0led[1]P3LED1led[2]M6LED2led[3]L7LED3在Pin Planner中分配完成后建议导出.qsf文件备份避免下次打开工程需要重新分配。4.2 程序下载编译工程Processing → Start Compilation连接USB-Blaster到JTAG口点击Programmer添加生成的.sof文件勾选Program/Configure后点击Start如果遇到驱动问题可以尝试右键我的电脑→管理→设备管理器更新USB-Blaster驱动换USB接口或重新插拔下载器5. 功能验证与调试技巧上电后你应该能看到LED默认快速流动约0.5秒切换一次按下按键后变为慢速约1秒切换一次再次按键恢复快速常见问题排查LED不亮检查引脚分配是否正确测量LED两端电压按键无反应用示波器检测按键信号是否正常传入FPGA速度异常在SignalTap中观察counter计数情况如果想增加更多速度档位可以修改代码// 增加中速档 parameter MID_SPEED 39_999_999; // 修改速度切换逻辑 always (posedge clk or negedge rst_n) begin if (!rst_n) begin speed_set FAST_SPEED; end else if (key_pressed) begin case(speed_set) FAST_SPEED: speed_set MID_SPEED; MID_SPEED: speed_set SLOW_SPEED; default: speed_set FAST_SPEED; endcase end end6. 进阶优化建议6.1 使用PLL精确分频直接计数分频会有误差可以调用Quartus的PLL IP核Tools → MegaWizard Plug-In Manager选择ALTPLL设置输入50MHz输出1Hz和2Hz两个时钟6.2 添加LED渐变效果通过PWM调节亮度实现呼吸灯效果reg [7:0] pwm_cnt; always (posedge clk) pwm_cnt pwm_cnt 1; assign led_out (led_reg (pwm_cnt 8d128));6.3 增加速度显示可以用数码管显示当前速度档位需要增加七段译码模块数码管扫描电路这个实验最让我印象深刻的是按键消抖的处理。刚开始做FPGA时我直接检测按键信号结果经常误触发。后来用移位寄存器实现消抖后稳定性大幅提升。建议大家在开发板上多尝试不同的消抖时间参数比如改成15ms或25ms观察实际效果差异。