|
100黑币
- LIBRARY IEEE;
- USE IEEE.STD_LOGIC_1164.all;
- USE IEEE.STD_LOGIC_ARITH.all;
- USE IEEE.STD_LOGIC_UNSIGNED.all;
- -- This code displays time in the UP3's LCD Display
- -- SW8 (GLOBAL RESET) resets time
- ENTITY UP3_CLOCK IS
- PORT(reset, clk_48Mhz,D ,K,D3,D4 : IN STD_LOGIC;--复位,时钟信号,按键输入定义
- LCD_RS, LCD_E, RESET_LED, SEC_LED,Q_LED : OUT STD_LOGIC;--使能端,LED指示灯输出定义
- LCD_RW ,Q : BUFFER STD_LOGIC;--
- DATA_BUS : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);--1602数据端口
- SW3 : IN STD_LOGIC_VECTOR(3 DOWNTO 0));--
- END UP3_CLOCK;
- ARCHITECTURE a OF UP3_CLOCK IS
- TYPE STATE_TYPE IS (HOLD, FUNC_SET, DISPLAY_ON, MODE_SET, WRITE_CHAR1,
- WRITE_CHAR2,WRITE_CHAR3,WRITE_CHAR4,WRITE_CHAR5,WRITE_CHAR6,WRITE_CHAR7,
- WRITE_CHAR8, WRITE_CHAR9, WRITE_CHAR10, RETURN_HOME, TOGGLE_E, RESET1, RESET2,
- RESET3, DISPLAY_OFF, DISPLAY_CLEAR);
- TYPE CNT IS RANGE 0 TO 9;
- SIGNAL state, next_command: STATE_TYPE;
- SIGNAL DATA_BUS_VALUE: STD_LOGIC_VECTOR(7 DOWNTO 0);
- SIGNAL CLK_COUNT_100HZ,CLK_COUNT_400HZ: STD_LOGIC_VECTOR(19 DOWNTO 0);
- SIGNAL CLK_COUNT_2HZ,B1,B2,B3: STD_LOGIC_VECTOR(7 DOWNTO 0);
- SIGNAL BCD_SECD0,BCD_SECD1,BCD_MIND0,BCD_MIND1: STD_LOGIC_VECTOR(3 DOWNTO 0);
- SIGNAL BCD_HRD0,BCD_HRD1,BCD_TSEC,S1,S2,BCD_3CAI: STD_LOGIC_VECTOR(3 DOWNTO 0);
- SIGNAL CLK_400HZ, CLK_100HZ,D1 ,D0,CLK_2HZ: STD_LOGIC;
- SIGNAL COUNT:INTEGER RANGE 0 TO 200;
- SIGNAL COUNT1,COUNT2:INTEGER RANGE 0 TO 40;
- BEGIN
-
- --1602数据总线
- DATA_BUS <= DATA_BUS_VALUE WHEN LCD_RW = '0' ELSE "ZZZZZZZZ";
- 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
- CLK_COUNT_400HZ <= CLK_COUNT_400HZ + 1;
- ELSE
- CLK_COUNT_400HZ <= X"00000";
- CLK_400HZ <= NOT CLK_400HZ;
- END IF;
- IF CLK_COUNT_100HZ < 240000 THEN
- CLK_COUNT_100HZ <= CLK_COUNT_100HZ + 1;
- ELSE
- CLK_COUNT_100HZ <= X"00000";
- CLK_100HZ <= NOT CLK_100HZ;
- END IF;
- END IF;
- END PROCESS;
- PROCESS (CLK_400HZ, reset)
- BEGIN
- IF reset = '0'OR D1='1'OR K='1' 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
- -- 产生1秒时钟信号
-
- IF CLK_COUNT_2HZ < 99 THEN
- CLK_COUNT_2HZ <= CLK_COUNT_2HZ + 1;
- ELSE
- CLK_COUNT_2HZ <= X"00";
- CLK_2HZ <= NOT CLK_2HZ;
- END IF;
- -- 发送时间到液晶显示器
- CASE state IS
- -- 将8位数据转换成1602的一个5X8字体大小
- 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_CHAR1;
- -- Write ASCII hex character in first LCD character location
- WHEN WRITE_CHAR1 =>
- LCD_E <= '1';
- LCD_RS <= '1';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3" & BCD_SECD1;
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR2;
- -- Write ASCII hex character in second LCD character location
- WHEN WRITE_CHAR2 =>
- LCD_E <= '1';
- LCD_RS <= '1';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3" & BCD_SECD0;
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR3;
- -- Write ASCII hex character in third LCD character location
- WHEN WRITE_CHAR3 =>
- LCD_E <= '1';
- LCD_RS <= '1';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3A" ;
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR4;
- -- Write ASCII hex character in fourth LCD character location
- WHEN WRITE_CHAR4 =>
- LCD_E <= '1';
- LCD_RS <= '1';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3" & BCD_TSEC;
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR5;
- -- Write ASCII hex character in fifth LCD character location
- WHEN WRITE_CHAR5 =>
- LCD_E <= '1';
- LCD_RS <= '1';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3" & BCD_3CAI;
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR6;
- -- Write ASCII hex character in sixth LCD character location
- WHEN WRITE_CHAR6 =>
- LCD_E <= '0';
- LCD_RS <= '0';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3A" ;
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR7;
- -- Write ASCII hex character in seventh LCD character location
- WHEN WRITE_CHAR7 =>
- LCD_E <= '0';
- LCD_RS <= '0';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3" & BCD_SECD1;
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR8;
- -- Write ASCII hex character in eighth LCD character location
- WHEN WRITE_CHAR8 =>
- LCD_E <= '0';
- LCD_RS <= '0';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3" & BCD_SECD0;
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR9;
- WHEN WRITE_CHAR9 =>
- LCD_E <= '0';
- LCD_RS <= '0';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"2E";
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR10;
- WHEN WRITE_CHAR10 =>
- LCD_E <= '0';
- LCD_RS <= '0';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"3" & BCD_TSEC;
- state <= TOGGLE_E;
- next_command <= RETURN_HOME;
- -- Return write address to first character postion
- WHEN RETURN_HOME =>
- LCD_E <= '1';
- LCD_RS <= '0';
- LCD_RW <= '0';
- DATA_BUS_VALUE <= X"80";
- state <= TOGGLE_E;
- next_command <= WRITE_CHAR1;
- -- The next two states occur at the end of each command to the LCD
- -- Toggle E line - falling edge loads inst/data to LCD controller
- WHEN TOGGLE_E =>
- LCD_E <= '0';
- state <= HOLD;
- -- Hold LCD inst/data valid after falling edge of E line
- WHEN HOLD =>
- state <= next_command;
- END CASE;
- END IF;
- END PROCESS;
- PROCESS (Clk_100hz, reset)
- BEGIN
-
- IF reset = '0' OR D1='1'THEN
- BCD_HRD1 <= X"0";
-
- BCD_HRD0 <= X"0";
- BCD_MIND1 <= X"0";
- BCD_MIND0 <= X"0";
- BCD_SECD1 <= X"0";
- BCD_SECD0 <= X"0";
- BCD_TSEC <= X"0";
- BCD_3CAI<=X"0";
- SEC_LED<='0';
- RESET_LED<='0';
- Q_LED<='0';
-
- IF K='0' THEN B2<=X"00";ELSE NULL;END IF;
- ELSIF clk_100HZ'EVENT AND clk_100HZ = '1' THEN
- IF COUNT1<20 THEN
- COUNT1<=COUNT1+1;ELSE COUNT1<=0;
- IF COUNT2<=8 THEN IF D3='0' THEN COUNT2<=COUNT2+1;ELSE
- COUNT2<=COUNT2; END IF;ELSE COUNT2<=1;END IF;END IF ;
-
-
- IF BCD_3CAI<9 THEN
- BCD_3CAI<=BCD_3CAI+1;
- IF K='0' THEN B2<=B2+1;
- ELSE NULL;
- IF D3='0' THEN SEC_LED<='0';
- RESET_LED<='0';Q_LED<='0';ELSE
- IF K='1'AND D0='1' THEN
- IF B2<=15 THEN SEC_LED<='1';
- ELSE SEC_LED<='0';
- IF B2>15 AND B2<=23 THEN RESET_LED<='1';
- ELSE RESET_LED<='0';
- IF B2>23 AND B2<=31 THEN Q_LED<='1';
- ELSE Q_LED<='0';
- IF B2>31 THEN
- SEC_LED<='1';
- RESET_LED<='1';Q_LED<='1';
- ELSE SEC_LED<='0';
- RESET_LED<='0';Q_LED<='0';
- END IF;END IF;END IF;END IF;END IF;
- END IF;END IF;
- ELSE
- BCD_3CAI<=X"0";
- -- TENTHS OF SECONDS
- IF BCD_TSEC < 9 THEN
- BCD_TSEC <= BCD_TSEC + 1;
- ELSE
- BCD_TSEC <= X"0";
-
- -- SECONDS
- IF BCD_SECD0 < 9 THEN
- BCD_SECD0 <= BCD_SECD0 + 1;
-
-
-
- ELSE
- -- TENS OF SECONDS
- BCD_SECD0 <= "0000";
- IF BCD_SECD1 < 5 THEN
- BCD_SECD1 <= BCD_SECD1 + 1;
- ELSE
- -- MINUTES
- BCD_SECD1 <= "0000";
- IF BCD_MIND0 < 9 THEN
- BCD_MIND0 <= BCD_MIND0 + 1;
- ELSE
- -- TENS OF MINUTES
- BCD_MIND0 <= "0000";
- IF BCD_MIND1 < 5 THEN
- BCD_MIND1 <= BCD_MIND1 + 1;
- ELSE
- -- HOURS
- BCD_MIND1 <= "0000";
- IF BCD_HRD0 < 9 AND NOT((BCD_HRD1 = 2) AND (BCD_HRD0 = 3))THEN
- BCD_HRD0 <= BCD_HRD0 + 1;
- ELSE
- -- TENS OF HOURS
- IF NOT((BCD_HRD1 = 2) AND (BCD_HRD0 = 3)) THEN
- BCD_HRD1 <= BCD_HRD1 + 1;
- BCD_HRD0 <= "0000";
- ELSE
- -- NEW DAY
- BCD_HRD1 <= "0000";
- BCD_HRD0 <= "0000";
- END IF;
- END IF;
- END IF;
- END IF;
- END IF;
- END IF;
- END IF;
- END IF;
- END IF;
- END PROCESS;
- PROCESS(CLK_100HZ)
- BEGIN
- CASE SW3 IS
- WHEN "0000"=>S1<=X"0";
- WHEN "0001"=>S1<=X"1";
- WHEN "0010"=>S1<=X"2";
- WHEN "0011"=>S1<=X"3";
- WHEN "0100"=>S1<=X"4";
- WHEN "0101"=>S1<=X"5";
- WHEN "0110"=>S1<=X"6";
- WHEN "0111"=>S1<=X"7";
- WHEN "1000"=>S1<=X"8";
- WHEN "1001"=>S1<=X"9";
- WHEN "1010"=>S1<=X"A";
- WHEN "1011"=>S1<=X"B";
- WHEN "1100"=>S1<=X"C";
- WHEN "1101"=>S1<=X"D";
- WHEN "1110"=>S1<=X"E";
- WHEN OTHERS=>S1<=X"F";
- END CASE;
- IF reset='0'OR D1='1' THEN
- B1<=X"00";B3<=X"00";D1<='0';
- ELSIF clk_100HZ'EVENT AND clk_100HZ = '1' THEN
- IF B1<99 THEN B1<=B1+1;
- ELSE B1<=X"00";
- IF B3<16 THEN B3<=B3+1;
- IF B3=S1 THEN D0<='1';D1<='1';ELSE D0<='0';END IF;
- ELSE B3<=X"00";
- END IF;END IF;END IF;
- END PROCESS;
- PROCESS(CLK_100HZ)
- BEGIN
- IF reset='0' THEN COUNT<=0;Q<='0';
- ELSIF D0='1' OR D4='0' THEN
- IF CLK_400HZ'EVENT AND CLK_400HZ='1' THEN
- IF COUNT<=COUNT2 THEN Q<='1';COUNT<=COUNT+1;
- ELSIF COUNT=8 THEN Q<='0';COUNT<=0;
- ELSE Q<='0';COUNT<=COUNT+1;
- END IF;END IF;ELSE NULL;END IF;END PROCESS;
- END a;
复制代码 |
|