開拓者FPGA開發闆上有六個共陽極八段數位管,本實驗将完成數位管靜态顯示。
功能描述
控制六位數位管以0.5秒的頻率同時顯示0-F 16個數字。
分頻子產品
開發闆本身的時鐘頻率為50kHz,對應時鐘周期為20ns,而本實驗需要0.5s讓數字變化一次,是以需要對時鐘進行分頻,使其0.5s輸出一個脈沖信号flag。
module time_count(
input clk , // 時鐘信号
input rst_n , // 複位信号
output reg flag // 一個時鐘周期的脈沖信号
);
//parameter define
parameter MAX_NUM = 25000_000; // 計數器最大計數值
//reg define
reg [24:0] cnt; // 時鐘分頻計數器
//*****************************************************
//** main code
//*****************************************************
//計數器對時鐘計數,每計時到0.5s,輸出一個時鐘周期的脈沖信号
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
flag <= 1'b0;
cnt <= 24'b0;
end
else if(cnt < MAX_NUM - 1'b1) begin
cnt <= cnt +1'b1;
flag <= 1'b0;
end
else begin
cnt <= 24'b0;
flag <= 1'b1;
數位管靜态顯示子產品
首先需清楚兩個概念:
位選信号(sel)——控制哪個數位管顯示
段選信号(seg_led)–控制數位管顯示内容
數位管顯示具體數值可參考真值表:
共陽極二極管,常理來說應當0才是點亮,而這裡是相反的。
原因可以看下面的原理圖,輸入信号并不是給到二極管的負級,而是給到了三級管的基極,三極管在這裡起到開關的作用,是以相反。
子產品代碼:
module seg_led_static (
input clk , // 時鐘信号
input rst_n , // 複位信号(低有效)
input add_flag, // 數位管變化的通知信号
output reg [5:0] sel , // 數位管位選
output reg [7:0] seg_led // 數位管段選
);
//reg define
reg [3:0] num; // 數位管顯示的十六進制數
//*****************************************************
//** main code
//*****************************************************
//控制數位管位選信号(低電平有效),選中所有的數位管
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
sel <= 6'b111111;
else
sel <= 6'b000000;
end
//每次通知信号到達時,數位管顯示的十六進制數值加1
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
num <= 4'h0;
else if(add_flag) begin
if (num < 4'hf)
num <= num + 1'b1;
else
num <= 4'h0;
end
else
num <= num;
end
//根據數位管顯示的數值,控制段選信号
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
seg_led <= 8'b0;
else begin
case (num)
4'h0 : seg_led <= 8'b1100_0000;
4'h1 : seg_led <= 8'b1111_1001;
4'h2 : seg_led <= 8'b1010_0100;
4'h3 : seg_led <= 8'b1011_0000;
4'h4 : seg_led <= 8'b1001_1001;
4'h5 : seg_led <= 8'b1001_0010;
4'h6 : seg_led <= 8'b1000_0010;
4'h7 : seg_led <= 8'b1111_1000;
4'h8 : seg_led <= 8'b1000_0000;
4'h9 : seg_led <= 8'b1001_0000;
4'ha : seg_led <= 8'b1000_1000;
4'hb : seg_led <= 8'b1000_0011;
4'hc : seg_led <= 8'b1100_0110;
4'hd : seg_led <= 8'b1010_0001;
4'he : seg_led <= 8'b1000_0110;
4'hf : seg_led <= 8'b1000_1110;
default : seg_led <= 8'b1100_0000;
頂層子產品
module seg_led_static_top (
input sys_clk , // 系統時鐘
input sys_rst_n, // 系統複位信号(低有效)
output [5:0] sel , // 數位管位選
output [7:0] seg_led // 數位管段選
);
//parameter define
parameter TIME_SHOW = 25'd25000_000; // 數位管變化的時間間隔0.5s
//wire define
wire add_flag; // 數位管變化的通知信号
//*****************************************************
//** main code
//*****************************************************
//每隔0.5s産生一個時鐘周期的脈沖信号
time_count #(
.MAX_NUM (TIME_SHOW)
) u_time_count(
.clk (sys_clk ),
.rst_n (sys_rst_n),
.flag (add_flag )
);
//每當脈沖信号到達時,使數位管顯示的數值加1
seg_led_static u_seg_led_static (
.clk (sys_clk ),
.rst_n (sys_rst_n),
.add_flag (add_flag ),
.sel (sel ),
.seg_led (seg_led )
);