URL
https://opencores.org/ocsvn/z80soc/z80soc/trunk
Subversion Repositories z80soc
[/] [z80soc/] [trunk/] [V0.7.3/] [DE2115/] [vhdl/] [lcd.vhd.bak] - Rev 46
Compare with Previous | Blame | View Log
-- VHDL CODE by Gerry O'Brien - HD44780 LCD Controller STATE_MACHINE--==================================================------ VHDL Architecture DE2_LCD_lib.TOP_LCD_DE2.LCD_DISPLAY_arch---- Created:-- by - Gerry O'Brien-- WWW.DIGITAL-CIRCUITRY.COM-- at - 15:30:18 26/03/2015---- using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)--LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.all;USE IEEE.STD_LOGIC_ARITH.all;USE IEEE.STD_LOGIC_UNSIGNED.all;ENTITY LCD ISPORT(reset : IN std_logic; -- Map this Port to a Switch within your [Port Declarations / Pin Planer]CLOCK_50 : IN std_logic; -- Using the DE2 50Mhz Clk, in order to Genreate the 400Hz signal... clk_count_400hz reset count value must be set to: <= x"0F424"LCD_RS : OUT std_logic;LCD_EN : OUT std_logic;LCD_RW : OUT std_logic;LCD_ON : OUT std_logic;LCD_BLON : OUT std_logic;LCD_DATA : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);lcd_on_sig : IN STD_LOGIC;next_char : IN STD_LOGIC_VECTOR(7 DOWNTO 0);char_count : OUT STD_LOGIC_VECTOR(4 downto 0);clk400hz : OUT STD_LOGIC);END LCD ;--ARCHITECTURE RTL OF LCD IStype state_type is (hold, func_set, display_on, mode_set, print_string,line2, return_home, drop_LCD_EN, 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 char_count_sig : STD_LOGIC_VECTOR(4 downto 0);signal clk_400hz_enable,LCD_RW_int : std_logic;signal data_bus : STD_LOGIC_VECTOR(7 downto 0);signal LCD_CHAR_ARRAY : STD_LOGIC_VECTOR(3 DOWNTO 0);BEGINLCD_DATA <= data_bus;data_bus <= data_bus_value when LCD_RW_int = '0' else "ZZZZZZZZ";LCD_RW <= LCD_RW_int;char_count <= char_count_sig;clk400hz <= clk_400hz_enable;--======================= CLOCK SIGNALS ============================--process(CLOCK_50)beginif (rising_edge(CLOCK_50)) thenif (reset = '0') thenclk_count_400hz <= x"00000";clk_400hz_enable <= '0';elseif (clk_count_400hz <= x"0F424") then -- If using the DE2 50Mhz Clock, use clk_count_400hz <= x"0F424" (50Mhz/400hz = 12500 converted to HEX = 0F424 )clk_count_400hz <= clk_count_400hz + 1; -- In Theory for a 27Mhz Clock, use clk_count_400hz <= x"01A5E" (27Mhz/400hz = 6750 converted to HEX = 01A5E )clk_400hz_enable <= '0'; -- In Theory for a 25Mhz Clock. use clk_count_400hz <= x"0186A" (25Mhz/400hz = 6250 converted to HEX = 0186A )elseclk_count_400hz <= x"00000";clk_400hz_enable <= '1';end if;end if;end if;end process;--==================================================================----======================== LCD DRIVER CORE ==============================---- STATE MACHINE WITH RESET ----===================================================-----===============--process (CLOCK_50, reset)beginif reset = '0' thenstate <= reset1;data_bus_value <= x"38"; -- RESETnext_command <= reset2;LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';elsif rising_edge(CLOCK_50) thenif clk_400hz_enable = '1' then--========================================================---- State Machine to send commands and data to LCD DISPLAY--========================================================--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--======================= INITIALIZATION START ============================--when reset1 =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"38"; -- EXTERNAL RESETstate <= drop_LCD_EN;next_command <= reset2;char_count_sig <= "00000";when reset2 =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"38"; -- EXTERNAL RESETstate <= drop_LCD_EN;next_command <= reset3;when reset3 =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"38"; -- EXTERNAL RESETstate <= drop_LCD_EN;next_command <= func_set;-- Function Set--==============--when func_set =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"38"; -- Set Function to 8-bit transfer, 2 line display and a 5x8 Font sizestate <= drop_LCD_EN;next_command <= display_off;-- Turn off Display--==============--when display_off =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"08"; -- Turns OFF the Display, Cursor OFF and Blinking Cursor Position OFF.......(0F = Display ON and Cursor ON, Blinking cursor position ON)state <= drop_LCD_EN;next_command <= display_clear;-- Clear Display--==============--when display_clear =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"01"; -- Clears the Displaystate <= drop_LCD_EN;next_command <= display_on;-- Turn on Display and Turn off cursor--===================================--when display_on =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"0C"; -- Turns on the Display (0E = Display ON, Cursor ON and Blinking cursor OFF)state <= drop_LCD_EN;next_command <= mode_set;-- Set write mode to auto increment address and move cursor to the right--====================================================================--when mode_set =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"06"; -- Auto increment address and move cursor to the rightstate <= drop_LCD_EN;next_command <= print_string;--======================= INITIALIZATION END ============================----=======================================================================---- Write ASCII hex character Data to the LCD--=======================================================================--when print_string =>state <= drop_LCD_EN;LCD_EN <= '1';LCD_RS <= '1';LCD_RW_int <= '0';-- ASCII character to outputif (next_char(7 downto 4) /= x"0") thendata_bus_value <= next_char;else-- Convert 4-bit value to an ASCII hex digitif next_char(3 downto 0) >9 then-- ASCII A...Fdata_bus_value <= x"4" & (next_char(3 downto 0)-9);else-- ASCII 0...9data_bus_value <= x"3" & next_char(3 downto 0);end if;end if;state <= drop_LCD_EN;-- Loop to send out 32 characters to LCD Display (16 by 2 lines)if (char_count_sig < 31) AND (next_char /= x"fe") thenchar_count_sig <= char_count_sig +1;elsechar_count_sig <= "00000";end if;-- Jump to second line?if char_count_sig = 15 thennext_command <= line2;-- Return to first line?elsif (char_count_sig = 31) or (next_char = x"fe") thennext_command <= return_home;elsenext_command <= print_string;end if;-- Set write address to line 2 character 1--======================================--when line2 =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"c0";state <= drop_LCD_EN;next_command <= print_string;-- Return write address to first character position on line 1--=========================================================--when return_home =>LCD_EN <= '1';LCD_RS <= '0';LCD_RW_int <= '0';data_bus_value <= x"80";state <= drop_LCD_EN;next_command <= print_string;-- The next states occur at the end of each command or data transfer to the LCD-- Drop LCD E line - falling edge loads inst/data to LCD controller--============================================================================--when drop_LCD_EN =>LCD_EN <= '0';state <= hold;-- Hold LCD inst/data valid after falling edge of E line--====================================================--when hold =>state <= next_command;LCD_BLON <= '1';-- roni LCD_ON <= '1';LCD_ON <= lcd_on_sig;end case;end if;-- CLOSING STATEMENT FOR "IF clk_400hz_enable = '1' THEN"end if;-- CLOSING STATEMENT FOR "IF reset = '0' THEN"end process;END ARCHITECTURE RTL;
