library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
entity lcd is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
key_in: in std_logic_vector (0 to 15) ;
data_out : inout STD_LOGIC_vector( 7 downto 0) ;
rs : out STD_LOGIC;
rw : out STD_LOGIC;
e : out STD_LOGIC
);
end lcd;
architecture Behavioral of lcd is
signal clock_count : unsigned ( 23 downto 0) :=(others=>'0') ;
signal clk_enable400 : std_logic :='0' ;
type state_type is (reset1, reset2,
reset3,power_up , func_set, display_on, mode_set,hell,second_line,str2,str3,str4, second_Line_data, third_line, third_line_data,one ,two,three,forward,backward,delay,
return_home, drop_lcd_e, display_off, display_clear ,char_mode, cursor_shift,st1,st2,st3,st4,st5,dram_address);
signal state, next_command : state_type;
signal data_bus : std_logic_vector ( 7 downto 0) ;
signal lcd_e, lcd_rs, lcd_rw_int : std_Logic ;
type character_string is array ( 0 to 15 ) of STD_LOGIC_VECTOR( 7 downto 0 );
signal lcd_display_string : character_string;
signal lcd_display_string_01 : character_string;
signal lcd_display_string_02 : character_string;
signal lcd_display_string_03 : character_string;
signal next_char : STD_LOGIC_VECTOR(7 downto 0);
signal char_count : STD_LOGIC_VECTOR(4 downto 0);
signal counter : unsigned ( 26 downto 0) :=( others=>'0') ;
------------------adt ------------
type str1 is array ( 0 to 5) of std_logic_Vector ( 7 downto 0) ;
signal adt_string,cdt_string : str1;
signal adt :std_logic_vector ( 7 downto 0) ;
signal cdt: std_logic_vector( 7 downto 0) ;
signal str_count : std_logic_vector( 3 downto 0) :="0000" ;
signal wait_count : std_logic_vector( 19 downto 0) := (others=>'0') ;
signal hour10_reg, hour1_reg , min10_reg , min1_reg , second10_reg, second1_reg : std_logic_vector( 7 downto 0) ;
signal state_count : std_Logic_vector (4 downto 0) ;
signal key_q : std_logic_vector( 0 to 15 ) ;
signal wait_1sec : integer range 0 to 239999 := 0 ;
attribute mark_debug : string ;
attribute mark_debug of key_q : signal is "true" ;
attribute mark_debug of lcd_e : signal is "true" ;
attribute mark_debug of lcd_rs : signal is "true" ;
attribute mark_debug of data_bus : signal is "true" ;
--attribute mark_debug of hour10_reg : signal is "true" ;
-- attribute mark_debug of hour1_reg : signal is "true" ;
-- attribute keep : string ; ------- keep attribute to debug a state
-- attribute keep of state :signal is "true" ;
-- attribute keep of next_command :signal is "true" ;
begin
---------------=============================
lcd_display_string <=( X"45" , X"4E" , X"54" ,X"45" , X"52" , X"20" ,X"20" ,X"43" , X"44" , X"54" , X"20" , X"20" , X"54" , X"49" , X"4D" , X"45" ) ;
NEXT_CHAR <= lcd_display_string( conv_integer( str_count)) ;
---------===============================
process(clk )
begin
if (rst='1') then
key_q<=x"0000" ;
elsif rising_edge ( clk ) then
key_q <= key_in ;
end if ;
end process ;
------------------------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-----------------------
adt_string <=( x"41" ,x"44" ,x"54" , x"3a",x"20" ,x"20" ) ;
adt <= adt_string (conv_integer ( str_count ) ) ;
cdt_string <=(x"43" , x"44" , x"54" ,x"3a",x"20" ,x"20" );
cdt <= cdt_string ( conv_integer ( str_count)) ;
-- BIDIRECTIONAL TRI STATE LCD DATA BUS
data_out <= data_bus when lcd_rw_int = '0' else "ZZZZZZZZ";
-- LCD_RW PORT is assigned to it matching SIGNAL
rw <= lcd_rw_int;
e<=lcd_e ;
rs <=lcd_rs ;
process ( clk )
begin
if rising_edge ( clk) then
if ( rst='1') then
clock_count <=(others=>'0') ;
clk_enable400<='0' ;
else
if ( clock_count <= 416) then -----------240 khz enable signal for zedboard working 100 mhz
clock_count <= clock_count +1 ;
clk_enable400 <='0' ;
else
clock_count<=(others=>'0') ;
clk_enable400 <='1';
end if ;
end if ;
end if ;
end process ;
------------------------------------------------------------------
---------------statemachine cotnrol-----------------------------
--------------------------------------------------------------------
process ( clk,rst)
begin
if (rst='1') then
state <= power_up;
data_bus <= x"38"; -- RESET ---default
next_command <= reset1;
lcd_e <= '1'; ------------enableing data in 120 khz half of the clk_enable
lcd_rs <= '0';
lcd_rw_int <= '0';
str_count <= "0000" ;
wait_count <=(others=>'0') ;
hour10_reg <=(others=> '0') ;
hour1_reg <=(others=> '0') ;
min10_reg <=(others=> '0') ;
min1_reg <=(others=> '0') ;
second10_reg <=(others=> '0') ;
second1_reg <=(others=> '0') ;
state_count<=(others=>'0') ;
elsif rising_edge(clk) then
if clk_enable400 = '1' then
case (state ) is
when power_up =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"38"; -- EXTERNAL RESET
state <= drop_lcd_e;
if ( wait_count =512) then ------ testing
wait_count <=(others=>'0') ;
next_command <= reset1; ----500 ms reached
else
wait_count <= wait_count +1 ;
end if ;
char_count <= "00000";
--======================= INITIALIZATION START ============================--
when reset1 =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"38"; -- EXTERNAL RESET
state <= drop_lcd_e;
-- next_command <= reset2;
-- if ( wait_count =250) then ------ working
if ( wait_count =120) then ------ testing
wait_count <=(others=>'0') ;
next_command <= reset2; ----500 ms reached
else
wait_count <= wait_count +1 ;
end if ;
char_count <= "00000";
when reset2 =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"38"; -- EXTERNAL RESET
state <= drop_lcd_e;
next_command <= reset3;
when reset3 =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"38"; -- EXTERNAL RESET
state <= drop_lcd_e;
next_command <= func_set;
-- Function Set
--==============--
when func_set =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"38"; -- Set Function to 8-bit transfer, 2 line display and a 5x8 Font size
state <= drop_lcd_e;
next_command <= display_off; ---default working
-- next_command <= display_clear;
-- Turn off Display
--==============--
when display_off =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"08"; -- Turns OFF the Display, Cursor OFF and Blinking Cursor Position OFF.......
-- data_bus <= x"0D"; -- (0F = Display ON and Cursor ON, Blinking cursor position ON)
state <= drop_lcd_e;
next_command <= display_clear;
-- Clear Display
--==============--
when display_clear =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"01"; -- Clears the Display
state <= drop_lcd_e;
next_command <= display_on;
-- Turn on Display and Turn off cursor
--===================================--
when display_on =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"0E"; -- Turns on the Display (0E = Display ON, Cursor ON and Blinking cursor OFF)
-- data_bus <= x"0D";
state <= drop_lcd_e;
next_command <= mode_set;
-- next_command <= char_mode;
-- next_command <= dram_address;------default working
-----------------enable while inputing from keypad
when cursor_shift =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"14";
state <= drop_lcd_e;
next_command <= mode_set;
when char_mode =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"17";
state <= drop_lcd_e;
next_command <= mode_set;
when dram_address =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= "10000000";
state <= drop_lcd_e;
-- next_command <= mode_set;
next_command <=hell;
-- Set write mode to auto increment address and move cursor to the right
--====================================================================--
when mode_set =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"06"; -- Auto increment address and move cursor to the right
-- data_bus <= x"07";
state <= drop_lcd_e;
-- next_command <=st1 ;
next_command <=hell;
-- next_command <=adt_state ;
-- next_command <= dram_address;------default working
-----------------added for keypad input ------------------
when hell=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"45"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=str2 ;
when str2=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"42"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=str3 ;
when str3=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"43"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=str4 ;
when str4=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"44"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
-- next_command <=return_home;
next_command <=second_LIne;
when second_LIne =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"C0"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <= second_line_data ;
when second_line_data=>
-- lcd_e <= '1'; ---default one
-- lcd_rs <= '1';
-- lcd_rw_int <= '0';
-- state <= drop_lcd_e;
-- data_bus <=x"20" ;
next_command<=return_home;
-- if (key_q=x"0100" ) then ------ 0
-- data_bus <= x"30" ;
-- hour10_reg <= data_bus ;
-- state <= drop_lcd_e;
-- next_command<=st2;
-- end if ;
if ( key_q =x"0004" ) then ------1
data_bus <= x"31" ;
hour1_reg <= data_bus ;
state <= drop_lcd_e;
-- next_command<=st2;
next_command<=one;
end if ;
if ( key_q =x"0008") then ----- 2
data_bus <=x"32" ;
state <= drop_lcd_e;
-- next_command<=st2;
next_command<=two;
end if ;
if (key_q=x"0010" ) then -------3
data_bus <= x"33" ;
state <= drop_lcd_e;
-- next_command<=st2;
next_command<=three;
end if ;
-- if (key_q=x"0002" ) then -------4
-- data_bus <= x"34" ;
-- state <= drop_lcd_e;
-- next_command<=st2;
-- end if;
-- if (key_q=x"0040" ) then ------5
-- data_bus <= x"35" ;
-- state <= drop_lcd_e;
-- next_command<=st2;
-- end if ;
-- if (key_q=x"0200" ) then --------------6
-- data_bus <= x"36" ;
-- state <= drop_lcd_e;
-- next_command<=st2;
-- end if ;
-- if (key_q=x"0001" ) then ------ 7
-- data_bus <= x"37" ;
-- state <= drop_lcd_e;
-- next_command<=st2;
-- end if ;
-- if (key_q=x"0080" ) then ----- 8
-- data_bus <= x"38" ;
-- state <= drop_lcd_e;
-- next_command<=st2;
-- end if ;
-- if (key_q=x"0400" ) then ------ 9
-- data_bus <= x"39" ;
-- state <= drop_lcd_e;
-- next_command<=st2;
-- end if ;
-- if (key_q=x"0100" ) then ------ 0
-- data_bus <= x"30" ;
-- state <= drop_lcd_e;
-- next_command<=st2;
-- end if ;
if (key_q=x"0020" ) then ----A SHIFT THE CURSOR TO THE LIFT
data_bus <= x"04" ;
state <= drop_lcd_e;
-- next_command<=st2;
next_command<=forward;
end if ;
if (key_q=x"1000" ) then ---B SHIFT THE DISPLAY AND CURSOR POSITION TO RIGHT
data_bus <= x"06" ;
state <= drop_lcd_e;
-- next_command<=st2;
next_command<=backward;
end if ;
when one=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"31"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=st2 ;
when two=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"32"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=st2 ;
when three=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"33"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=st2 ;
when forward=>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"04"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=delay ;
when backward=>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"06"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=delay ;
when third_line =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <= x"97"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <= third_line_data ;
when third_line_data=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"33"; -- Auto increment address and move cursor to the right
state <= drop_lcd_e;
next_command <=return_home ;
when st1=>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
if ( key_q =x"0004" ) then ------1
data_bus <= x"31" ; ---c0 default ---working
state <= drop_lcd_e;
next_command<=st2;
end if ;
if ( key_q =x"0008") then ----- 2
lcd_e <= '1';
data_bus <=x"32" ;
state <= drop_lcd_e;
next_command<=st2;
end if ;
if (key_q=x"0010" ) then -------3
data_bus <= x"33" ;
state <= drop_lcd_e;
next_command<=st2;
end if ;
if (key_q=x"0002" ) then -------4
data_bus <= x"34" ;
state <= drop_lcd_e;
next_command<=st2;
end if;
if (key_q=x"0040" ) then ------5
data_bus <= x"35" ;
state <= drop_lcd_e;
next_command<=st2;
end if ;
if (key_q=x"0200" ) then --------------6
data_bus <= x"36" ;
state <= drop_lcd_e;
next_command<=st2;
end if ;
if (key_q=x"0001" ) then ------ 7
data_bus <= x"37" ;
state <= drop_lcd_e;
next_command<=st2;
end if ;
if (key_q=x"0080" ) then ----- 8
data_bus <= x"38" ;
state <= drop_lcd_e;
next_command<=st2;
end if ;
if (key_q=x"0400" ) then ------ 9
data_bus <= x"39" ;
state <= drop_lcd_e;
next_command<=st2;
end if ;
if (key_q=x"0100" ) then ------ 0
data_bus <= x"30" ;
state <= drop_lcd_e;
next_command<=st2;
end if ;
if (key_q=x"0020" ) then -----cursor left a
data_bus <= x"10" ;
state <= drop_lcd_e;
next_command<=st3;
end if ;
if (key_q=x"1000" ) then ------cursor right b
data_bus <= x"1C" ;
state <= drop_lcd_e;
next_command<=st4;
end if ;
if (key_q=x"2000" ) then ---------clear all c
data_bus <= x"01" ;
state <= drop_lcd_e;
next_command<=display_clear;
end if ;
if (key_q=x"4000" ) then -------return home d
data_bus <= x"02" ;
state <= drop_lcd_e;
next_command<=RETURN_HOME;
end if ;
if (key_q=x"0800" ) then -------enter time #
data_bus <= x"01" ;
state <= drop_lcd_e;
next_command<=ST5;
end if ;
if (key_q=x"8000" ) then -------save and exit *
data_bus <= x"02" ;
state <= drop_lcd_e;
next_command<=RETURN_HOME;
end if ;
when st2=>
lcd_e <= '0';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <=x"20";
wait_1sec <= wait_1sec+1 ;
if ( wait_1sec=60000) then ---- .5 sec wait
wait_1sec <=0 ;
-- state<=second_line_data ; -----working
state<=second_line_data ;
end if ;
when delay=>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
data_bus <=x"20";
wait_1sec <= wait_1sec+1 ;
if ( wait_1sec=60000) then ---- .5 sec wait
wait_1sec <=0 ;
state<=second_line_data ;
end if ;
when st3=> ----CURSOR LEFT
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
-- data_bus <= x"10" ;
data_bus <= x"04" ;
state <= drop_lcd_e;
next_command<=second_line_data;
when st4=> ---CURSOR RIGHT
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
-- data_bus <= x"1C" ;
data_bus <= x"06" ;
state <= drop_lcd_e;
next_command<=second_line_data;
when st5 =>
lcd_e <= '1';
lcd_rs <= '1';
lcd_rw_int <= '0';
data_bus <= x"41" ;
state <= drop_lcd_e;
next_command<=return_home;
-------------------xxxxxxxxx---------------------------------
when return_home =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_rw_int <= '0';
-- data_bus <= x"80"; ---working
data_bus <= x"02"; ----just now commented
state <= drop_lcd_e;
-- next_command <=adt_state ;
next_command <=hell ;
-- 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_e =>
state <= next_command;
lcd_e <= '0';
end case ;
end if ;
end if ;
end process ;
end Behavioral;-- Company:
No comments:
Post a Comment