VHDL动态显示4位数码管电路
代码工程:https://github.com/Lxiangrui/VHDL
我这里的实验室通过拨码开关计数,然后通过数码管来显示,并没有对按键进行消抖处理。
一、动态数码管是什么?
实际上很多两个以上的数码管都是动态数码管,设计成这样的真正目的是为了节约硬件资源,使用少量的引脚就可以点亮多个数码管。
多位数码管的数据端口实际上只有8个口,所有数码管的数据口都是连接到一个口上面的,然后每个数码管还都会有一个片选端口,控制这位数码管的开关。
所以说,所有数码管都只能显示相同的数字,或者不显示。
多个数码管显示数字的时候,我们实际上是轮流点亮数码管(一个时刻内只有一个数码管是亮的),利用人眼的视觉暂留现象(也叫余辉效应),就可以做到看起来是所有数码管都同时亮了,这就是动态显示,也叫做动态扫描。
二、VHDL实现代码
1、实体部分
clk,每个FPGA板子不同的时钟源,需要查找对应的技术手册,我这里的是25MHZ,还是比较小的哈,我看网上一般都是50MHZ。
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ;
USE IEEE.STD_LOGIC_unsigned.ALL;--因为使用到了从Integer类型转换到STD_LOGIC_VECTER
ENTITY shumaguan4 is
PORT (
segcs : out STD_LOGIC_vector (3 DOWNTO 0); --四个数码管的片选信号,如果为0就打开
Q : BUFFER INTEGER RANGE 0 TO 9999; --显示的数字
seg : out STD_LOGIC_vector (7 DOWNTO 0); --具体某个数码管要显示的数字
key : in STD_LOGIC;
clk : in STD_LOGIC); --25Mhz,用于提供数码管刷新频率
END;
ARCHITECTURE FH1 OF shumaguan4 IS
SIGNAL num : INTEGER RANGE 0 TO 9;
SIGNAL cnt_200Hz: INTEGER RANGE 0 TO 249999;
SIGNAL segcs_SIFNAL : STD_LOGIC_vector (3 DOWNTO 0);
BEGIN
2、信号线部分
num是用来存放当前显示数码管的数字,cnt_200HZ是用来做200HZ的计数,segcs_SIFNAL是为了代替segcs定义的信号线(比较输出信号不能拿来做判断,只能拿来赋值)
SIGNAL num : INTEGER RANGE 0 TO 9;
SIGNAL cnt_200Hz: INTEGER RANGE 0 TO 249999;
SIGNAL segcs_SIFNAL : STD_LOGIC_vector (3 DOWNTO 0);
3、计数部分
CNT: PROCESS(key)
BEGIN
IF key'EVENT AND key = '1' THEN
IF Q<=9999 THEN Q<=Q+1 ;
ELSE Q<=0;
END IF;;
END IF;
END PROCESS CNT;
4、显示部分
因为我们切换显示数码管,这个切换的频率还是需要适当设置的,不能一直直接放到主循环里面一直高频率的执行,那样会浪费资源,但是频率
太低的话,切换不过来,达不到人眼的暂留效应,显示会不是很流畅。所以我们这里选择了200hz为切换频率。
FF: PROCESS(clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF cnt_200Hz<100000 THEN cnt_200Hz<=cnt_200Hz+1 ;
ELSE cnt_200Hz<=0;
END IF;
IF (cnt_200Hz<=25000) THEN segcs_SIFNAL <= "1110";
ELSIF ((25000<cnt_200Hz)AND(cnt_200Hz<=50000)) THEN segcs_SIFNAL <= "1101";
ELSIF ((50000<cnt_200Hz)AND(cnt_200Hz<=75000)) THEN segcs_SIFNAL <= "1011";
ELSE segcs_SIFNAL <= "0111";
END IF;
END IF;
END PROCESS FF;
我是废物,这个只是为了给自己一个总结哈,我还只是一个小菜鸡儿。