📄 up3_clock.vhd
字号:
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 : IN STD_LOGIC;
DipSwitch1,DipSwitch2,DipSwitch3 : IN STD_LOGIC;
PBSwitch1,PBSwitch2,PBSwitch3 : IN STD_LOGIC;
LCD_RS, LCD_E, RESET_LED : OUT STD_LOGIC;
SEC_LED,ALARM_LED,RTC_LED : OUT STD_LOGIC;
LCD_RW : BUFFER STD_LOGIC;
sda : INOUT STD_LOGIC;
scl : OUT STD_LOGIC;
DATA_BUS : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END UP3_CLOCK;
ARCHITECTURE a OF UP3_CLOCK IS
TYPE STATE_TYPE IS (HOLD, FUNC_SET, DISPLAY_ON, MODE_SET, WRITE_CHART,
WRITE_CHARI, WRITE_CHARM, WRITE_CHARE, WRITE_CHAR1, WRITE_CHAR2, WRITE_CHAR3,
WRITE_CHAR4, WRITE_CHAR5, WRITE_CHAR6, WRITE_CHAR7, WRITE_CHAR8, WRITE_CHAR9,
WRITE_CHAR10,WRITE_CHAR11,WRITE_CHAR12,WRITE_CHAR13,WRITE_CHAR14,WRITE_CHAR15,
WRITE_CHAR16,WRITE_CHAR17,WRITE_CHAR18,WRITE_CHAR19,WRITE_CHAR20,WRITE_CHAR21,WRITE_CHAR22,
WRITE_CHAR23,WRITE_CHAR24,WRITE_CHAR25,WRITE_STAR1,
WRITE_STAR2, WRITE_BLANK1, WRITE_BLANK2,WRITE_BLANK3, SECOND_LINE, RETURN_HOME, TOGGLE_E,
RESET1, RESET2, RESET3, DISPLAY_OFF, DISPLAY_CLEAR);
SIGNAL state, next_command: STATE_TYPE;
SIGNAL DATA_BUS_VALUE: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL CLK_COUNT_400HZ: STD_LOGIC_VECTOR(19 DOWNTO 0);
SIGNAL CLK_COUNT_4000HZ: STD_LOGIC_VECTOR(19 DOWNTO 0);
SIGNAL BCD_SECD0,BCD_SECD1,BCD_MIND0,BCD_MIND1: STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL BCD_HRD0,BCD_HRD1,BCD_DAY,BCD_DATE1,BCD_DATE0: STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL BCD_MONTH1,BCD_MONTH0,BCD_YEAR1,BCD_YEAR0:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL CLK_400HZ,CLK_4000HZ : STD_LOGIC;
SIGNAL FLAG: STD_LOGIC;
SIGNAL RTC_SEC, RTC_MIN, RTC_HOR, RTC_DAY :STD_LOGIC_VECTOR(8 DOWNTO 1);
SIGNAL RTC_DATE, RTC_MONTH, RTC_YEAR :STD_LOGIC_VECTOR(8 DOWNTO 1);
SIGNAL write_sec, write_min, write_hor, write_day :STD_LOGIC_VECTOR(8 DOWNTO 1);
SIGNAL write_date, write_month, write_year :STD_LOGIC_VECTOR(8 DOWNTO 1);
type R_RTC_state is (R_prepare,R_start,R_transmit_slave_address,R_transmit_sub_address,
R_start1,R_transmit_read,R_read_data1,R_read_data2,R_read_data3,R_read_data4,
R_read_data5, R_read_data6, R_read_data7, R_check_ack1, R_check_ack2, R_check_ack3,
R_check_ack4,R_check_ack5, R_check_ack6, R_check_ack7, R_check_ack8, R_check_ack9, R_stop ); --定义状态机的各子状态;
signal R_current_state:R_RTC_state; --定义信号;
type W_RTC_state is (W_prepare,W_start,W_transmit_slave_address,W_transmit_sub_address,
W_write_data1, W_write_data2, W_write_data3, W_write_data4, W_write_data5, W_write_data6,
W_write_data7, W_check_ack1, W_check_ack2, W_check_ack3, W_check_ack4, W_check_ack5,
W_check_ack6, W_check_ack7, W_check_ack8, W_check_ack9, W_stop, W_delay ); --定义状态机的各子状态;
signal W_current_state:W_RTC_state; --定义信号;
SIGNAL ALARM_BCD_MIND0,ALARM_BCD_HRD0 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL ALARM_BCD_HRD1, ALARM_BCD_MIND1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL TEMP_BCD_SECD0,TEMP_BCD_SECD1,TEMP_BCD_MIND0 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL TEMP_BCD_MIND1,TEMP_BCD_HRD0, TEMP_BCD_HRD1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
signal PBSwitch1_flop1 : std_logic;
signal PBSwitch1_flop2 : std_logic;
signal PB1_PulseOut : std_logic;
signal PB1_valid : std_logic;
signal PBSwitch2_flop1 : std_logic;
signal PBSwitch2_flop2 : std_logic;
signal PB2_PulseOut : std_logic;
signal PB2_valid : std_logic;
signal PBSwitch3_flop1 : std_logic;
signal PBSwitch3_flop2 : std_logic;
signal PB3_PulseOut : std_logic;
signal PB3_valid : std_logic;
signal count1 : unsigned(15 downto 0);
signal count2 : unsigned(15 downto 0);
signal count3 : unsigned(15 downto 0);
--********************************************************************************************
-- As clock is of 48 Mhz, 0x5DC0 is required to get debounce count of 500 microsecond
--********************************************************************************************
constant mincount : unsigned(15 downto 0) := "0000000000000000";
constant debounce_count: unsigned(15 downto 0) := "0101110111000000";-- 5DC0
BEGIN
RESET_LED <= NOT RESET;
SEC_LED <= BCD_SECD0(0);
-- BIDIRECTIONAL TRI STATE LCD DATA BUS
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;
END IF;
END PROCESS;
PROCESS
BEGIN
WAIT UNTIL CLK_48MHZ'EVENT AND CLK_48MHZ = '1';
IF RESET = '0' THEN
CLK_COUNT_4000HZ <= X"00000";
CLK_4000HZ <= '0';
ELSE
IF CLK_COUNT_4000HZ < X"01770" THEN
CLK_COUNT_4000HZ <= CLK_COUNT_4000HZ + 1;
ELSE
CLK_COUNT_4000HZ <= X"00000";
CLK_4000HZ <= NOT CLK_4000HZ;
END IF;
END IF;
END PROCESS;
PROCESS (CLK_400HZ, reset)
BEGIN
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
-- 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_CHART;
WHEN WRITE_CHART =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"54";
state <= TOGGLE_E;
next_command <= WRITE_CHARI;
WHEN WRITE_CHARI =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"49";
state <= TOGGLE_E;
next_command <= WRITE_CHARM;
WHEN WRITE_CHARM =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"4D";
state <= TOGGLE_E;
next_command <= WRITE_CHARE;
WHEN WRITE_CHARE =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"45";
state <= TOGGLE_E;
IF BCD_SECD0(0) = '0' THEN
next_command <= WRITE_STAR1;
ELSE
next_command <= WRITE_BLANK1;
END IF;
WHEN WRITE_STAR1 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"2A";
state <= TOGGLE_E;
next_command <= WRITE_STAR2;
WHEN WRITE_STAR2 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"2A";
state <= TOGGLE_E;
next_command <= WRITE_CHAR1;
WHEN WRITE_BLANK1 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"23";
state <= TOGGLE_E;
next_command <= WRITE_BLANK2;
WHEN WRITE_BLANK2 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"23";
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_HRD1;
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_HRD0;
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_MIND1;
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_MIND0;
state <= TOGGLE_E;
next_command <= WRITE_CHAR6;
-- Write ASCII hex character in sixth LCD character location
WHEN WRITE_CHAR6 =>
LCD_E <= '1';
LCD_RS <= '1';
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 <= '1';
LCD_RS <= '1';
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 <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"3" & BCD_SECD0;
state <= TOGGLE_E;
next_command <= WRITE_CHAR9;
WHEN WRITE_CHAR9 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"2A";
state <= TOGGLE_E;
next_command <= WRITE_CHAR10;
WHEN WRITE_CHAR10 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"3" & BCD_DAY;
state <= TOGGLE_E;
next_command <= SECOND_LINE;
WHEN SECOND_LINE =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"C0";
state <= TOGGLE_E;
next_command <= WRITE_CHAR11;
WHEN WRITE_CHAR11 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"32";
state <= TOGGLE_E;
next_command <= WRITE_CHAR12;
WHEN WRITE_CHAR12 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"30";
state <= TOGGLE_E;
next_command <= WRITE_CHAR13;
WHEN WRITE_CHAR13 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"3" & BCD_YEAR1;
state <= TOGGLE_E;
next_command <= WRITE_CHAR14;
WHEN WRITE_CHAR14 =>
LCD_E <= '1';
LCD_RS <= '1';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -