内容目录
↓本次设计的仿真源文件见下方↓
题目:用VHDL写一个数字秒表
要求:数码管显示最大为999.9,之后归零重新计数
分析:题目要求能显示十分秒,所以十分秒位应该是每100ms(产生10Hz的时钟信号)加一,然后十分秒位满10往前进一位,依次类推,SO应该有如下结构
因此本题最重要的几个点就是:由输入时钟产生10Hz的时钟信号,数码管能够正确显示数据,并能正常进位计数
1.首先分频器部分,假如我们用的是100Hz的时钟,要产生10Hz的频率信号,只能进行10分频,然后通过分频后的时钟信号对十分秒位
进行计数进位操作,相应的分频器代码如下:
--第一种写法
if clk'event and clk='1' then
if ctr_10 < 9 then
ctr_10 <= ctr_10+1;
else
ctr_10<=0;
end if;
if ctr_10 < 5 then
clk_div10 <= '0';
else
clk_div10 <= '1';
end if;
--第二种写法
signal x:std_logic;--定义信号
if clk'event and clk='1' then
if ctr_10 < 10 then
ctr_10:=ctr_10+1;
else
ctr_10:=0;
x <= not x;
end if;
clk_div10 <= x;
end if;
2.其次判断计数器的进位操作,相应代码如下:
process(RST,clk_div10) --计数器进程(100ms+1)
begin
if RST='0' then
counter_sec <= x"0000";
elsif clk_div10'EVENT AND clk_div10='1' then
if START='1' then
if counter_sec(3 downto 0) < x"9" then --判断十分秒进位
counter_sec(3 downto 0) <= counter_sec(3 downto 0)+'1';
else
counter_sec(3 downto 0)<=x"0";
if counter_sec(7 downto 4) < x"9" then--判断秒进位
counter_sec(7 downto 4) <= counter_sec(7 downto 4)+'1';
else
counter_sec(7 downto 4) <= x"0";
if counter_sec(11 downto 8) < x"9" then--判断十秒进位
counter_sec(11 downto 8) <= counter_sec(11 downto 8)+'1';
else
counter_sec(11 downto 8) <= x"0";
if counter_sec(15 downto 12) < x"9" then--判断百秒位
counter_sec(15 downto 12) <= counter_sec(15 downto 12)+'1';
else
counter_sec(15 downto 12) <= x"0";
end if;
end if;
end if;
end if;
end if;
end if;
end process;
3.数码管显示模块
由于七段数码管公共端连接到GND(共阴极型), 当数码管的中的那一个段被输入高电平, 则相应的这一段被点亮。 反之则不亮。 四位一体的七段数码管在单个静态数码管的基础上加入了用于选择哪一位数码管的位选信号端口。 八个数码管的a、 b、 c、 d、 e、 f、 g、 h、 dp都连在了一起, 8个数码管分别由各自的位选信号来控制, 被选通的数码管显示数据, 其余关闭
数码管模块采用的是38译码器,好处是可以减少IO口的占用,只需要用三个输入就可以控制八个输出,我们利用这个来进行数码管的位选操作,位选就是选择第几位数码管,而段选就是控制一个数码管上的灯条的亮灭
根据题目要求第三个数码管要一直显示小数点,所以要把第三位数码管的dp位(最高位)置1,其余数码管的dp位置0,这样就实现了只让第三个数码管小数点点亮,数码管模块部分代码如下:
--shumaguan.vhd
library ieee;
use ieee.std_logic_1164.all;
entity shumaguan is
port(
RST,CLK :in std_logic;
DIN :in std_logic_vector(15 downto 0);
BIT_4 :buffer std_logic_vector(2 downto 0);
SEG_8 :out std_logic_vector(7 downto 0)
);
end entity;
architecture rtl of shumaguan is
type Disp_State is(S_DIG4,S_DIG3,S_DIG2,S_DIG1);--定义显示状态机类型,有S4,S3,S2,S1四个状态
signal currect_state,next_state: Disp_State;--定义当前状态和下个状态信号
signal num:std_logic_vector(3 downto 0);
begin
switch_p:process(RST,currect_state)--切换段
begin
if RST='0' then
next_state<=S_DIG4;
else
case currect_state is
when S_DIG4=>next_state<=S_DIG3;
when S_DIG3=>next_state<=S_DIG2;
when S_DIG2=>next_state<=S_DIG1;
when S_DIG1=>next_state<=S_DIG4;
when others=>next_state<=S_DIG4;
end case;
end if;
end process;
lock_p:process(RST,CLK)--锁存段,将下个状态锁存到当前状态的信号
begin
if RST='0' then
currect_state<=S_DIG4;
elsif CLK'EVENT AND CLK='1' then
currect_state<=next_state;
end if;
end process;
handle_p:process(RST,CLK)
begin
if RST='0' then
BIT_4<="000";
num <="0000";
elsif CLK'EVENT AND CLK='1' then
case currect_state is
when S_DIG4=>
BIT_4 <= "000";
num <= DIN(15 downto 12);
when S_DIG3=>
BIT_4 <= "001";
num <= DIN(11 downto 8);
when S_DIG2=>
BIT_4 <= "010";
num <= DIN(7 downto 4);
when S_DIG1=>
BIT_4 <= "011";
num <= DIN(3 downto 0);
when others =>
BIT_4 <= "000";
num <= "0000";
end case;
end if;
end process;
decode_p:process(num,BIT_4)--译码进程:共阴数码管
begin
if BIT_4 = "010" then
case num is
when X"0" => SEG_8 <= X"BF";--10111111
when X"1" => SEG_8 <= X"86";--10000110
when X"2" => SEG_8 <= X"DB";--11011011
when X"3" => SEG_8 <= X"CF";--11001111
when X"4" => SEG_8 <= X"E6";--11100110
when X"5" => SEG_8 <= X"ED";--11101101
when X"6" => SEG_8 <= X"FD";--11111101
when X"7" => SEG_8 <= X"87";--10000111
when X"8" => SEG_8 <= X"FF";--11111111
when X"9" => SEG_8 <= X"EF";--11101111
when others=>SEG_8 <= X"BF";
end case;
else
case num is
when X"0" => SEG_8 <= X"3F";
when X"1" => SEG_8 <= X"06";
when X"2" => SEG_8 <= X"5B";
when X"3" => SEG_8 <= X"4F";
when X"4" => SEG_8 <= X"66";
when X"5" => SEG_8 <= X"6D";
when X"6" => SEG_8 <= X"7D";
when X"7" => SEG_8 <= X"07";
when X"8" => SEG_8 <= X"7F";
when X"9" => SEG_8 <= X"6F";
when others=>SEG_8 <= X"3F";
end case;
end if;
end process;
end architecture;
同理,课程设计当中用到数码管的地方也进行类似操作,比如打地鼠游戏中显示STAR-,只需要把每一个数码管点亮的灯条变动,然后加到case判断中去就好啦
真的已经傻瓜式教学了,再不会找个班上吧
总结:多动手,多动脑,少白嫖,你不会一直白嫖,实践>理论
end...
Comments 2 条评论
博主 Kz
小智,小智真的牛杯!!!!
博主 Kz
大家多多支持jony站长!!!!
制作不易,珍惜站长现在的秀发!