⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 up3_clock.vhd

📁 用vhdl设计实现的多功能电子钟
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--******************************************************************************
--  结构体中使用的库
--******************************************************************************

LIBRARY IEEE;
USE  IEEE.STD_LOGIC_1164.all;
USE  IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;

--******************************************************************************
--  实体
--  PORT说明
--  MOD_DRT : modify_drive_time 修改时间状态驱动
--  MOD_DRD : modify_drive_date 修改日期状态驱动
--  MOD_RDW : modify_drive_week 修改星期状态驱动
--  reset : 复位键,低电平有效
--  clk_48Mhz : 接键盘上时钟输出
--  AL2NOAL : all_to_nomal 用于将所有修改状态恢复到正常状态(未实现)
--  MOD_OR_SET : 选择修改时钟还是设定闹钟
--  TIMING_LED : 闹铃
--******************************************************************************

ENTITY UP3_CLOCK IS
	PORT(      
	               reset, clk_48Mhz : IN	   STD_LOGIC;
    AL2NOL, MOD_DRT,MOD_DRD,MOD_DRW : IN	   STD_LOGIC;   --BUTTON
                         MOD_OR_SET : IN       STD_LOGIC;   --SWITCH
		         key_data,key_clock : IN	   STD_LOGIC;
           LCD_RS, LCD_E,HIT_LED	: OUT	   STD_LOGIC; 
	TIMING_LED,  RESET_LED, SEC_LED : OUT	   STD_LOGIC;
		 	     	       LCD_RW	: BUFFER   STD_LOGIC;
		 			       DATA_BUS : INOUT	   STD_LOGIC_VECTOR(7 DOWNTO 0)
		);
END UP3_CLOCK;

ARCHITECTURE a OF UP3_CLOCK IS


COMPONENT ps2 is
	port (
		resetn: in std_logic; -- active low reset
		clock: in std_logic; -- system clock
		clk_10hz:in std_logic;
		ps2_clk: in std_logic; -- PS/2 clock line
		ps2_dta: in std_logic; -- PS/2 data line
		hit_1: out std_logic;
		ascii: out std_logic_vector(7 downto 0)); 
end COMPONENT;
--******************************************************************************
--  结构体
--  定义数据类型 state_type,以及各信号量
--  RESET1, RESET2, RESET3:DATA_BUS_VALUE <= X"38" 复位过程必须的三个状态
--  FUNC_SET:DATA_BUS_VALUE <= X"38" 显示模式设置,准备关闭      
--	DISPLAY_OFF:DATA_BUS_VALUE <= X"08" 显示关闭 
--  DISPLAY_CLEAR :DATA_BUS_VALUE <= X"01" 显示清屏 
--  DISPLAY_ON:DATA_BUS_VALUE <= X"0C" 显示开及光标设置
--  MODE_SET:DATA_BUS_VALUE <= X"06" 显示光标移动设置
--  WRITE_CHAR1,WRITE_CHAR2,WRITE_CHAR3,WRITE_CHAR4,WRITE_CHAR5,
--	WRITE_CHAR6,WRITE_CHAR7,WRITE_CHAR8, WRITE_CHAR9, WRITE_CHAR10,
--  HOLD:状态保持   
--  RETURN_HOME:DATA_BUS_VALUE <= X"80",数据指针设置
--	TOGGLE_E:非使能状态 
--******************************************************************************

	TYPE STATE_TYPE IS (HOLD, FUNC_SET, DISPLAY_ON, MODE_SET, WRITE_CHAR0,WRITE_CHAR1,
	WRITE_CHAR2,WRITE_CHAR3,WRITE_CHAR4,WRITE_CHAR5,WRITE_CHAR6,WRITE_CHAR7,
	WRITE_CHAR8, WRITE_CHAR9, WRITE_CHARA,WRITE_CHARB,WRITE_CHARC,WRITE_CHARD,WRITE_CHARE,
    WRITE_CHARF,GOTO_NEXT_ROW, WRITE_CHAR40, WRITE_CHAR41,WRITE_CHAR42, WRITE_CHAR43,
	WRITE_CHAR44, WRITE_CHAR45, WRITE_CHAR46,WRITE_CHAR47, WRITE_CHAR48, WRITE_CHAR49,
	WRITE_CHAR4A,WRITE_CHAR4B,WRITE_CHAR4C,WRITE_CHAR4D,WRITE_CHAR4E, WRITE_CHAR4F,
	RETURN_HOME, TOGGLE_E, RESET1, RESET2, RESET3, DISPLAY_OFF, DISPLAY_CLEAR);
	
	SIGNAL state, next_command: STATE_TYPE;
	SIGNAL BCD_SECD0,BCD_SECD1,BCD_MIND0,BCD_MIND1: STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL BCD_DAY0,BCD_DAY1,BCD_MON1,BCD_MON0,BCD_YEAR3,BCD_YEAR2,BCD_YEAR1,BCD_YEAR0: STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL DAY_MODE : INTEGER RANGE 1 TO 4 ;
	SIGNAL YEAR_DEF : STD_LOGIC;
	
	TYPE STATE_MODIFY IS (COUNT, MODIFY_HOUR1,MODIFY_HOUR0,MODIFY_MIN1,MODIFY_MIN0,
	MODIFY_SECD1,MODIFY_SECD0);
	SIGNAL MODIFY_STATE,MODIFY_NEXT : STATE_MODIFY;
	SIGNAL COUNT_CON, MODIFY_HOUR1_CON,MODIFY_HOUR0_CON,MODIFY_MIN1_CON,MODIFY_MIN0_CON,
	MODIFY_SECD1_CON,MODIFY_SECD0_CON : STD_LOGIC;
	
	TYPE STATE_MODIFY_DATE IS (COUNT_DATE, MODIFY_YEAR0,MODIFY_YEAR1,MODIFY_YEAR2,MODIFY_YEAR3,
	MODIFY_MON1,MODIFY_MON0,MODIFY_DAY1,MODIFY_DAY0);
	SIGNAL MODIFY_DATE_STATE,MODIFY_DATE_NEXT : STATE_MODIFY_DATE;
	SIGNAL COUNT_DATE_CON, MODIFY_YEAR0_CON,MODIFY_YEAR1_CON,MODIFY_YEAR2_CON,MODIFY_YEAR3_CON,
	MODIFY_MON1_CON,MODIFY_MON0_CON,MODIFY_DAY1_CON,MODIFY_DAY0_CON: STD_LOGIC;
	SIGNAL ONE_DAY ,ONE_MONTH : STD_LOGIC;
	
	SIGNAL DATA_BUS_VALUE: STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL CLK_COUNT_400HZ: STD_LOGIC_VECTOR(19 DOWNTO 0);
	SIGNAL CLK_COUNT_10HZ: STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL BCD_HRD0,BCD_HRD1,BCD_TSEC: STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL CLK_400HZ, CLK_10HZ : STD_LOGIC;
	SIGNAL MODIFY_MOD :STD_LOGIC_VECTOR(1 DOWNTO 0);
	
	SIGNAL DATA_LED: STD_LOGIC;
	SIGNAL KEY_ASCII : STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL KEY_BCD : STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL HIT :STD_LOGIC;
	
	
	SIGNAL THE_TIME : STD_LOGIC;
    SIGNAL BCD_CLK_HRD1,BCD_CLK_HRD0,BCD_CLK_MIN1,BCD_CLK_MIN0,BCD_CLK_SEC1,BCD_CLK_SEC0 : STD_LOGIC_VECTOR(3 DOWNTO 0);


	TYPE STATE_TYPE_WEEK IS (W0,W1,W2,W3,W4,W5,W6);		
    SIGNAL WEEK1,WEEK2,WEEK3 : STD_LOGIC_VECTOR(7 DOWNTO 0);--星期几的前三个字母
	SIGNAL STATE_WEEK,NEXT_STATEWEEK :STATE_TYPE_WEEK;
	
	SIGNAL CHAR0,CHAR1,CHAR2,CHAR3,CHAR4,CHAR5,CHAR6,CHAR7,CHAR8,CHAR9,CHARA,
	CHARE,CHARF,CHAR40,CHAR41,CHAR42,CHAR43,CHAR44,CHAR45,CHAR46,CHAR47,CHAR48,
	CHAR49,CHAR4A,CHAR4B,CHAR4C,CHAR4D,CHAR4E,CHAR4F:STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL WR_OR_BL : STD_LOGIC;
	
BEGIN

	RESET_LED <= NOT RESET;     --信号输出
	SEC_LED <= BCD_SECD0(0);
--	KEY_BCD <= KEY_ASCII(3 DOWNTO 0);
	HIT_LED <= HIT;
-- BIDIRECTIONAL TRI STATE LCD DATA BUS
	DATA_BUS <= DATA_BUS_VALUE WHEN LCD_RW = '0' ELSE "ZZZZZZZZ";   --LCD_RW为零时数据输出
--******************************************************************************
--  时钟信号分频
--  利用48MHz时钟信号产生400Hz的时钟信号
--******************************************************************************
	PROCESS
	BEGIN
	 WAIT UNTIL CLK_48MHZ'EVENT AND CLK_48MHZ = '1';
		IF RESET = '0' THEN
		 CLK_COUNT_400HZ <= X"00000";
		 CLK_400HZ <= '0';
		ELSE
				IF CLK_COUNT_400HZ < X"0EA60" THEN --0EA60      
				 CLK_COUNT_400HZ <= CLK_COUNT_400HZ + 1;
				ELSE
		    	 CLK_COUNT_400HZ <= X"00000";
				 CLK_400HZ <= NOT CLK_400HZ;
				END IF;
		END IF;
	END PROCESS;
	
--******************************************************************************
--  This code displays time in the UP3's LCD Display
--  状态转换,400Hz信号用于驱动状态转换,刷新显示器
--  显示时钟
--******************************************************************************	
	PROCESS (CLK_400HZ, reset)
	BEGIN
	
--******************************************************************************
--  reset = '0'时state <= RESET1 利用400Hz时钟信号产生10Hz的时钟信号
--  next_command <= RESET2
--******************************************************************************	
		IF reset = '0' THEN
			state <= RESET1;
			DATA_BUS_VALUE <= X"38";
			next_command <= RESET2;
			LCD_E <= '1';
			LCD_RS <= '0';
			LCD_RW <= '0';

		ELSIF CLK_400HZ'EVENT AND CLK_400HZ = '1' THEN
-- GENERATE 1 SEC CLOCK SIGNAL FOR SECOND COUNT PROCESS
			IF CLK_COUNT_10HZ < 19  THEN      --19               
				CLK_COUNT_10HZ <= CLK_COUNT_10HZ + 1;
			ELSE
				CLK_COUNT_10HZ <= X"00";
				CLK_10HZ <= NOT CLK_10HZ;
			END IF;
-- SEND TIME TO LCD	
		
			CASE state IS
-- Set Function to 8-bit transfer and 2 line display with 5x8 Font size
-- see Hitachi HD44780 family data sheet for LCD command and timing details
				WHEN RESET1 =>
						LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"38";
						state <= TOGGLE_E;
						next_command <= RESET2;
				WHEN RESET2 =>
						LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"38";
						state <= TOGGLE_E;
						next_command <= RESET3;
				WHEN RESET3 =>
						LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"38";
						state <= TOGGLE_E;
						next_command <= FUNC_SET;
-- EXTRA STATES ABOVE ARE NEEDED FOR RELIABLE PUSHBUTTON RESET OF LCD
				WHEN FUNC_SET =>
						LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"38";
						state <= TOGGLE_E;
						next_command <= DISPLAY_OFF;
-- Turn off Display and Turn off cursor
				WHEN DISPLAY_OFF =>
						LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"08";
						state <= TOGGLE_E;
						next_command <= DISPLAY_CLEAR;
-- Turn on Display and Turn off cursor
				WHEN DISPLAY_CLEAR =>
						LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"01";
						state <= TOGGLE_E;
						next_command <= DISPLAY_ON;
-- Turn on Display and Turn off cursor
				WHEN DISPLAY_ON =>
						LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"0C";
						state <= TOGGLE_E;
						next_command <= MODE_SET;
-- Set write mode to auto increment address and move cursor to the right
				WHEN MODE_SET =>
						LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"06";
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR0;
-- Write ASCII hex character in first LCD character location
				WHEN WRITE_CHAR0 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR0;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR1;
-- Write ASCII hex character in second LCD character location
				WHEN WRITE_CHAR1 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR1;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR2;
-- Write ASCII hex character in third LCD character location
				WHEN WRITE_CHAR2 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR2 ;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR3;
-- Write ASCII hex character in fourth LCD character location
				WHEN WRITE_CHAR3 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR3;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR4;
-- Write ASCII hex character in fifth LCD character location
				WHEN WRITE_CHAR4 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR4;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR5;
-- Write ASCII hex character in sixth LCD character location
				WHEN WRITE_CHAR5 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR5 ;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR6;
-- Write ASCII hex character in seventh LCD character location
				WHEN WRITE_CHAR6 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR6;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR7;
-- Write ASCII hex character in eighth LCD character location
				WHEN WRITE_CHAR7 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR7;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR8;
				WHEN WRITE_CHAR8 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR8;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR9;
				WHEN WRITE_CHAR9 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR9;
						state <= TOGGLE_E;
						next_command <= WRITE_CHARA;
				WHEN WRITE_CHARA =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHARA;
						state <= TOGGLE_E;
						next_command <= WRITE_CHARB;
				WHEN WRITE_CHARB =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= WEEK1;
						state <= TOGGLE_E;
						next_command <= WRITE_CHARC;
				WHEN WRITE_CHARC =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= WEEK2;
						state <= TOGGLE_E;
						next_command <= WRITE_CHARD;
				WHEN WRITE_CHARD =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= WEEK3;
						state <= TOGGLE_E;
						next_command <= WRITE_CHARE;												
				WHEN WRITE_CHARE =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHARE;
						state <= TOGGLE_E;
						next_command <= WRITE_CHARF;	
				WHEN WRITE_CHARF =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHARF;
						state <= TOGGLE_E;
						next_command <= GOTO_NEXT_ROW;											
				WHEN GOTO_NEXT_ROW =>
				        LCD_E <= '1';
						LCD_RS <= '0';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= X"C0";
						state <= TOGGLE_E; 
						next_command <= WRITE_CHAR40;
                WHEN WRITE_CHAR40 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR40;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR41;
				WHEN WRITE_CHAR41 =>
						LCD_E <= '1';
						LCD_RS <= '1';
						LCD_RW <= '0';
						DATA_BUS_VALUE <= CHAR41;
						state <= TOGGLE_E;
						next_command <= WRITE_CHAR42;
				WHEN WRITE_CHAR42 =>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -