用VHDL编写数字时钟

该博客围绕数字时钟系统展开,其在1Hz信号驱动下实现显示“时-分-秒”、整点报时、小时和分钟可调等功能。系统在50MHZ时钟驱动下,用两个按键控制时间设定,整点时LED灯闪烁报时,还使用4*2键盘和数码管,设置四个按键实现不同调节功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数字时钟系统实现目标:

实现显示“时-分-秒”、整点报时、小时和分钟可调等基本功能。电子钟的工作应该是在1Hz 信号的驱动下进行,这样每来一个该时钟信号,秒增加1 秒,当秒从59 秒跳转到00秒时,分钟增加1 分,同时当分钟从59 分跳转到00 分时,小时增加1 小时,但是需要注意的是,小时的范围是从0~23 时。

数字时钟系统要求:

在一个50MHZ系统时钟的驱动下完成整个电路的输出,电路要能正确的输出时、分、秒,并且根据用户的设定来改变时钟和分钟的值,这里需要使用两个按键作为输入控制S1,S0,可以分别用来改变时钟和分钟的值以达到时间设定的目的,每按一次S0按钮分钟加1,每按一次S1按钮时钟加1。同时在整点时分都应该输出一个整点报时信号,信号规律为1秒钟闪烁一次,持续5秒,控制某个LED灯进行报时。

功能

这里用了一个4*2的键盘和四个数字显示的数码管。设置四个按键,功能分别是调节分钟,调节时钟,全部置0,查看秒钟。

-- VHDL library Declarations 
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;


-- The Entity Declarations 
ENTITY LED8 IS
	PORT 
	(
		-- Reset & Clock Signal 
		RESET: 		IN STD_LOGIC; 
		GCLKP1:		IN STD_LOGIC;	-- 50 MHz 
		k1, k2, k3,k4 : in std_LOGIC;
		LED1: buffer std_logic;
		-- LED8 PIN 
		LEDOut:		 OUT STD_LOGIC_VECTOR(7 DOWNTO 0);	-- LED Segment 
		DigitSelect: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)	-- LED Digit 
	);
END LED8;


-- The Architecture of Entity Declarations 
ARCHITECTURE Behavioral OF LED8 IS
	SIGNAL LED:	integer range 0 to 9;	
	SIGNAL cnt,Period1uS, Period1mS, Period1S,count12: STD_LOGIC;
	SIGNAL s1,s2,s3,s4: integer range 0 to 9;
	
	
BEGIN
	
	------------------------------------------------------------------------------
	-- Clock 
	------------------------------------------------------------------------------
	PROCESS( RESET, GCLKP1, Period1uS, Period1mS )
		VARIABLE Count  : STD_LOGIC_VECTOR(5 DOWNTO 0);
		VARIABLE Count1 : STD_LOGIC_VECTOR(9 DOWNTO 0);
		VARIABLE Count2 : STD_LOGIC_VECTOR(9 DOWNTO 0);
	BEGIN
		------------------------------------
		--Period: 1uS 
		IF( RESET = '0' ) THEN 
			Count := "000000";
		ELSIF( GCLKP1'EVENT AND GCLKP1='1' ) THEN 
			IF( Count>"110000" ) THEN 	Count := "000000";	--  110000:48  50/50M = 1us
			ELSE                  		Count := Count + 1;
			END IF;
			Period1uS <= Count(5);
		END IF;
		------------------------------------
		--Period: 1mS 
		IF( Period1uS'EVENT AND Period1uS='1' ) THEN 
			IF( Count1>"1111100110" ) THEN 	Count1 := "0000000000";  -- 1111100110:998  1000*1us = 1ms
			ELSE                  			Count1 := Count1 + 1;
			END IF;
			Period1mS <= Count1(9);

		END IF;
		------------------------------------
		--Period: 1S (1111100110: 998)
		IF( Period1mS'EVENT AND Period1mS='1' ) THEN 
			IF( Count2>"1111100110" ) THEN 	Count2 := "0000000000";
			ELSE                  			Count2 := Count2 + 1;
			END IF;
			Period1S  <= Count2(9); 
		END IF; 
	END PROCESS;
	
	-------------------------------------------------
	-- Encoder 
	-------------------------------------------------
	-- HEX-to-seven-segment decoder 
	-- segment encoding 
	--      0 
	--     ---  
	--  5 |   | 1
	--     --- <------6
	--  4 |   | 2
	--     ---  
	--      3
	PROCESS( LED )   
	BEGIN
		CASE LED IS
			when 0=>LEDOut<= "11000000";    --'0'
			when 1=>LEDOut<= "11111001";    --'1'
			when 2=>LEDOut<= "10100100";    --'2'
			when 3=>LEDOut<= "10110000";    --'3'
			when 4=>LEDOut<= "10011001";    --'4'
			when 5=>LEDOut<= "10010010";    --'5'
			when 6=>LEDOut<= "10000010";    --'6'
			when 7=>LEDOut<= "11111000";    --'7'
			when 8=>LEDOut<= "10000000";    --'8'
			when 9=>LEDOut<= "10010000";    --'9'
			when others=>LEDOut<= "XXXXXXXX";    --' '
		END CASE;
	END PROCESS;
	
	-------------------------------------------------
	
	-- Clock  
	PROCESS( RESET, Period1S )   
		VARIABLE Glide   : STD_LOGIC_VECTOR(3 DOWNTO 0);
		VARIABLE reflash: integer range 0 to 3;
		VARIABLE s,m,h   : integer range 0 to 64;
		VARIABLE count,count1  : integer range 0 to 1024;
		variable l1,l2,l3,l4  :integer range 0 to 9;
	BEGIN
		
		IF( Period1ms'EVENT AND Period1ms = '1' )THEN 
			CASE reflash IS
				when 0=>DigitSelect<= "0001";LED <= l1;
				when 1=>DigitSelect<= "0010";LED <= l2;
				when 2=>DigitSelect<= "0100";LED <= l3;
				when 3=>DigitSelect<= "1000";LED <= l4;
				when others=>DigitSelect<= "XXXX";
			END CASE;			
			
			if( count =0) then
				cnt <= '1';
			end if;
			
			if( (count = 0 or count = 250 or count = 500 or count = 750) and (s = 0 or s=1 or s =2 or s = 3 or s = 4)) then
				cnt <= not cnt;
			end if;
			
			if(count < 999) then 
				count := count + 1;
			else
				s := s + 1;
				count := 0;
			end if;
			
			if s = 60 then
				m := m + 1; 
				s := 0;
			end if;
							
			if( m = 60 ) then     -- every hours in position
				m := 0;
				h := h + 1;
			end if;
			
			if( h = 24) then        -- every day in position
				h := 0;
			end if;
				
			l4 := m rem 10;
			l3 := (m-l2)/10;
			l2 := h rem 10;
			l1 := (h-l2)/10; 
			
			if( k4 = '0') then	
				l4 := s rem 10;
				l3 := (s-l4)/10;
				l2 := m rem 10;
				l1 := (m-l2)/10;
			end if;
			
			reflash := reflash + 1;	
			
			if(k1 = '0') then 
				if( count rem 60 = 0) then 
					count1 := count1 + 1;
				end if;
				if( count1 = 2) then 
					m := m + 1; count1 := 0;
				end if;
			end if;
		   if(k2 = '0') then 
				if( count rem 60 = 0) then 
					count1 := count1 + 1;
				end if;
				if( count1 = 2) then 
					h := h + 1; count1 := 0;
				end if;
			end if;
		end if;
				
		if(k3 = '0') then 
			s := 0;
			m := 0;
			h := 0;
			count := 0;
		end if;
	
	END PROCESS;
	
	process(cnt)
	variable count12: integer range 0 to 6;
	begin
		if(cnt'event and cnt = '1') then	
			led1 <= not led1;
		end if;
		
	end process;
END Behavioral;

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值