目录
简介:
由于一般的静态驱动操作虽然方便,但占用的 I/0 口较多,例如要驱动6 位 8 段数码管,以静态驱动方式让数码管各个位显示不同的数值,如“123456”,需要占用6 × 8 = 48个I/O 口,虽然对于 FPGA 这种 I/O 口较多的芯片而言,在资源允许的情况下可以使用,但一般不建议浪费宝贵的 I/O 口资源,尤其在 I/O 口资源紧张的情况下,所以对于多位数码管一般采用动态驱动方式使数码管显示数字。
为了更好的理解数码管动态驱动,我们首先了解下市面上常见的多位数码管的内部连接。以两位数码管为例,其内部连接如下图。由此图可知,两位 8 段数码管共 10 个引脚,每位数码管的阳极连接在一起,为共阳极数码管,每位数码管相同段的 led 的阴极连接在一起,这样当给第 10 和第 5 脚高电平,给第 3 脚低电平时,两个数码管的发光二极管 A 都点亮,对于此种数码管以静态方式驱动显然不可能显示像“18”这种个位与十位不同的数字。那么该如何显示数字“18”呢?
既然同时给第 10 和第 5 脚高电平不可行,那么是不是可以先给第 5 脚高电平,第 10 脚低电平,此时,让其显示数字“8”时,左边的数码管不显示,右边的数码管显示数字“8”;然后给第 10 脚高电平,第 5脚低电平,此时,让其显示数字“1”时,左边的数码管显示数字“1”,右边的数码管不显示,这样就可以显示数字“18”了。但有一个问题,多长时间切换显示的数码管呢,时间如果太长就只能看到数字―8”或数字“1”了,时间太短呢,结果是显示不清晰而且显示亮度不够。由于人眼的视觉暂留(人眼在观察景物时,光信号传人大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称“后像”,视觉的这一现象则被称为“视觉暂留”)及发光二极管的余辉效应(当停止向发光二极管供电时,发光二极管亮度仍能维持一段时间),每位数码管的点亮时间为 1~2ms 时,显示效果能满足使用需要。数码管的这种驱动方式称为数码管的动态驱动,实际上就是分时轮流控制不同数码管的显示。
程序设计:
library ieee;use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity seg is
port(
clk: in std_logic;
rst_n:in std_logic;
ids_data: in std_logic_vector (15 downto 0);
seg_duan: out std_logic_vector (7 downto 0);
seg_wei: out std_logic_vector (5 downto 0)
);
end seg;
architecture behav of seg is
constant num0:std_logic_vector(7 downto 0) := x"c0";
constant num1:std_logic_vector(7 downto 0) := x"f9";
constant num2:std_logic_vector(7 downto 0) := x"a4";
constant num3:std_logic_vector(7 downto 0):= x"b0";
constant num4:std_logic_vector(7 downto 0) := x"99";
constant num5:std_logic_vector(7 downto 0) := x"92";
constant num6:std_logic_vector(7 downto 0):= x"82";
constant num7:std_logic_vector(7 downto 0) := x"f8";
constant num8:std_logic_vector(7 downto 0) := x"80";
constant num9:std_logic_vector(7 downto 0) := x"90";
constant num00:std_logic_vector(7 downto 0) := x"40";
constant num11:std_logic_vector(7 downto 0) := x"79";
constant num22:std_logic_vector(7 downto 0) := x"24";
constant num33:std_logic_vector(7 downto 0) := x"30";
constant num44:std_logic_vector(7 downto 0) := x"19";
constant num55:std_logic_vector(7 downto 0) := x"12";
constant num66:std_logic_vector(7 downto 0) := x"02";
constant num77:std_logic_vector(7 downto 0) := x"78";
constant num88:std_logic_vector(7 downto 0) := x"00";
constant num99:std_logic_vector(7 downto 0) := x"10";
constant numa:std_logic_vector(7 downto 0) := x"88";
constant numb:std_logic_vector(7 downto 0) := x"83";
constant numc:std_logic_vector(7 downto 0):= x"c6";
constant numd:std_logic_vector(7 downto 0) := x"a1";
constant nume:std_logic_vector(7 downto 0) := x"86";
constant numf:std_logic_vector(7 downto 0) := x"8e";
constant we0:std_logic_vector(5 downto 0) := "111110";
constant we1:std_logic_vector(5 downto 0) := "111101";
constant we2:std_logic_vector(5 downto 0) := "111011";
constant we3:std_logic_vector(5 downto 0) := "011111";
constant we:std_logic_vector(5 downto 0) := "111111";
signal a:integer range 0 to 100 :=0;
signal b:integer range 0 to 100 :=0;
signal c:integer range 0 to 100 :=0;
begin
process(rst_n,clk,ids_data)
variable cnt_4 : std_logic_vector (9 downto 0);
variable seg_num : std_logic_vector (3 downto 0);
begin
if (rst_n = '0') then cnt_4:="0000000000";
elsif(rising_edge(clk)) then cnt_4:= cnt_4+1;
end if;
if (rst_n= '0') then seg_num:= "0000";
elsif(rising_edge(clk)) then
case (cnt_4 (9 downto 8)) is
when "00" => seg_num:=ids_data (3 downto 0);
when "01" => seg_num:=ids_data (7 downto 4);
when "10" =>seg_num:=ids_data (11 downto 8) ;
when "11" => seg_num:=ids_data (15 downto 12);
when others=>NULL;
end case;
end if;
if (rst_n='0') then seg_wei<= "000000";
elsif (rising_edge(clk)) then
if(cnt_4(7 downto 0) <="11100011")then
case cnt_4 (9 downto 8) is
when "00"=>
seg_wei<=we0;
when "01"=>
seg_wei<=we1;
when "10"=>
seg_wei<=we2;
when "11"=>
seg_wei<=we3;
when others=>
seg_wei<=we;
end case;
else seg_wei<=we;
end if;
end if;
if (rst_n='0') then seg_duan<= "00000000";
elsif (rising_edge(clk)) then
if(cnt_4(9 downto 8)="01")then
case seg_num is
when "0000"=>seg_duan<=num00;
when "0001"=>seg_duan<=num11;
when "0010"=>seg_duan<=num22;
when "0011"=>seg_duan<=num33;
when "0100"=>seg_duan<=num44;
when "0101"=>seg_duan<=num55;
when "0110"=>seg_duan<=num66;
when "0111"=>seg_duan<=num77;
when "1000"=>seg_duan<=num88;
when "1001"=>seg_duan<=num99;
when others=>NULL;
end case;
else
case seg_num is
when "0000"=>seg_duan<=num0;
when "0001"=>seg_duan<=num1;
when "0010"=>seg_duan<=num2;
when "0011"=>seg_duan<=num3;
when "0100"=>seg_duan<=num4;
when "0101"=>seg_duan<=num5;
when "0110"=>seg_duan<=num6;
when "0111"=>seg_duan<=num7;
when "1000"=>seg_duan<=num8;
when "1001"=>seg_duan<=num9;
when others=>NULL;
end case;
end if;
end if;
end process;
end behav;
下载验证:
具体效果可参考:
大家如果仅仅拿来用的话,只需要注意传入的数据 ids_data 的数据类型及位宽即可
没有回复内容