Problems HD44780 - LCD - ALTERA DE2-115...
Hey guys,
I am new in VHDL and tried to control the LCD, but no chance... It needs to be a simple error, but because I am new in FPGA/VHDL is going to be difficult for me to fix it.
I made a simulation with modelsim (all fine...), I checked the out- and input-pin-setting a thousand times (all fine...) and I checked the board (DE2-115) with the control panel (all works...)
I mixed up a code I found in the internet for an (working?) example and modified it a little bit.
General function: At first the program initialize the LCD and goes in a loop for writing letters to the lcd. Via 7 switchs the user is defining the binary code of the letters which should be written on the LCD.
Result: After transfering the code, the FPGA doesnt react to a chancing of the switchs. The standart message "Welcome to the Alterna DE2-115" is shown up, thats all... ;-(
I made some comments to understand the functions a little bit faster...
Hopefully someone can find the error... thx to all answers...
-------------------------------------------------------------------
-- ASCII HEX TABLE
-- Hex Low Hex Digit
-- Value 0 1 2 3 4 5 6 7 8 9 A B C D E F
------\---------------------------------------a-------------------------
--H 2 | SP ! " # $ % & ' ( ) * + , - . /
--i 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
--g 4 | @ A B C D E F G H I J K L M N O
--h 5 | P Q R S T U V W X Y Z [ \ ] ^ _
-- 6 | ` a b c d e f g h i j k l m n o
-- 7 | p q r s t u v w x y z { | } ~ DEL
-----------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
entity lcd_control is
port
(
trigger,trigger2, clk : in std_logic;
ascii : in std_logic_vector(7 downto 0);
lcd_rs, lcd_e, lcd_rw : out std_logic;
lcd_data : out std_logic_vector(7 downto 0);
lcd_an : out std_logic
);
end lcd_control;
architecture behv of lcd_control is
type state_type is ( START, START_WAIT, FUNC_SET_WAIT, DISP_ON_WAIT,
DROP_E, HOLD,
FUNC_SET, DISP_ON, DISP_CLEAR, MODE_SET,
WAIT_CHAR, DISP_CLEAR_WAIT,
WAIT_TRIGGER_RESET,
CHK_CNT, LINE2, HOME);
signal state, next_command : state_type;
signal char_cnt : std_logic_vector(5 downto 0);
signal wait_cnt : std_logic_vector(7 downto 0);
begin
process(clk)
begin
if trigger2='1' then -- a switch to turn the lcd on and off
lcd_an<='1';
lcd_rw<='0'; -- setting the rw permenantly to 1
else
lcd_an<='0';
end if;
state <= START;
case state is
when START =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_data <= X"38"; -- set the lcd to 8 bit lenght
wait_cnt<=X"00";
state <= DROP_E; -- function of DROP_E: just sets lcd_e to '1' and state goes to next_command
next_command <= START_WAIT;
when START_WAIT => -- waiting for a few msec
if wait_cnt < X"10" then
wait_cnt <= wait_cnt +1;
state <= START_WAIT;
else
state <= FUNC_SET;
wait_cnt <= X"00";
end if;
when FUNC_SET =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_data <= X"38";
state <= DROP_E;
next_command <= FUNC_SET_WAIT;
when FUNC_SET_WAIT =>
if wait_cnt < X"10" then
wait_cnt <= wait_cnt +1;
state <= FUNC_SET_WAIT;
else
state <= DISP_ON;
wait_cnt <= X"00";
end if;
when DISP_ON =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_data <= X"0F"; -- set the lcd to Display on, Cursor is displayed, Blinking enable,
state <= DROP_E;
next_command <= DISP_ON_WAIT;
when DISP_ON_WAIT =>
if wait_cnt < X"10" then
wait_cnt <= wait_cnt +1;
state <= DISP_ON_WAIT;
else
state <= DISP_CLEAR;
wait_cnt <= X"00";
end if;
when DISP_CLEAR =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_data <= X"01"; -- command: clear the display
wait_cnt <= X"00";
state <= DROP_E;
next_command <= DISP_CLEAR_WAIT;
when DISP_CLEAR_WAIT =>
if wait_cnt < X"10" then
wait_cnt <= wait_cnt +1;
state <= DISP_CLEAR_WAIT;
else
state <= MODE_SET;
wait_cnt <= X"00";
end if;
when MODE_SET =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_data <= X"06"; -- Cursor moves right, Display shift enabled.
state <= DROP_E;
next_command <= WAIT_CHAR;
---------------- initialization done, Loop of writing begins -------------------------------------------
-- WAIT_CHAR -> DROP_E -> HOLD -> WAIT_TRIGGER_RESET -> CHK_CNT -> LINE2 -> DROP_E -> HOLD -> |
-- | |
-- ^ -> HOME -> DROP_E -> HOLD -> |
-- | | |
-- | v v
-- |----------------------------------------<<-------------------------------------------|
-------------------------------------------------------------------------------------------------
when WAIT_CHAR =>
if trigger = '0' then -- trigger is set to a switch
lcd_e <= '1';
lcd_rs <= '1';
lcd_data <= ascii; -- ascii is defined through 7 switchs
char_cnt <= char_cnt +1; -- a counter for the written letters
state <= DROP_E;
next_command <= WAIT_TRIGGER_RESET;
else
next_command <= WAIT_CHAR;
end if;
when WAIT_TRIGGER_RESET => -- loop, waiting for an change at the switch
if trigger = '0' then
state <= WAIT_TRIGGER_RESET;
else
state <= CHK_CNT;
end if;
when CHK_CNT => -- checking if the first line is full of letters,
if char_cnt = X"10" then
state <= LINE2;
elsif char_cnt = X"20" then
state <= HOME; -- clears the display
else
state <= WAIT_CHAR;
end if;
when LINE2 => -- starts writing at the secound line
lcd_e <= '1';
lcd_rs <= '0';
lcd_data <= X"C0"; -- sets the DDRAM-Adress to '1000000'
state <= DROP_E;
next_command <= WAIT_CHAR;
when HOME =>
lcd_e <= '1';
lcd_rs <= '0';
lcd_data <= X"80"; -- sets the DDRAM-adress to '0000000'
char_cnt <= "000000";
state <= DROP_E;
next_command <= WAIT_CHAR;
when DROP_E =>
lcd_e <= '1';
state <= HOLD;
when HOLD =>
state <= next_command;
end case;
end process;
end behv;