前言
因工作版本要求,FPGA板Verilog语言开发软件改为Quartus_18_0,本次项目实现根据不同输入状态下要求显示的数字,依据74LV164D移位芯片的原理,控制2位8段共阳数码管(A-3D2SR)的显示。
一、代码组成
1.数码管交替显示代码
2.74LV164D芯片驱动代码
3.集成代码
二、代码需注意点
1.交替显示
//数码管扫描时钟生成模块
reg [1:0] scan_counter; // 用于在两个数码管之间切换的计数器
// 数码管扫描时钟生成模块
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
scan_counter <= 2'b01;
SEGLED_en1 <= 1'b1; //en_1为0时,数码管1使能,反之,不使能
SEGLED_en2 <= 1'b0; //en_2为0时,数码管1使能,反之,不使能
SEGLED_DP <= 1'b0; //当为0时数码管点使能,当为1时数码管点不使能
end else if (div_cnt == MCNT) begin
if (scan_counter == 2'b10)
scan_counter <= 2'b01;
else
scan_counter <= scan_counter << 1;
SEGLED_en1 <= ~scan_counter[0];
SEGLED_en2 <= ~scan_counter[1];
end
end
// 选择不同数码管
always @(*) begin
case (scan_counter)
2'b10: data_temp = data[7:4]; //将低位赋值给第1个数码管
2'b01: data_temp = data[3:0]; //将高位赋值给第2个数码管
default:data_temp = 4'b1111; // 无效状态,保持为0或其他安全值
endcase
end
2.74LV164D芯片驱动代码需注意问题
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
// 异步复位逻辑
prev_SEG <= 8'b0;
bit_cnt <= 0;
shift_active <= 0;
SEGLED_CLK <= 0; // 通常在复位时禁用时钟
end else begin
// 同步逻辑
if (SEG != prev_SEG) begin
// SEG变化时启动移位
prev_SEG <= SEG;
bit_cnt <= 0;
shift_active <= 1;
end
// 如果正在进行移位且未完成,则继续移位
if (shift_active) begin
if (div_cnt == MCNT / 2) begin // 在分频器的一半时切换
SEGLED_CLK <= ~SEGLED_CLK;
if (SEGLED_CLK) begin // 只在时钟上升沿发送数据
if (bit_cnt < 8) begin
SEGLED_Data <= SEG[7 - bit_cnt];
bit_cnt <= bit_cnt + 1;
end else begin
shift_active <= 0; // 所有位都已移位,停止移位
end
end
end
end
end
end
总结
在做此项目时,多次出现数码管鬼影的现象,其原因为驱动部分没有给限制条件,即驱动部分应如上方驱动代码加入:只有前一个数值与本次数值不同时,移位寄存器才会进行1次8位的移位操作。