Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

LCD DE2-115 Initialization poblem

Hello everyone!! I'm trying to initialize LCD in the DE2-115 board. I know that the LCD is based in HDD44780U and I have following the datasheet to initialize it but the LCD turns crazy.

See my Initiazitaion code:


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY lcd IS
  PORT(
    clock_50        : IN    STD_LOGIC; 
    reset_n    : IN    STD_LOGIC;  
    lcd_enable : IN    STD_LOGIC; 
    lcd_bus    : IN    STD_LOGIC_VECTOR(9 DOWNTO 0);  -- DATOS Y CONTROL
    busy       : OUT   STD_LOGIC := '1';  -- LIBRE/OCUPADO
    lcd_rw, lcd_rs, lcd_en  : OUT   STD_LOGIC;  --read/write, setup/data y ENABLE
     lcd_on: out std_logic:='1';
--     lcd_blon: out std_logic:='1';
    lcd_data   : OUT   STD_LOGIC_VECTOR(7 DOWNTO 0)); -- DATOS HACIA LCD
END lcd;
ARCHITECTURE controller OF lcd IS
  TYPE CONTROL IS(power_up, initialize, ready, send);
  SIGNAL    state      : CONTROL;
  CONSTANT  freq       : INTEGER := 50; -- 50 Mhz
BEGIN
  PROCESS(clock_50)
    VARIABLE clk_count : INTEGER := 0; --Contador de timming
  BEGIN
  IF(clock_50'EVENT and clock_50 = '1') THEN
        
      CASE state IS
        
        -- Espera de 50 ms para inicilización de Vcc
        WHEN power_up =>
          busy <= '1';
          IF(clk_count < (50000 * freq)) THEN    --espera de 50 ms
            clk_count := clk_count + 1;
            state <= power_up;
          ELSE                                   --power-up completado
            clk_count := 0;
            lcd_rs <= '0';
            lcd_rw <= '0';
            lcd_data <= "00110000";
            state <= initialize;
          END IF;
        -- Inicialización de LCD
        WHEN initialize =>
          busy <= '1';
          clk_count := clk_count + 1;
          IF(clk_count < (40 * freq)) THEN       -- espera de 10us
            lcd_data <= "00111100";      --2-line mode, display on
            --lcd_data <= "00110100";    --1-line mode, display on
            --lcd_data <= "00110000";    --1-line mdoe, display off
            --lcd_data <= "00111000";    --2-line mode, display off
            lcd_en <= '1';
            state <= initialize;
--          ELSIF(clk_count < (50 * freq)) THEN    --espera de 50 us
--            lcd_data <= "00000000";
--            lcd_en <= '0';
--            state <= initialize;
          ELSIF(clk_count < (80 * freq)) and (clk_count > (40 * freq)) THEN    --display on/off control
--            lcd_data <= "00001100";      --display on, cursor off, parpadeo off
--            lcd_data <= "00001101";    --display on, cursor off, parpadeo on
--            lcd_data <= "00001110";    --display on, cursor on, parpadeo off
           lcd_data <= "00001111";    --display on, cursor on, parpadeo on
            --lcd_data <= "00001000";    --display off, cursor off, parpadeo off
            --lcd_data <= "00001001";    --display off, cursor off, parpadeo on
            --lcd_data <= "00001010";    --display off, cursor on, parpadeo off
            --lcd_data <= "00001011";    --display off, cursor on, parpadeo on            
            lcd_en <= '1';
            state <= initialize;
--          ELSIF(clk_count < (120 * freq)) THEN   --espera 50 us
--            lcd_data <= "00000000";
--            lcd_en <= '0';
--            state <= initialize;
          ELSIF (clk_count > (80 * freq)) and (clk_count < (1610 * freq)) THEN   -- limpiado de pantalla
            lcd_data <= "00000001";
            lcd_en <= '1';
            state <= initialize;
--          ELSIF(clk_count < (1620 * freq)) THEN  --espera 2 ms
--            lcd_data <= "00000000";
--            lcd_en <= '0';
--            state <= initialize;
          ELSIF(clk_count < (1650 * freq)) and (clk_count > (1610 * freq)) THEN  --entry mode set // espera 10 us
            lcd_data <= "00000110";      --increment mode, entire shift off
            --lcd_data <= "00000111";    --increment mode, entire shift on
            --lcd_data <= "00000100";    --decrement mode, entire shift off
            --lcd_data <= "00000101";    --decrement mode, entire shift on
            lcd_en <= '1';
            state <= initialize;
          ELSIF(clk_count < (2200 * freq)) THEN  --wait 60 us
            lcd_data <= "00000000";
            lcd_en <= '0';
            state <= initialize;
          ELSE                                   --inicialización completada
            clk_count := 0;
            busy <= '0';
            state <= ready;
          END IF;    
       
        -- Espera al enable para el correcto envio de datos
        WHEN ready =>
          IF(lcd_enable = '1') THEN
            busy <= '1';
            lcd_rs <= lcd_bus(9);
            lcd_rw <= lcd_bus(8);
            lcd_data <= lcd_bus(7 DOWNTO 0);
            clk_count := 0;            
            state <= send;
          ELSE
            busy <= '0';
            lcd_rs <= '0';
            lcd_rw <= '0';
            lcd_data <= "00000000";
            clk_count := 0;
            state <= ready;
          END IF;
        
        --send instruction to lcd        
        WHEN send =>
        busy <= '1';
        IF(clk_count < (35 * freq)) THEN  --do not exit for 50us
           busy <= '1';
           IF(clk_count < 3*freq) THEN      --negative enable
           lcd_en <= '0';
           ELSIF(clk_count < (8 * freq)) THEN  --positive enable half-cycle
           lcd_en <= '1';
           ELSIF(clk_count < (34* freq)) THEN  --negative enable half-cycle
           lcd_en <= '0';
           END IF;
           clk_count := clk_count + 1;
           state <= send;
        ELSE
          clk_count := 0;
          state <= ready;
        END IF;
      END CASE;    
    
      --reset
      IF(reset_n = '0') THEN
          state <= power_up;
      END IF;
    
    END IF;
  END PROCESS;
END controller;

And see my example to print in the lcd:


LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY lcd_example IS
  PORT(
      clock_50      : IN  STD_LOGIC; 
      lcd_rw, lcd_rs, lcd_en : OUT STD_LOGIC;  
        lcd_on: out std_logic:='1';
--        lcd_blon: out std_logic:='1';
      lcd_data  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
       &nbsp;); 
END lcd_example;
ARCHITECTURE behavior OF lcd_example IS
  SIGNAL   lcd_enable : STD_LOGIC;
  SIGNAL   lcd_bus    : STD_LOGIC_VECTOR(9 DOWNTO 0);
  SIGNAL   lcd_busy   : STD_LOGIC;
  COMPONENT lcd IS
    PORT(
       clock_50        : IN  STD_LOGIC; 
       reset_n    : IN  STD_LOGIC; 
       lcd_enable : IN  STD_LOGIC; 
       lcd_bus    : IN  STD_LOGIC_VECTOR(9 DOWNTO 0); 
       busy       : OUT STD_LOGIC; 
       lcd_rw, lcd_rs, lcd_en  : OUT STD_LOGIC; 
         lcd_on: out std_logic:='1';
         lcd_blon: out std_logic:='1';
       lcd_data   : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
  END COMPONENT;
BEGIN
  --Instanciación
  dut: lcd
    PORT MAP(clock_50=> clock_50, reset_n => '1', lcd_enable => lcd_enable, lcd_bus => lcd_bus, 
             busy => lcd_busy, lcd_rw => lcd_rw, lcd_rs => lcd_rs, lcd_en => lcd_en, lcd_on=>lcd_on, lcd_data => lcd_data);
  
  PROCESS(clock_50)
    VARIABLE char  :  INTEGER RANGE 0 TO 10 := 0;
  BEGIN
    IF(clock_50'EVENT AND clock_50 = '1') THEN
      IF(lcd_busy = '0' AND lcd_enable = '0') THEN
        lcd_enable <= '1';
        IF(char < 10) THEN
          char := char + 1;
        END IF;
        CASE char IS
          WHEN 1 => lcd_bus <= "1000110001";
          WHEN 2 => lcd_bus <= "1000110010";
          WHEN 3 => lcd_bus <= "1000110011";
          WHEN 4 => lcd_bus <= "1000110100";
          WHEN 5 => lcd_bus <= "1000110101";
          WHEN 6 => lcd_bus <= "1000110110";
          WHEN 7 => lcd_bus <= "1000110111";
          WHEN 8 => lcd_bus <= "1000111000";
          WHEN 9 => lcd_bus <= "1000111001";
          WHEN OTHERS => lcd_enable <= '0';
        END CASE;
      ELSE
        lcd_enable <= '0';
      END IF;
    END IF;
  END PROCESS;
  
END behavior;

is there anyone could help me?

Thank you very much.
No RepliesBe the first to reply