
1. 盘古PGX-Lite 7K开发板硬件概览紫光同创盘古PGX-Lite 7K开发板型号PGC7KD-6IMBG256是一款面向FPGA初学者的高性价比开发平台。作为国产FPGA的重要代表该板卡搭载紫光同创Compa系列FPGA芯片采用256引脚BGA封装核心资源包括7K逻辑单元约等效于Xilinx Artix-7系列的7K规模。开发板标配的外设接口中最引人注目的是两组4位8段共阳数码管这也是本实验的核心操作对象。开发板的数码管模块采用典型的动态扫描驱动设计每组数码管包含4位独立的8段显示单元含小数点共阳极端通过PNP三极管阵列驱动段选信号通过74HC595移位寄存器扩展扫描频率建议设置在100Hz-1kHz范围内实际测量中发现当扫描频率低于60Hz时会出现肉眼可见的闪烁而高于2kHz会导致三极管开关损耗明显增加。经过多次测试250Hz是最佳平衡点。2. 动态显示原理深度解析2.1 动态扫描的本质动态显示技术的核心是视觉暂留效应Persistence of Vision。人眼在光源消失后约0.1秒内仍保留视觉印象利用这一特性通过快速轮流点亮多个数码管只要刷新速度足够快人眼就会认为所有数码管在持续发光。具体到本开发板每个数码管的相同段a-g、dp并联连接位选信号通过三极管控制公共阳极在1ms时间片内先关闭所有位选通过595移位寄存器输出当前位的段码打开对应位选三极管循环执行4位数码管的上述操作2.2 硬件驱动电路详解开发板采用的典型驱动方案包含三个关键部件74HC595移位寄存器将串行数据转换为8位并行输出节省FPGA IO资源数据引脚SDI串行数据输入控制引脚SCLK移位时钟、RCLK锁存时钟PNP三极管阵列作为大电流开关驱动共阳极型号SS8550最大500mA集电极电流基极电阻选用2.2kΩ限制驱动电流限流电阻网络段选线路串联100Ω电阻实测单段电流约8mA时亮度适中// 典型的三极管驱动电路Verilog描述 assign digit_en[3:0] ~{4{!en}} sel[3:0]; // 位选使能信号 always (posedge clk) begin if(shift_en) begin shreg {shreg[6:0], sdi}; // 移位寄存器 end end3. FPGA工程创建与配置3.1 PDS开发环境搭建软件安装下载PDS Lite最新版本当前为v3.5.1安装时勾选PGC7K器件支持包安装USB-JTAG驱动需连接开发板后自动识别工程创建步骤create_project -name led_display -path ./prj set_device -name PGC7KD-6IMBG256 -speed -6 add_file -type verilog ./src/top.v add_file -type cst ./constraint/io.cst引脚约束文件关键配置# 数码管段选信号通过595驱动 define_attribute PIN_12 SDI define_attribute PIN_23 SCLK define_attribute PIN_24 RCLK # 位选信号 define_attribute PIN_45 DIGIT_EN[0] define_attribute PIN_46 DIGIT_EN[1] define_attribute PIN_47 DIGIT_EN[2] define_attribute PIN_48 DIGIT_EN[3]3.2 时钟系统设计开发板提供50MHz主时钟需要通过DCM数字时钟管理器分频得到扫描时钟// 250Hz扫描时钟生成50MHz/200000 reg [17:0] div_cnt; always (posedge clk_50m) begin if(div_cnt 199999) begin div_cnt 0; scan_clk ~scan_clk; end else begin div_cnt div_cnt 1; end end实际调试中发现直接使用计数器分频会产生时钟偏移。更稳定的做法是调用PDS内置的CLKDIV原语CLKDIV #(.DIV(200000)) u_clkdiv (.CLKIN(clk_50m), .CLKOUT(scan_clk));4. Verilog核心代码实现4.1 顶层模块设计module top( input wire clk_50m, output wire sdi, output wire sclk, output wire rclk, output wire [3:0] digit_en ); // 扫描时钟生成 wire scan_clk; clk_div u_clkdiv(.clk_in(clk_50m), .clk_out(scan_clk)); // 显示数据缓冲 reg [15:0] disp_data 16h1234; // 默认显示1234 // 动态扫描控制器 display_scan u_scan( .clk(scan_clk), .data(disp_data), .sdi(sdi), .sclk(sclk), .rclk(rclk), .digit_en(digit_en) ); endmodule4.2 动态扫描状态机module display_scan( input wire clk, input wire [15:0] data, output reg sdi, output reg sclk, output reg rclk, output reg [3:0] digit_en ); // 数码管段码表共阳 parameter [7:0] SEG_TAB [0:15] { 8hC0, // 0 8hF9, // 1 8hA4, // 2 8hB0, // 3 8h99, // 4 8h92, // 5 8h82, // 6 8hF8, // 7 8h80, // 8 8h90, // 9 8h88, // A 8h83, // b 8hC6, // C 8hA1, // d 8h86, // E 8h8E // F }; // 状态寄存器 reg [1:0] state 0; reg [3:0] cnt 0; reg [7:0] shift_data; always (posedge clk) begin case(state) 0: begin // 准备阶段 digit_en 4b1111; // 关闭所有位选 rclk 0; shift_data SEG_TAB[data[cnt*4 : 4]]; // 获取当前位段码 state 1; end 1: begin // 移位阶段 sdi shift_data[7]; shift_data {shift_data[6:0], 1b0}; sclk 1; state 2; end 2: begin sclk 0; if(shift_data) begin // 移位完成 state 3; end else begin state 1; end end 3: begin // 锁存并显示 rclk 1; digit_en ~(1 cnt); // 使能当前位 cnt cnt 1; state 0; end endcase end endmodule5. 调试技巧与性能优化5.1 常见问题排查数码管显示暗淡检查段选限流电阻是否过大建议100Ω测量三极管导通压降正常应0.3V确认595输出驱动强度设置PDS中设为12mA显示错位或重影增加位切换时的消隐时间至少20us检查位选信号与段码更新的时序配合// 改进的消隐处理 always (posedge clk) begin if(state 0) digit_en 4b1111; // 提前关闭显示 // ...其余逻辑... end5.2 资源优化方案时间分片复用// 将扫描时钟提升到1kHz每个数码管显示时间缩短为250us // 同时利用空闲时间处理其他任务 always (posedge scan_clk) begin case(time_slot) 0: begin /* 数码管扫描 */ end 1: begin /* 按键扫描 */ end 2: begin /* 通信处理 */ end endcase end亮度均匀性校正// 因不同段LED导通压降不同需进行亮度补偿 wire [7:0] seg_adj SEG_TAB[data] 8h7F; // 去除小数点 assign seg_data { seg_adj[7], // dp seg_adj[6] | 1b0, // g seg_adj[5] | 1b1, // f seg_adj[4] | 1b0, // e seg_adj[3] | 1b1, // d seg_adj[2] | 1b0, // c seg_adj[1] | 1b1, // b seg_adj[0] | 1b0 // a };6. 功能扩展实践6.1 滚动显示实现通过添加显示缓冲区和定时刷新机制可实现文字滚动效果reg [31:0] disp_buf HELLO; reg [15:0] scroll_cnt; always (posedge clk_1khz) begin if(scroll_cnt 1000) begin // 每秒滚动1次 scroll_cnt 0; disp_buf {disp_buf[23:0], disp_buf[31:24]}; // 循环左移 end else begin scroll_cnt scroll_cnt 1; end disp_data disp_buf[31:16]; // 显示前4字符 end6.2 多级亮度调节利用PWM技术实现16级亮度控制reg [3:0] pwm_cnt; reg [3:0] brightness 15; // 默认最亮 always (posedge clk_50m) begin pwm_cnt pwm_cnt 1; end assign digit_en (pwm_cnt brightness) ? ~(1 cnt) : 4b1111;在调试动态显示系统时我发现三极管的开关特性对显示效果影响极大。某次使用非原装SS8550三极管时出现了明显的拖尾现象。后来用示波器捕获发现替换件的关断时间比原装件慢了约3us导致位切换时出现短暂的重叠导通。这个案例让我深刻理解到在动态扫描设计中每个元件的参数匹配都至关重要。