雾盈FPGA笔记之(二十)显示三位数字的通用数码管程序
本帖最后由 雾盈 于 2016-8-28 13:42 编辑显示三位数字的通用数码管程序
雾盈 2016-8-10
雾盈FPGA笔记汇总目录
我们先不讲数码管的原理,我们先说步骤,从步骤中把其中的原理都讲清楚。
为了让数码管显示,有哪些步骤?
第一步、数据转换
让十进制数字能够在数码管上显示出来 ,例如128
Ones = (data_In )% 10;
Ones =128 % 10=8
Tens =(data_In /10 )% 10;
Tens =128/10%10 = 2
Hundres = (data_in /100 ) % 10 ;
Hunders =128 /100 % 10 = 1
更多位数的十进制数字以此类推。
那我们可不可以总结出一个小公式,这样也算有了一个小算法啊对不对,
算了,想了一会儿发现,其实这个已经够简练了,再 整个算法就复杂了。= =
谁有简单的方式可以分享一下。
第二步、分频一个片选扫描时钟
因为选择让哪个数码管显示是由片选信号SEL 决定的。Sel是个三位位宽的38译码器。
000 表示 选中 第一个数码管
001 表示 选中 第二个数码管
011 表示 选中 第四个数码管
以此类推。
但是,你也看出来了,sel控制的信号一次只能选中一个数码管,为了让多位数码管同时显示,怎么办呢?
于是,我们要用到这个扫描时钟,这个时钟不能频率太高,太高扫描速度太快,你根本不能看到数码管显示。
也不能频率太低,太低的话,你看到的数码管就不是同时亮了,而是有间隔延迟的亮灭。
一般我们会根据经验选择1kHz - 10 kHz 的分频时钟驱动sel去扫描数码管。
第三步、数码管数据的查找表
数码管的原理图如下
一个数码管由8个led灯构成(包括小数点),让每个led 保持高电平或者低电平就可以显示不同的字母或数字。
这样就会有0-F 对应的显示查找表。代码如下:
case( seg_data )
0: seg = 8'hc0;
1: seg = 8'hf9;
2: seg = 8'ha4;
3: seg = 8'hb0;
4: seg = 8'h99;
5: seg = 8'h92;
6: seg = 8'h82;
7: seg = 8'hf8;
8: seg = 8'h80;
9: seg = 8'h90;
10: seg = 8'h88;
11: seg = 8'h83;
12: seg = 8'hc6;
13: seg = 8'ha1;
14: seg = 8'h86;
15: seg = 8'h8e;
endcase
到这里,数码管最核心的三个部分讲完了,其它就是根据不同的功能,增加不同的程序了。
后面贴上显示三位数的数码管通用程序。
//=====================================================================
// module name: smg
// function: project iic_rd
// create data: from 2016-8-5 10:04:16 to2016-8-10 17:48:14
// editor: miao
// note : reference the code of techer chen
// Tool versions: quartus 13.0
//=====================================================================
module smg(
//system signal
input clk , //50MHZ system clock
input rst_n ,
//external input
input data_in ,
// output signal
output reg sel , // CS signal
output reg seg // LS signal
);
//=========================================================================================================
//************************** Define parameter and internal signals *********************************
//=========================================================================================================
reg clk_10K ; // 10KHZ clock for sel
reg count ; //count for frequency division10KHZ
parameter CNT_MAX = 2500 - 1; // count 2500 times for 10KHZ
reg seg_data ;
reg ones ;
reg tens ;
reg hundreds ;
//=========================================================================================================
//********************************* frequency division 10KHZ for sel*********************************
//=========================================================================================================
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
clk_10K <= 1'b0;
end
elsebegin
if( count == CNT_MAX )
begin
count <= 1'b0 ;
clk_10K <= ~clk_10K ;
end
elsebegin
count <= count + 1'b1;
end
end
end
//=========================================================================================================
//********************************* data convert ***********************************
//=========================================================================================================
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
ones <= 4'd0 ;
tens <= 4'd0 ;
hundreds <= 4'd0 ;
end
elsebegin
ones <= data_in % 10;
tens <= (data_in / 10) % 10 ;
hundreds <= (data_in /100) % 10 ;
end
end
//=========================================================================================================
//********************************* smg code ***********************************
//=========================================================================================================
// cut out the last three of sel
always @ (posedge clk_10K or negedge rst_n)
begin
if(!rst_n)
begin
sel <= 3 ;
end
elsebegin
if( sel <= 5 )
sel <= sel + 1'b1 ;
else
sel <= 3 ;
end
end
// seg_data for display
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
seg_data <= 4'd0 ;
end
elsebegin
case( sel )
3:begin
seg_data <= hundreds ;
end
4:begin
seg_data <= tens ;
end
5:begin
seg_data <= ones ;
end
default: seg_data <= seg_data ;
endcase
end
end
// LUT for display
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
seg <= 8'hff;
d
elsebegin
case( seg_data )
0: seg = 8'hc0;
1: seg = 8'hf9;
2: seg = 8'ha4;
3: seg = 8'hb0;
4: seg = 8'h99;
5: seg = 8'h92;
6: seg = 8'h82;
7: seg = 8'hf8;
8: seg = 8'h80;
9: seg = 8'h90;
10: seg = 8'h88;
11: seg = 8'h83;
12: seg = 8'hc6;
13: seg = 8'ha1;
14: seg = 8'h86;
15: seg = 8'h8e;
endcase
end
end
endmodule
代码编辑器好难用 写的不错 值得分享 谢谢 楼主 谢谢分享 厉害 受教,好好努力,加油;; 支持。 雾盈FPGA笔记之(二十)显示三位数字的通用数码管程序
页:
[1]