Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

LCD <--> VHDL small problem in code

Status
Not open for further replies.

mobile-it

Advanced Member level 1
Joined
Apr 24, 2004
Messages
464
Helped
22
Reputation
44
Reaction score
8
Trophy points
1,298
Activity points
3,344
lcd vhdl

Hi all,

I have found an LCD controller for use on my FPGA. but when I try to write some text to it, it shows the text but there are 2 small problems in it.

I want to display the text: "http://www.fpga.be XIOS" but this leads to (on the LCD): http:/"www.fpgf.be XIOS".


Can someone help me out? Very much thank you!

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity lcd is
    Port ( lcd_data : out std_logic_vector (7 downto 4);
           clk        : in std_logic;
		   reset      : in std_logic;
		   lcd_enable : out std_logic;
           lcd_rs : out std_logic;
 		   lcd_rw : out std_logic );
end lcd ;

architecture behavioural of lcd is

type state_type is (warmup, setfunc, clear1, clear2, setmode1, setmode2, write1, home1, home2);

signal state : state_type;

attribute syn_state_machine : boolean;
attribute syn_state_machine of state : signal is true;  

signal count : std_logic_vector(3 downto 0);
signal finished : std_logic;         -- set high if done write cycle

signal  char_mode : std_logic_vector(1 downto 0);

--defining the display
constant N: integer :=8;
type arr is array (1 to N) of std_logic_vector(7 downto 0);
constant display_char1 : arr := 	(X"A0", --blank
							x"68", --h
							x"74", --t
							X"74", --t
							X"70", --p
							X"3A", --:
							X"2F", --/
							X"2F"); --/

constant display_char2 : arr := 	(X"77", --w
							x"77", --w
							x"77", --w
							X"2E", --.
							X"66", --f
							X"70", --p
							X"67", --g
							X"61"); --a

constant display_char3 : arr := 	(X"2E", --.
							x"62", --b
							x"65", --e
							X"88", --blank
							X"88", --blank
							X"88", --blank
							X"88", --blank
							X"88"); --blank

constant display_char4 : arr := 	(X"A0", --blank
							X"88", --blank
                            x"58", --X
							x"49", --I
							X"4F", --O
							X"53", --S
							X"88", --blank
							X"88"); --blank

signal display_char : arr;

begin
	lcd_rw <= '0';
    lcd_enable <= clk; --not clk;  -- this is very important! if enable is not pulsed, lcd will not write
	
    char_mode_process: process (char_mode)
    begin
        case char_mode  is
            when "00" =>
                display_char <= display_char1;
            when "01" =>
                display_char <= display_char2;
            when "10" =>
                display_char <= display_char3;
            when "11" =>
                display_char <= display_char4;
            when OTHERS  =>
                display_char <= display_char1;
    end case;
    end process;
    
    state_set: process (clk, reset, finished)
	begin
		if reset = '1' then
			count <= (others => '0');
            state <= warmup;--setfunc;            
            char_mode <= (others => '0');

		elsif (clk'event and clk = '1') then
			case state is
				when warmup =>
					lcd_rs <= '0';
					lcd_data <= "0011"; --"0000";  -- do nothing 
					if count = "0111" then  --0111
						count <= (others => '0');
						state <= setfunc;
					else
						count <= count + '1';
						state <= warmup;
					end if;
					
				when setfunc =>
					lcd_rs <= '0';
                    lcd_data <= "0010";
                    finished <= '0';

                    if count = "0010" then  --0010
						count <= (others => '0');
						state <= clear1;
                    else
						count <= count + '1';
                        state <= setfunc;
					end if;
				
                when clear1 =>
                 
					lcd_rs <= '0';
                    lcd_data <= "0000";
                    state <= clear2;
				
                when clear2 =>
				  lcd_rs <= '0';
                  if count = "0111" then                 
                    state <= setmode1;
                    count <= (others => '0');
                    lcd_data <= "1111";
                  else
                    count <= count + '1';
                    lcd_data <= "0001";
                    state <= clear1;
                  end if;
                    				
				when setmode1 =>
					lcd_rs <= '0';
                    lcd_data <= "0000";
					state <= setmode2;
                    finished <= '0';
				
                when setmode2 =>
					lcd_rs <= '0';
                    lcd_data <= "0110";
					state <= write1;
                                       											
				when write1 =>
					if finished = '1' then
						state <= home1;
					else					
						lcd_rs <= '1';
						count  <= count  + '1';
						state <= write1;
						CASE count IS
							WHEN "0000" =>
							    lcd_data <= display_char(1)(7 downto 4);
                            WHEN "0001" =>
							    lcd_data <= display_char(1)(3 downto 0);
                            WHEN "0010" =>
								lcd_data <= display_char(2)(7 downto 4);
							WHEN "0011" =>
							    lcd_data <= display_char(2)(3 downto 0);
							WHEN "0100"=>
								lcd_data <= display_char(3)(7 downto 4);			    		
							WHEN "0101"=>
								lcd_data <= display_char(3)(3 downto 0);
							WHEN "0110"=>
							    lcd_data <= display_char(4)(7 downto 4);
						    WHEN "0111"=>
							    lcd_data <= display_char(4)(3 downto 0);
							WHEN "1000" =>
							    lcd_data <= display_char(5)(7 downto 4);
						    WHEN "1001" =>
							    lcd_data <= display_char(5)(3 downto 0);
							WHEN "1010" =>
							    lcd_data <= display_char(6)(7 downto 4);
                            WHEN "1011" =>
							    lcd_data <= display_char(6)(3 downto 0);
							WHEN "1100" =>
							    lcd_data <= display_char(7)(7 downto 4);
                            WHEN "1101" =>
							    lcd_data <= display_char(7)(3 downto 0);
                            WHEN "1110" =>
							    lcd_data <= display_char(8)(7 downto 4);
		    				    finished <= '1';  -- needed to set done low before valid data is gone
                                char_mode  <= char_mode + '1';
                            WHEN OTHERS =>
							    lcd_data <= "0000";  -- ' '
						END CASE;
					end if;              
                when home1 =>
					lcd_rs <= '0';
                    lcd_data <= "0000";
					state <= home2;
                    finished <= '0';
                    count <= (others => '0');				
                when home2 =>
					lcd_rs <= '0';
                    lcd_data <= "0111";
					state <= write1;               
			end case;
		end if;
	end process;
	
end behavioural;
 

vhdl lcd

You do not output

Code:
display_char(8)(3 downto 0);

nibble.

In any case the code seems to be very cumbersome. Why do not to use some bits of the counter as array index for example?
 

    mobile-it

    Points: 2
    Helpful Answer Positive Rating
lcd controller vhdl

Thank you,

I use this VHDL snippet for learning purposes, (I have found it somewhere).

Added after 16 minutes:

The text on the LCD is still not correct.

Added after 2 hours 25 minutes:

Ok,


I did a download from the ACTEL website of the new example on the ProASIC3 (the FPGA I am working on) and write the contents to the FROM and then everything works... I think I will go further with this example to create my application; I need to change the FROM to some memory on the FPGA because I can't write to the FROM from the FPGA silicon. (The FROM is used for security purposes etc.).


thanks for your help
 

vhdl lcd controller

You were not outputting the last nibble of the 8th character. I hope it will work fine.

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity lcd is
    Port ( lcd_data   : out std_logic_vector (7 downto 4);
           clk        : in  std_logic;
           reset      : in  std_logic;
           lcd_enable : out std_logic;
           lcd_rs     : out std_logic;
           lcd_rw     : out std_logic
         );
end lcd ;

architecture behavioural of lcd is

    type state_type is (warmup, setfunc, clear1, clear2, setmode1, setmode2, write1, home1, home2);

    signal state : state_type;

    attribute syn_state_machine : boolean;
    attribute syn_state_machine of state : signal is true;

    signal count    : std_logic_vector(3 downto 0);
    signal finished : std_logic;         -- set high if done write cycle

    signal  char_mode : std_logic_vector(1 downto 0);

    --defining the display
    constant N: integer :=8;
    type arr is array (1 to N) of std_logic_vector(7 downto 0);

    constant display_char1 : arr :=    (x"A0",  --blank
                                        X"68",  --h
                                        X"74",  --t
                                        X"74",  --t
                                        X"70",  --p
                                        X"3A",  --:
                                        X"2F",  --/
                                        X"2F"); --/

    constant display_char2 : arr :=    (X"77",  --w
                                        X"77",  --w
                                        X"77",  --w
                                        X"2E",  --.
                                        X"66",  --f
                                        X"70",  --p
                                        X"67",  --g
                                        X"61"); --a

    constant display_char3 : arr :=    (X"2E",  --.
                                        X"62",  --b
                                        X"65",  --e
                                        X"88",  --blank
                                        X"88",  --blank
                                        X"88",  --blank
                                        X"88",  --blank
                                        X"88"); --blank

    constant display_char4 : arr :=    (X"A0",  --blank
                                        X"88",  --blank
                                        X"58",  --X
                                        X"49",  --I
                                        X"4F",  --O
                                        X"53",  --S
                                        X"88",  --blank
                                        X"88"); --blank

    signal display_char : arr;

begin
    lcd_rw <= '0';
    lcd_enable <= clk; --not clk;  -- this is very important! if enable is not pulsed, lcd will not write

    char_mode_process: process (char_mode)
    begin
        case char_mode  is
            when "00" =>
                display_char <= display_char1;
            when "01" =>
                display_char <= display_char2;
            when "10" =>
                display_char <= display_char3;
            when "11" =>
                display_char <= display_char4;
            when OTHERS  =>
                display_char <= display_char1;
         end case;
    end process;

    state_set: process (clk, reset, finished)
    begin
      if (reset = '1') then

         state     <= warmup;   --setfunc;
         count     <= (others => '0');
         char_mode <= (others => '0');

      elsif (clk'event and clk = '1') then
         case state is

            when warmup =>
               lcd_rs <= '0';
               lcd_data <= "0011"; --"0000";  -- do nothing
               if count = "0111" then  --0111
                  count <= (others => '0');
                  state <= setfunc;
               else
                  count <= count + '1';
                  state <= warmup;
               end if;

            when setfunc =>
               lcd_rs <= '0';
               lcd_data <= "0010";
               finished <= '0';

               if count = "0010" then  --0010
                  count <= (others => '0');
                  state <= clear1;
               else
                  count <= count + '1';
                  state <= setfunc;
               end if;

            when clear1 =>

               lcd_rs <= '0';
               lcd_data <= "0000";
               state <= clear2;

            when clear2 =>
               lcd_rs <= '0';
               if count = "0111" then
                    state <= setmode1;
                    count <= (others => '0');
                    lcd_data <= "1111";
               else
                    count <= count + '1';
                    lcd_data <= "0001";
                    state <= clear1;
               end if;

            when setmode1 =>
               lcd_rs   <= '0';
               lcd_data <= "0000";
               state    <= setmode2;
               finished <= '0';

            when setmode2 =>
               lcd_rs   <= '0';
               lcd_data <= "0110";
               state    <= write1;

            when write1 =>
               if finished = '1' then
                  state <= home1;
               else
                  lcd_rs <= '1';
                  count  <= count  + '1';
                  state  <= write1;

                  CASE count IS

                     WHEN "0000" =>
                         lcd_data <= display_char(1)(7 downto 4);

                     WHEN "0001" =>
                         lcd_data <= display_char(1)(3 downto 0);

                     WHEN "0010" =>
                         lcd_data <= display_char(2)(7 downto 4);

                     WHEN "0011" =>
                         lcd_data <= display_char(2)(3 downto 0);

                     WHEN "0100"=>
                         lcd_data <= display_char(3)(7 downto 4);

                     WHEN "0101"=>
                         lcd_data <= display_char(3)(3 downto 0);

                     WHEN "0110"=>
                         lcd_data <= display_char(4)(7 downto 4);

                     WHEN "0111"=>
                         lcd_data <= display_char(4)(3 downto 0);

                     WHEN "1000" =>
                         lcd_data <= display_char(5)(7 downto 4);

                     WHEN "1001" =>
                         lcd_data <= display_char(5)(3 downto 0);

                     WHEN "1010" =>
                         lcd_data <= display_char(6)(7 downto 4);

                     WHEN "1011" =>
                         lcd_data <= display_char(6)(3 downto 0);

                     WHEN "1100" =>
                         lcd_data <= display_char(7)(7 downto 4);

                     WHEN "1101" =>
                         lcd_data <= display_char(7)(3 downto 0);

                     WHEN "1110" =>
                         lcd_data <= display_char(8)(7 downto 4);
                         --finished <= '1';  -- needed to set done low before valid data is gone
                         --char_mode  <= char_mode + '1';

                    WHEN "1111" =>
                         lcd_data <= display_char(8)(3 downto 0);
                         finished <= '1';  -- needed to set done low before valid data is gone
                         char_mode  <= char_mode + '1';

                     WHEN OTHERS =>
                         lcd_data <= "0000";  -- ' '

                  END CASE;
               end if;

            when home1 =>
               lcd_rs <= '0';
               lcd_data <= "0000";
               state <= home2;
               finished <= '0';
               count <= (others => '0');

            when home2 =>
               lcd_rs <= '0';
               lcd_data <= "0111";
               state <= write1;

         end case;

      end if;

   end process;

end behavioural;
 

    mobile-it

    Points: 2
    Helpful Answer Positive Rating
lcd vhdl code

how it will work .
lcd_rw <= '0';
lcd_enable <= clk; --not clk; -- this is very important! if enable is not pulsed, lcd will not write

un-nessesory EN clk create problems.

i am working on the same project.
 

    mobile-it

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top