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.

2x16 LCD display program in VHDL

Status
Not open for further replies.

shilongo83

Newbie level 6
Newbie level 6
Joined
Apr 27, 2009
Messages
12
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,283
Visit site
Activity points
1,378
vhdl programs

I am in my second month of learning VHDL but I am good in Microprocessor (PIC16F84, 877) those are the chips I have been able to program.
I programed a 2x16 LCD using PIC-Microcontroller and now I want to have a program in VHDL using any 2x16 LCD display.

Can somebody please help, with a program that can display a word on the display "SHILONGO" and/or a clock/counter on the display.
 

lcd display programming

Here is some code I created when I was experimenting with VHDL. Note that it is/was intended as a learning experience, and is not optimized in any way (or should be considered good programming for that matter). State machines are used to do everything step by step.
'LCD_controller_main.vhd' (the 'entity' declaration that is) needs to be altered so it reflects 'your' hardware ...

Code:
--{******************************************************************************}
--{ FileName............: Lcd_controller_main.vhd
--{ Project.............: FPGA
--{------------------------------------------------------------------------------}
--{
--{ Notes: has some design flaws
--{
--{
--{ Physical 'Testbench' for LCD_CONTROLLER
--{ Output signals on prototyping board:
--{   J4-6  260 ns cycle signal 
--{   J4-8  1 ms cycle signal   (1 kHz)
--{   J4-10 0.2 ms cycle signal (5 kHz)
--{------------------------------------------------------------------------------}

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


--{------------------------------------------------------------------------------}
--{                       Xilinx primitives libraries used
--{------------------------------------------------------------------------------}
library UNISIM;
use UNISIM.VComponents.all; 


entity LCD_CONTROLLER_MAIN is
  port(
    CLK_SMT   : in  std_logic;

    PUSH_RESET: in  std_logic;
    PUSH      : in  std_logic_vector(2 downto 1);

    LCD_DB    : out std_logic_vector (7 downto 0);
    LCD_E     : out std_logic;
    LCD_RS    : out std_logic;

    PIEZO     : out std_logic;

    P1_LIO_A09: out std_logic;
    P1_LIO_A13: out std_logic;
    P1_LIO_A15: out std_logic
  );
end LCD_CONTROLLER_MAIN;


--{------------------------------------------------------------------------------}
--{                               Architecture
--{------------------------------------------------------------------------------}
architecture LCD_CONTROLLER of LCD_CONTROLLER_MAIN is
  component CLOCK_DIV is
    generic(
      CLK_TIMING_IN_NS : natural;                          -- Input clock cycle time (in ns)
      CLK_TIMING_OUT_NS: natural                           -- Input clock cycle time (in ns)
    );
    port(
      CLK_IN : in  std_logic;                              -- Input clock
      CLK_OUT: out std_logic                               -- Output clock
    );
  end component;

  component LCD_CONTROLLER is
    port(
      RST       : in  std_logic;                           -- Reset
      CLK       : in  std_logic;                           -- Clock (>= 250 ns cycle time)
      START     : in  std_logic;                           -- Start flag
      RS        : in  std_logic;                           -- Register select
      DATA      : in  std_logic_vector (7 downto 0);       -- Data
      E_PORT    : out std_logic;                           -- Enable signal port
      RS_PORT   : out std_logic;                           -- Register select port
      DATA_PORT : out std_logic_vector (7 downto 0);       -- Data port
      READY     : out std_logic                            -- Ready flag
    );
  end component;

  type tstate_main is (wait1, init1, init2, text1, text2, crlf1, crlf2, text3, text4, idle, 
                       crlf3, crlf4, press1, press2, press3, crlf5, crlf6, press4, press5, press6);
                      
  type ttextlength is range 16 downto 0;
  type tline       is array(ttextlength) of std_logic_vector (7 downto 0);
  type tinitlength is range 8 downto 0;
  type tinitdata   is array(tinitlength) of std_logic_vector (7 downto 0);

  constant init_data   : tinitdata := (x"38", x"38", x"38", x"38", x"06", x"0E", x"01", x"80", x"00");
  constant line1       : tline     := (x"20", x"20", x"20", x"20", x"20", x"4C", x"49", x"53",
                                       x"4D", x"41", x"52", x"20", x"20", x"20", x"20", x"20", x"00");
  constant line2       : tline     := (x"45", x"6E", x"67", x"69", x"6E", x"65", x"65", x"72",
                                       x"69", x"6E", x"67", x"20", x"42", x"2E", x"56", x"2E", x"00");
  constant line3       : tline     := (x"42", x"75", x"74", x"74", x"6F", x"6E", x"20", x"31",
                                       x"20", x"70", x"72", x"65", x"73", x"73", x"65", x"64", x"00");
  constant line4       : tline     := (x"42", x"75", x"74", x"74", x"6F", x"6E", x"20", x"32",
                                       x"20", x"70", x"72", x"65", x"73", x"73", x"65", x"64", x"00");

  signal state         : tstate_main;                      -- Current state main state amchine
  signal text_index    : ttextlength;                      -- Index counter
  signal init_index    : tinitlength;                      -- Index counter

  signal clk           : std_logic;                        -- Buffered master clock
  signal rst           : std_logic;                        -- Reset signal
  signal start         : std_logic;                        -- Start flag for writing to LCD
  signal ready         : std_logic;                        -- Ready flag (ready for writing to LCD)
  signal rs            : std_logic;                        -- RS data for LCD
  signal data          : std_logic_vector (7 downto 0);    -- Data to write to LCD

  signal clk_out : std_logic;                              -- LCD clock
  signal clk_1ms : std_logic;                              -- Timing signal (piezo)
  signal clk_02ms: std_logic;                              -- Timing signal (piezo)
  
  signal push1_p : std_logic_vector (3 downto 0);          -- Debouncing PUSH1 button   
  signal push1_d : std_logic;                              -- Debounced  PUSH1 button   
  signal push2_p : std_logic_vector (3 downto 0);          -- Debouncing PUSH2 button   
  signal push2_d : std_logic;                              -- Debounced  PUSH2 button   

begin
  CLK_250NS_I : CLOCK_DIV
    generic map (
      CLK_TIMING_IN_NS  => 13,
      CLK_TIMING_OUT_NS => 260
    )
    port map (
      CLK_IN  => clk,
      CLK_OUT => clk_out
    )
  ;


  CLK_1MS_I : CLOCK_DIV
    generic map (
      CLK_TIMING_IN_NS  => 13,
      CLK_TIMING_OUT_NS => 1000000
    )
    port map (
      CLK_IN  => clk,
      CLK_OUT => clk_1ms
    )
  ;

  CLK_02MS_I : CLOCK_DIV
    generic map (
      CLK_TIMING_IN_NS  => 13,
      CLK_TIMING_OUT_NS => 200000
    )
    port map (
      CLK_IN  => clk,
      CLK_OUT => clk_02ms
    )
  ;


  UUT : LCD_CONTROLLER
    port map (
      RST        => rst,
      CLK        => clk_out,
      START      => start,
      RS         => rs,
      DATA       => data,
      E_PORT     => LCD_E,
      RS_PORT    => LCD_RS,
      DATA_PORT  => LCD_DB,
      READY      => ready
    )
  ;

  --{------------------------------------------------------------------------------}
  --{ Descript: Clock buffering
  --{------------------------------------------------------------------------------}
  BUFGDLL_INST1: BUFGDLL
    port map (
      I => CLK_SMT,
      O => clk
    )
  ;    


  --{------------------------------------------------------------------------------}
  --{ Params  : <clk_1ms>  Clock
  --{ Descript: Debounce the input. This is done by checking the
  --{           input for a number of cycles and when all of them are
  --{           equal the output changes.
  --{------------------------------------------------------------------------------}
  process (clk_1ms)
  begin
    if (rising_edge(clk_1ms)) then
      push1_p(0) <= not(PUSH(1));
      push1_p(1) <= push1_p(0);
      push1_p(2) <= push1_p(1);
      push1_p(3) <= push1_p(2);
      if (push1_p = "1111") then
        push1_d <= '1';
      else
        if (push1_p = "0000") then
          push1_d <= '0';
        end if;
      end if;
    end if;
  end process;
  
  
  process (clk_1ms)
  begin
    if (rising_edge(clk_1ms)) then
      push2_p(0) <= not(PUSH(2));
      push2_p(1) <= push2_p(0);
      push2_p(2) <= push2_p(1);
      push2_p(3) <= push2_p(2);
      if (push2_p = "1111") then
        push2_d <= '1';
      else
        if (push2_p = "0000") then
          push2_d <= '0';
        end if;
      end if;
    end if;
  end process;
  
  --{------------------------------------------------------------------------------}
  --{                                 Main state machine
  --{------------------------------------------------------------------------------}
  
  --{------------------------------------------------------------------------------}
  --{ Params  : <clk>  Clock
  --{           <rst>  Reset
  --{ Descript: Main state machine: State register
  --{------------------------------------------------------------------------------}
  process (clk, rst)
  begin
    if (rst = '1') then
      start <= '0';
      state <= wait1;
    else
      if (rising_edge(clk)) then
        case state is
          when wait1  => start  <= '0';                    -- Make sure LCD sequence stops
                         state  <= init1;
                         init_index <= tinitlength'HIGH;
          when init1  => if (ready = '1') then             -- Wait for LCD ready to accept command
                           data       <= init_data(init_index);
                           init_index <= init_index - 1;
                           start      <= '1';              -- Start LCD sequence
                           rs         <= '0';
                           state      <= init2;
                         end if;
          when init2  => if (ready = '0') then             -- Wait for LCD sequence started
                           start <= '0';                   -- Make sure sequence not automatically restarted
                           if (init_index = 0) then        -- Did we just send the last initialization data?
                             state      <= text1;
                             text_index <= ttextlength'HIGH;
                           else
                             state <= init1;
                           end if;  
                         end if;

          when text1  => if (ready = '1') then             -- Wait for LCD ready to accept command
                           data       <= line1(text_index);
                           text_index <= text_index - 1;
                           start      <= '1';              -- Start LCD sequence
                           rs         <= '1';
                           state      <= text2;
                         end if;
          when text2  => if (ready = '0') then             -- Wait for LCD sequence started
                           start <= '0';                   -- Make sure sequence not automatically restarted
                           if (text_index = 0) then        -- Did we just send the last text line 1 data?
                             state <= crlf1;
                           else
                             state <= text1;
                           end if;  
                         end if;
          when crlf1  => if (ready = '1') then             -- Wait for LCD ready to accept command
                           data       <= x"C0";            -- DDRAM Address set: address $40 (2nd line)
                           start      <= '1';              -- Start LCD sequence
                           rs         <= '0';
                           state      <= crlf2;
                         end if;
          when crlf2  => if (ready = '0') then             -- Wait for LCD sequence started
                           start      <= '0';              -- Make sure sequence not automatically restarted
                           state      <= text3;
                           text_index <= ttextlength'HIGH;
                         end if;
          when text3  => if (ready = '1') then             -- Wait for LCD ready to accept command
                           data       <= line2(text_index);
                           text_index <= text_index - 1;
                           start      <= '1';              -- Start LCD sequence
                           rs         <= '1';
                           state      <= text4;
                         end if;
          when text4  => if (ready = '0') then             -- Wait for LCD sequence started
                           start <= '0';                   -- Make sure sequence not automatically restarted
                           if (text_index = 0) then        -- Did we just send the last text line 2 data?
                             state <= idle;
                           else
                             state <= text3;
                           end if;  
                         end if;
                         
          when idle   => if (push1_d = '1') then
                           state <= crlf3;
                         else
                           if (push2_d = '1') then
                             state <= crlf5;
                           else
                             state <= idle;
                           end if;
                         end if;
                          
          when crlf3  => if (ready = '1') then             -- Wait for LCD ready to accept command
                           data       <= x"80";            -- DDRAM Address set: address $00 (1st line)
                           start      <= '1';              -- Start LCD sequence
                           rs         <= '0';
                           state      <= crlf4;
                         end if;
          when crlf4  => if (ready = '0') then             -- Wait for LCD sequence started
                           start      <= '0';              -- Make sure sequence not automatically restarted
                           state      <= press1;
                           text_index <= ttextlength'HIGH;
                         end if;
          when press1 => if (ready = '1') then             -- Wait for LCD ready to accept command
                           data       <= line3(text_index);
                           text_index <= text_index - 1;
                           start      <= '1';              -- Start LCD sequence
                           rs         <= '1';
                           state      <= press2;
                         end if;
          when press2 => if (ready = '0') then             -- Wait for LCD sequence started
                           start <= '0';                   -- Make sure sequence not automatically restarted
                           if (text_index = 0) then        -- Did we just send the last text line 1 data?
                             state <= press3;
                           else
                             state <= press1;
                           end if;  
                         end if;
          when press3 => if (push1_d = '1') then
                            state <= press3;
                          else
                            state <= wait1;
                          end if;  
                          
          when crlf5  => if (ready = '1') then             -- Wait for LCD ready to accept command
                           data       <= x"80";            -- DDRAM Address set: address $00 (1st line)
                           start      <= '1';              -- Start LCD sequence
                           rs         <= '0';
                           state      <= crlf6;
                         end if;
          when crlf6  => if (ready = '0') then             -- Wait for LCD sequence started
                           start      <= '0';              -- Make sure sequence not automatically restarted
                           state      <= press4;
                           text_index <= ttextlength'HIGH;
                         end if;
          when press4 => if (ready = '1') then             -- Wait for LCD ready to accept command
                           data       <= line4(text_index);
                           text_index <= text_index - 1;
                           start      <= '1';              -- Start LCD sequence
                           rs         <= '1';
                           state      <= press5;
                         end if;
          when press5 => if (ready = '0') then             -- Wait for LCD sequence started
                           start <= '0';                   -- Make sure sequence not automatically restarted
                           if (text_index = 0) then        -- Did we just send the last text line 1 data?
                             state <= press6;
                           else
                             state <= press4;
                           end if;  
                         end if;
          when press6 => if (push2_d = '1') then
                            state <= press6;
                          else
                            state <= wait1;
                          end if;  
          
          when others  => state <= wait1;
        end case;
      end if;
    end if;  
  end process;   
  
  rst <= not PUSH_RESET;
  P1_LIO_A09 <= clk_out;
  P1_LIO_A13 <= clk_1ms;
  P1_LIO_A15 <= clk_02ms;
  
  PIEZO <= (clk_1ms and push1_d) or (clk_02ms and push2_d);


end LCD_CONTROLLER;

Code:
--{******************************************************************************}
--{ FileName............: Lcd_controller.vhd
--{ Project.............: FPGA
--{------------------------------------------------------------------------------}
--{
--{ Component for controlling a Seiko KS0066 based character LCD (write only)
--{
--{ The LCD has the following connections:
--{   DATAx_PORT  Databus bits 0..7
--{   E_PORT      Enable
--{   RS_PORT     Register select
--{
--{ Timing issues (writing):
--{   E    Cycle time    : min 500 ns
--{        Pulse width   : min 230 ns (high level)
--{        Rise/fall time: max  20 ns
--{   RS   Setup time    : min  40 ns before rising  edge E
--{        Hold  time    : min  10 ns after  falling edge E
--{   DBx  Setup time    : min  80 ns before falling edge E
--{                                   data is clocked in at falling edge of E
--{        Hold  time    : min  10 ns after  falling edge E
--{ After power up a 15 ms delay is required
--{
--{   A LCD command takes some time to complete, depending on the type of command.
--{   Typically commands are executed in 40 us. Others can take up to 1.7 ms
--{------------------------------------------------------------------------------}

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


--{------------------------------------------------------------------------------}
--{ Params  : <RST>            Reset
--{           <CLK>            Input clock (must be clock with cycle time close to 250 ns)
--{           <START>          Start sequence when '1'
--{                            Only validated when <READY>
--{                            Note that the caller must remove the signal after
--{                            <READY> becomes false, otherwise the sequence will
--{                            be repeated once it is done
--{           <E>              Enable signal
--{           <RW>             R/W signal
--{           <RS>             Register selection
--{                            Latched when sequence starts
--{           <DATA>           Data
--{                            Latched when sequence starts
--{           <E_PORT>         Enable signal port
--{           <RS_PORT>        RS port
--{           <DATAx_PORT>     Data bit ports
--{           <READY>          Ready status (ready to start a new sequecne)
--{ Descript: LCD component (based on KS0066 chipset), write only
--{------------------------------------------------------------------------------}
entity LCD_CONTROLLER is
  port(
    RST       : in  std_logic;                             -- Reset
    CLK       : in  std_logic;                             -- Clock (>= 250 ns cycle time)
    START     : in  std_logic;                             -- Start flag
    RS        : in  std_logic;                             -- Register select
    DATA      : in  std_logic_vector (7 downto 0);         -- Data
    E_PORT    : out std_logic;                             -- Enable signal port
    RS_PORT   : out std_logic;                             -- Register select port
    DATA_PORT : out std_logic_vector (7 downto 0);         -- Data port
    READY     : out std_logic                              -- Ready flag
  );
end LCD_CONTROLLER;


--{------------------------------------------------------------------------------}
--{                               Architecture
--{------------------------------------------------------------------------------}
architecture LCD_CONTROLLER of LCD_CONTROLLER is
  constant STARTDELAY   : natural := 60000;                -- Startup delay 15 ms (based on 250 ns clock)
  constant COMPLETEDELAY: natural := 7200;                 -- Command completion delay 1.8 ms (based on 250 ns clock)

  type   state_LCD  is (wait1, wait2, idle, set_rs, set_e_h, set_e_l, execw);

  signal state_now : state_lcd;                            -- Current state
  signal state_next: state_lcd;                            -- Next state

  signal e_next    : std_logic;                            -- Next E to write (to be registered)
  signal e_reg     : std_logic;                            -- Registered E (to be written)
  signal rs_next   : std_logic;                            -- Next RS to write (to be registered)
  signal rs_reg    : std_logic;                            -- Registered RS (to be written)
  signal data_next : std_logic_vector(7 downto 0);         -- Next data to write (to be registered)
  signal data_reg  : std_logic_vector(7 downto 0);         -- Registered data (to be written)
  signal ready_next: std_logic;                            -- Next READY to write (to be registered)
  signal ready_reg : std_logic;                            -- Registered READY (to be written)
  signal delay_reg : integer range 0 to STARTDELAY;        -- Delay counter (for start next state)
  signal delay_next: integer range 0 to STARTDELAY;        -- Delay counter (for start next state)


begin
  --{------------------------------------------------------------------------------}
  --{ Params  : <CLK>  Clock
  --{           <RST>  Reset
  --{ Descript: State machine: State register
  --{           The state register is updated
  --{           Using synchronuous reset
  --{------------------------------------------------------------------------------}
  process (CLK, RST)
  begin
    if (rising_edge(CLK)) then
      if (RST = '1') then
        delay_reg <= 0;
      else
        if (delay_reg = 0) then
          state_now <= state_next;
          delay_reg <= delay_next;
        else
          delay_reg <= delay_reg - 1;
        end if;      
      end if;  
    end if;
  end process;


  --{------------------------------------------------------------------------------}
  --{ Params  : <CLK>  Clock
  --{ Descript: State machine: Output buffer
  --{           The output registers are updated
  --{------------------------------------------------------------------------------}
  process (CLK)
  begin
    if (rising_edge(CLK)) then
      ready_reg <= ready_next;                             -- Register READY output
      data_reg  <= data_next;                              -- Register data output
      rs_reg    <= rs_next;                                -- Register RS output
      e_reg     <= e_next;                                 -- Register E output
    end if;
  end process;


  --{------------------------------------------------------------------------------}
  --{ Params  : <START>       Start flag
  --{           <RST>         Reset
  --{           <state_now>   Current state
  --{ Descript: State machine: Next state logic
  --{ Notes   : <delay_next> is the delay after the -next- state has been executed
  --{           and must be reset
  --{------------------------------------------------------------------------------}
  process (START, RST, state_now)
  begin
    if (RST = '1') then
      ready_next <= '0';
      e_next     <= '0';
      rs_next    <= '0';
      data_next  <= x"00";
      delay_next <= 0;
      state_next <= wait1;
    else
      case state_now is
        when wait1   => ready_next <= '0';
                        e_next     <= '0';
                        rs_next    <= rs_reg;
                        data_next  <= data_reg;
                        delay_next <= STARTDELAY;          -- Delay active after -next- state executes!
                        state_next <= wait2;
        when wait2   => ready_next <= ready_reg;
                        e_next     <= e_reg;
                        rs_next    <= rs_reg;
                        data_next  <= data_reg;
                        delay_next <= 0;
                        state_next <= idle;                -- STARTDELAY activated here
        when idle    => ready_next <= '1';                 -- Idle == ready == set ready flag
                        e_next     <= e_reg;
                        rs_next    <= rs_reg;
                        data_next  <= data_reg;
                        delay_next <= delay_reg;
                        if (START = '1') then
                          state_next <= set_rs;
                        else
                          state_next <= state_now;
                        end if;
        when set_rs  => ready_next <= '0';                 -- Sequence will start == reset ready flag
                        e_next     <= e_reg;
                        rs_next    <= RS;
                        data_next  <= data_reg;
                        delay_next <= delay_reg;
                        state_next <= set_e_h;
        when set_e_h => ready_next <= ready_reg;
                        e_next     <= '1';
                        rs_next    <= rs_reg;
                        data_next  <= DATA;
                        delay_next <= delay_reg;
                        state_next <= set_e_l;
        when set_e_l => ready_next <= ready_reg;
                        e_next     <= '0';
                        rs_next    <= rs_reg;
                        data_next  <= data_reg;
                        delay_next <= COMPLETEDELAY;       -- Completion of command delay
                        state_next <= execw;
        when execw   => ready_next <= ready_reg;
                        e_next     <= e_reg;
                        rs_next    <= rs_reg;
                        data_next  <= data_reg;
                        delay_next <= 0;
                        state_next <= idle;                -- COMPLETEDELAY activated here
        when others  => ready_next <= ready_reg;
                        e_next     <= e_reg;
                        rs_next    <= rs_reg;
                        data_next  <= data_reg;
                        delay_next <= delay_reg;
                        state_next <= wait1;
      end case;
    end if;
  end process;


  --{------------------------------------------------------------------------------}
  --{ Descript: Output
  --{           The actual outputs are set
  --{------------------------------------------------------------------------------}
  READY      <= ready_reg;
  E_PORT     <= e_reg;
  RS_PORT    <= rs_reg;
  DATA_PORT  <= data_reg;
end LCD_CONTROLLER;
Code:
--{******************************************************************************}
--{ FileName............: Clock_div.vhd
--{ Project.............: FPGA
--{------------------------------------------------------------------------------}
--{
--{ Component for dividing a clock
--{------------------------------------------------------------------------------}

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


--{------------------------------------------------------------------------------}
--{ Params  : <CLK_TIMING_IN_NS>   Speed (in ns) of input clock
--{           <CLK_TIMING_OUT_NS>  Speed (in ns) of required output clock
--{           <CLK_IN>             Input clock
--{           <CLK_OUT>            Output clock
--{ Descript: Clock divider component
--{------------------------------------------------------------------------------}
entity CLOCK_DIV is
  generic(
    CLK_TIMING_IN_NS : natural;                            -- Input clock cycle time (in ns)
    CLK_TIMING_OUT_NS: natural                             -- Input clock cycle time (in ns)
                                                           -- Should be multiple of CLK_TIMING_IN_NS otherwise actual timing is slightly less 
  );
  port(
    CLK_IN : in  std_logic;                                -- Input clock
    CLK_OUT: out std_logic                                 -- Output clock
  );
end CLOCK_DIV;


--{------------------------------------------------------------------------------}
--{                               Architecture
--{------------------------------------------------------------------------------}
architecture CLOCK_DIV of CLOCK_DIV is
  constant COUNTER_LOAD: natural := (CLK_TIMING_OUT_NS / CLK_TIMING_IN_NS / 2) - 1;  -- Required counts of the input clock to run at the required output speed
  
  signal   counter: integer range 0 to COUNTER_LOAD;         -- Counter (clock division)
  signal   toggle : std_logic := '0';                        -- Toggle bit
  
begin
  --{------------------------------------------------------------------------------}
  --{ Params  : <CLK_IN>  Clock
  --{ Descript: Countdown and reload counter and toggle when counted down
  --{------------------------------------------------------------------------------}
  process (CLK_IN)
  begin
    if (rising_edge(CLK_IN)) then
      if (counter = 0) then
        counter <= COUNTER_LOAD;
        toggle  <= not toggle;
        CLK_OUT <= toggle;
      else
        counter <= counter - 1;
      end if;
    end if;
  end process;


end CLOCK_DIV;
 
how to control ks0066 vhdl

Thanks Marcel Majoor.
I am hoping to to get more codes please, the more code I have the better I understand this.

Added after 14 minutes:

Marcel,

If its not too much to ask can you please provide the state diagram for these codes(preferrably code1), if you have it?

I will be glad to have that and will make it easier for me to understand the code too.
 

    V

    Points: 2
    Helpful Answer Positive Rating
vhdl program

The states the state machines go through is actually the way it is presented.
For instance, the states for LCD_CONTROLLER is 'state_LCD' is defined as:

type state_LCD is (wait1, wait2, idle, set_rs, set_e_h, set_e_l, execw);

The state machine in LCD_CONTROLLER goes from state-to-state based on a specified timeout (delay_reg).
wait1: setup initial startup delay
wait2: setup initial registers
idle: wait for signal to start writing to LCD
set_rs: set RS (according to input)
set_e_h: activate E
set_e_l: de-activate E
exec_w: wait for delay for completion of command; jump to 'idle' if done

Note: 'exec_w' and 'wait2' are identical so one of these could be omitted. 'others' is used to make sure that any 'illegal' states will execute 'wait1' the next time.


For LCD_CONTROLLER_MAIN about the same applies.

tstate_main is (wait1, init1, init2, text1, text2, crlf1, crlf2, text3, text4, idle,
crlf3, crlf4, press1, press2, press3, crlf5, crlf6, press4, press5, press6);

The state machine here goes from state to state based on the 'feedback' from the LCD_CONTROLLER state machine. Using the 'ready' signal the state machine knows that LCD_CONTROLLER has accepted a new command or has completed it. After initiating a new command (when 'ready' was 1), the state machine waits for 'ready' to become '0' (which means the other state machine has started executing the command). It is then a matter of waiting for 'ready' to become '1' again before the next command can be issued.

wait1..init2 are executes only once, to initialzie the display. 'init1' and 'init2' are looped through until all initialization data has been written to the LCD.
The 'text1' and 'text2' are looped through until the first text is displayed.
'crlf1' and 'crlf2' are then used to move the LCD cursor to the second line. Then 'text3' and 'text4' are looped through to display the 2nd text.
We have then reached the 'idle' state at that point, were the state machine waits for one of two keys to be pressed. Depending on which key is pressed a different text is displayed on the top line of the display. This is done by setting the cursor ('crlf3'/'crlf4' or 'crlf5'/'crlf6'), and then displaying each character of the text to display ('press1'/'press2'/'press3' or 'press4'/'press5'/'press6').
The 'others' state is used to catch any illegal states.
 
program on vhdl

Marcel,

Can you please tell me which 2x16 LCD did you used in the above program.
The serial code/number or make or anything that will help me to find a similar one, please.
 

program of vhdl code of lcd display

I don't know the actual LCD type (it is from an AVNET FPGA development kit) but it should work for all displays using a HD44780 or equivalent controller.
The code above is based on a 2 line display, but -not- necessarily 16 characters.
A 20 character display should do too.

The 'Lcd_controller.vhd' file can be used for all displays using the mentioned controller.
Only the 'lcd_controller_main.vhd' file is specific to the type of display (a 2 line display in this case) but changes would only be minor for supporting, for instance, a 4 line display.
 

port toggle programm in vhdl

Thanks.

The below array is it the characters you are displaying on the Display or is it code to active the address where you are writting??

I dont mean to sound stupid but I am getting tuff time to understand this code.
Plus you are having components in this program also, ooouuuf I think I am missing alot of things in this program.

type ttextlength is range 16 downto 0;
type tline is array(ttextlength) of std_logic_vector (7 downto 0);
type tinitlength is range 8 downto 0;
type tinitdata is array(tinitlength) of std_logic_vector (7 downto 0);

constant init_data : tinitdata := (x"38", x"38", x"38", x"38", x"06", x"0E", x"01", x"80", x"00");
constant line1 : tline := (x"20", x"20", x"20", x"20", x"20", x"4C", x"49", x"53",
x"4D", x"41", x"52", x"20", x"20", x"20", x"20", x"20", x"00");
constant line2 : tline := (x"45", x"6E", x"67", x"69", x"6E", x"65", x"65", x"72",
x"69", x"6E", x"67", x"20", x"42", x"2E", x"56", x"2E", x"00");
constant line3 : tline := (x"42", x"75", x"74", x"74", x"6F", x"6E", x"20", x"31",
x"20", x"70", x"72", x"65", x"73", x"73", x"65", x"64", x"00");
constant line4 : tline := (x"42", x"75", x"74", x"74", x"6F", x"6E", x"20", x"32",
x"20", x"70", x"72", x"65", x"73", x"73", x"65", x"64", x"00");
 
  • Like
Reactions: Aya2002

    Aya2002

    Points: 2
    Helpful Answer Positive Rating
lcd_controller.vhd

Marcel,

I think it has been my fault all along I didnt mention whichboard I am using, I am using UP2 Development board, using FLEX 10K CPLD.

Which board are you using on thesecode??

Added after 1 minutes:

I mean Altera UP2 Development board, using FLEX 10K CPLD.
 

2x16 lcd commands

I can't recollect the exact board, but as I mentioned it is from Avnet (Memec) with a Spartan 3S...1500 FPGA on board.

Except from lcd_controller_main.vhd the code is not directly board related. Only in lcd_controller_main (which is there to demonstrate the actual use of the other components) hardware dependencies are present. Keep in mind that the 'entity' declaration is actually the 'outside' of such an unit. This 'outside' can be the actual hardware (the actual hardware pin is then set by the constrainst definiton), or the 'outside' can be another unit (like a vhdl testbench which would emulate the clock and all other signals).


The code as in 'init_data' is the data send to the display. 'init_data' has some initialization data (like 4/8-bit mode, cursor settings etc). The 'lineX' definitions are ASCII 'strings' (each character as hexadecimal value).
You will notice that, when the 'init_data' data is send to the display that the 'rs' will be set to 0 (indicating control data) and that the ASCII strings have 'rs' set to 1 (indicating character data).
 

vhdl ile lcd programlama

Thanx Marcel.

Cant you compile one that is compatible with Altera UP2 educational board, Flex10k20RC240-4 CPLD, the make No. is DBA560001.

I js want a simple one, I hv been tryg to follow your programs but I always get lost in the middle. or mayb if you can shorten them then I can understand, u know I am new still learning this laguage.
 

programs in vhdl using clock

Basically you should forget about 'Lcd_controller_main.vhd' and 'clock_div.vhd'.
The actual LCD code is in 'Lcd_controller.vhd'.

'Clock_div.vhd' is only used to generate a clock of 250 ns (which 'Lcd_controller.vhd' needs), but this could be generated by other means too.
There might be some clock library/component you can use, or you could even use an external clock.
'Lcd_controller_main.vhd' is just an example of using 'Lcd_controller.vhd'.
One can use any kind of 'program' (typically a state machine like used in 'Lcd_controller_main.vhd') to send the correct sequence of data to the LCD.

I know you would like to use code you can use directly for your target, but that involves more than just the vhdl code. You need to define the I/O pins and such in a constraints file/definition.
I myself only use Xilinx devices (and as software Xilinx ISE Webpack, MathWorks Simulink + Xilinx System Generator) and nothing from Altera so I am not able to create a complete workable project for you.
 

x80 vhdl

Thanks Marcel.

So the code you gave is for/from Xilinx ??
Maybe I should learn that, do you any website where I can get it for free? I am searchg the net but I cant find any...
I only Altera at my disposal...
 

Hi there,

should 'LCD_controller_main.vhd' run at xilinx without other sources??
I tryed to run the code and i got some errors like missing the LCD_CONTROLLER_MAIN, can you help me???
 

how to program a lcd inverter with sch?

Care to 1: expend more characters on your problem descriptions and 2: stuff it in a seperate thread. Sounds like it doesn´t have much to do with the OP other than generic things with LCD.

To answer your original question: to program a lcd inverter with sch you do the thing. You know, the thing with the stuff. Glad we cleared that up!
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top