📄 display.vhd
字号:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DISPLAY IS
PORT(
CLK : IN STD_LOGIC;
RES : IN STD_LOGIC;
DS0 : IN STD_LOGIC;
DS1 : IN STD_LOGIC;
LCD_RS, LCD_E : OUT STD_LOGIC;
LCD_RW : BUFFER STD_LOGIC;
DATA_BUS : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END DISPLAY;
ARCHITECTURE behav OF DISPLAY 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,
--------------------
WRITE1_CHAR1,WRITE1_CHAR2,WRITE1_CHAR3,
WRITE2_CHAR1,WRITE2_CHAR2,WRITE2_CHAR3,
WRITE3_CHAR1,WRITE3_CHAR2,WRITE3_CHAR3,
----------------------
DISPLAY_SET,
RETURN_HOME,TOGGLE_E, RESET1, RESET2,
GOTO_NEXTLINE,
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_400HZ : STD_LOGIC;
BEGIN
DATA_BUS <= DATA_BUS_VALUE WHEN LCD_RW = '0' ELSE "ZZZZZZZZ";
PROCESS
BEGIN
WAIT UNTIL CLK'EVENT AND CLK = '1';
IF RES = '1' 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 (CLK_400HZ, RES)
BEGIN
IF RES = '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
-- GENERATE 1 SEC CLOCK SIGNAL FOR SECOND COUNT PROCESS
-- 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 <= DISPLAY_SET;
--*************************************************************
--以下是显示模式控制,即通过拨码选择不同的显示内容
--*************************************************************
WHEN DISPLAY_SET =>
IF DS0='0' AND DS1='0' THEN
state <= TOGGLE_E;
next_command <= WRITE_CHAR1;
END IF;
IF DS0='1' AND DS1='0' THEN
state <= TOGGLE_E;
next_command <= WRITE1_CHAR1;
END IF;
IF DS0='0' AND DS1='1' THEN
state <= TOGGLE_E;
next_command <= WRITE2_CHAR1;
END IF;
IF DS0='1' AND DS1='1' THEN
state <= TOGGLE_E;
next_command <= WRITE3_CHAR1;
END IF;
--*****************************************************
--以下是字符显示部分
--*****************************************************
--写第一个字符
WHEN WRITE_CHAR1 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"30";
state <= TOGGLE_E;
next_command <= WRITE_CHAR2;
--写第二个字符
WHEN WRITE_CHAR2 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"31";
state <= TOGGLE_E;
next_command <= WRITE_CHAR3;
--写第三个字符
WHEN WRITE_CHAR3 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"32" ;
state <= TOGGLE_E;
next_command <= GOTO_NEXTLINE;
--
WHEN WRITE1_CHAR1 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"33";
state <= TOGGLE_E;
next_command <= WRITE1_CHAR2;
--
WHEN WRITE1_CHAR2 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"34";
state <= TOGGLE_E;
next_command <= WRITE1_CHAR3;
--
WHEN WRITE1_CHAR3 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"35" ;
state <= TOGGLE_E;
next_command <= GOTO_NEXTLINE;
WHEN WRITE2_CHAR1 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"36";
state <= TOGGLE_E;
next_command <= WRITE2_CHAR2;
--
WHEN WRITE2_CHAR2 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"37";
state <= TOGGLE_E;
next_command <= WRITE2_CHAR3;
--
WHEN WRITE2_CHAR3 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"38" ;
state <= TOGGLE_E;
next_command <= GOTO_NEXTLINE;
WHEN WRITE3_CHAR1 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"39";
state <= TOGGLE_E;
next_command <= WRITE3_CHAR2;
--
WHEN WRITE3_CHAR2 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"3a";
state <= TOGGLE_E;
next_command <= WRITE3_CHAR3;
--
WHEN WRITE3_CHAR3 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"3b" ;
state <= TOGGLE_E;
next_command <= GOTO_NEXTLINE;
--
WHEN WRITE_CHAR4 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"20";
state <= TOGGLE_E;
next_command <= WRITE_CHAR5;
--
WHEN WRITE_CHAR5 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"34";
state <= TOGGLE_E;
next_command <= WRITE_CHAR6;
--
WHEN WRITE_CHAR6 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"38" ;
state <= TOGGLE_E;
next_command <= WRITE_CHAR7;
--
WHEN WRITE_CHAR7 =>
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"4D";
state <= TOGGLE_E;
next_command <= RETURN_HOME;
--换行
WHEN GOTO_NEXTLINE =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"C0";
state <= TOGGLE_E;
next_command <= WRITE_CHAR4;
-- 回到开头
WHEN RETURN_HOME =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
DATA_BUS_VALUE <= X"80";
state <= TOGGLE_E;
next_command <= DISPLAY_SET;
-- 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;
END behav;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -