LCD12864 coding problem

Thread Starter

pruzr

Joined Mar 13, 2008
3
I have found that I can't display a 8 bit on the lcd, I have tried it for a full day and I can't find any solution, can someone know what error in the code?
thank you very much


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

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity LCD is

port( clk:in std_logic;
RST:in std_logic;
Tick : in std_logic; -- Tick at 250 kHz (one clock cycle long)
Din : in std_logic_vector (7 downto 0);
Dav : in std_logic; -- Write Data command (1 clock cycle) if Dav=1 , then write data
Busy : out std_logic;
x : in std_logic_vector (7 downto 0);
y : in std_logic_vector (7 downto 0);
cs : in std_logic; -- choose segment to display
---Lcd signals---------------------------------------
RS:eek:ut std_logic; ---LCD R R_sel
RW:eek:ut std_logic; ---LCD Read/Write
E:eek:ut std_logic; ---Enable
CS1: out std_logic;---LCD chip select 1
CS2: out std_logic;---LCD Chip select 2
Dout: inout std_logic_vector(7 downto 0) --- LCD data
-----------------------------------------------------

);

end LCD;

architecture Behavioral of LCD is
-----type defination----
--TYPE State_type IS ( w_Z_SCROLL, w_X_PAGE, W_Y_COL, W_DATA, W_INS,
-- DISPLAY_ON, DISPLaY_OFF, SEGMENT1, SEGMENT2,IDLE) ;
type State_type is (Boot, W_Z_SCROLL,W_Y_COL,W_X_PAGE,Display,Segment_Select,Waiting,WriteData);
-----constant defination----

constant DON : std_logic_vector(7 downto 0) := "00111111"; -- Display on
constant DOFF : std_logic_vector(7 downto 0) := "00111110"; -- Display off
constant Y_ADD : std_logic_vector(7 downto 0) := "01000000"; -- Set Y address 01xxxxxx, xxxxxx is 0-127
constant X_ADD : std_logic_vector(7 downto 0) := "10111000"; -- Set X col 10111xxx, xxx is 0-7
constant Z_ADD : std_logic_vector(7 downto 0) := "11000000"; -- set z address 11xxxxxx, xxxxxx is 0-127
constant write : std_logic_vector(7 downto 0) := "00000000"; -- xxxxxxxx is the data want to write



constant Big_delay : integer := 25000; -- 25000/250 = 100 ms
constant Clr_delay : integer := 5000; -- 500/250= 2 ms
constant Small_delay : integer := 120; -- > 39 us after E down
constant En_delay : integer := 20;
--constant LastPosition : integer := 16;

-----signal defination------
SIGNAL State : State_type;
--SIGNAL Next_State : State_type;
--SIGNAL Count : integer range 0 to Big_delay;
--SIGNAL Count2 : std_logic_vector(7 downto 0);
SIGNAL Z_SCROLL : std_logic_vector(7 downto 0);
SIGNAL X_PAGE : std_logic_vector(7 downto 0);
SIGNAL Y_COL : std_logic_vector(7 downto 0);
SIGNAL DAT : std_logic_vector(7 downto 0);
SIGNAL temp,temp2,INS : std_logic_vector(7 downto 0);
SIGNAL active : std_logic;

signal DavM : std_logic;
signal DataM : std_logic_vector (7 downto 0);
signal Position : integer range 0 to 32;
signal Count : integer range 0 to Big_delay;

----------------------------
begin

--RW <= '0';-------- write mode
process(clk,RST)
begin
if Rst = '1' then
State <= Boot;
Position <= 0;
Count <= 0;
DavM <= '0';
--Lcd_En <= '0';
--Lcd_Sel <= '1';
Busy <= '1';
RS <= '1';
RW <= '0';
E <= '0';
CS1 <= '0';
CS2 <= '0';
Dout <= (others=>'0');

elsif rising_edge(Clk) then

if Dav = '1' then
DavM <= '1';
DataM <= Din;
Busy <= '1';
end if;

if Tick = '1' then

case State is

when Boot => -- Power up wait 30 ms
RS <= '1';
E <= '0';
Busy <= '1';
if Count = Big_delay then
RS <= '0';
Count <= 0;
State <= W_Z_SCROLL;
else
Count <= Count + 1;
end if;


when W_Z_SCROLL => -- Set Function & Mode
Dout <= Z_ADD;
RS <= '0';
if Count = 1 then
E <= '1';
elsif Count = En_delay then
E <= '0';
end if;
if Count = Small_delay then
State <= W_Y_COL;
Count <= 0;
else
Count <= Count+1;
end if;


when W_Y_COL => -- set Entry Mode,
temp <= Y_ADD or y;
Dout <= temp;
RS <= '0';
if Count = 1 then
E <= '1';
elsif Count = En_delay then
E <= '0';
end if;
if Count = Small_delay then
State <= W_X_PAGE;
Count <= 0;
else
Count <= Count+1;
end if;

when W_X_PAGE => -- set Entry Mode,
temp2 <= X_ADD or x;
Dout <= temp2;
RS <= '0';
if Count = 1 then
E <= '1';
elsif Count = En_delay then
E <= '0';
end if;
if Count = Small_delay then
State <= Display;
Count <= 0;
else
Count <= Count+1;
end if;


when Display => -- set Display ON
Dout <= DON;
RS <= '0';
if Count = 1 then
E <= '1';
elsif Count = En_delay then
E <= '0';
end if;
if Count = Small_delay then
State <= Segment_Select;
Count <= 0;
else
Count <= Count+1;
end if;




when Segment_Select => -- set Display ON

if cs ='0' then ---- cs1 enable
RS <='0';
RW <='1';
CS1 <='1';
CS2 <='0';
Dout <= "00000000";

if Count = 1 then
E <= '1';
elsif Count = En_delay then
E <= '0';
end if;
if Count = Small_delay then
State <= Waiting;
Count <= 0;
else
Count <= Count+1;
end if;

elsif cs ='1' then -----cs2 enalbe
RS <='0';
RW <='1';
CS1 <='0';
CS2 <='1';
Dout <= "00000000";

if Count = 1 then
E <= '1';
elsif Count = En_delay then
E <= '0';
end if;
if Count = Small_delay then
State <= Waiting;
Count <= 0;
else
Count <= Count+1;
end if;

end if;



when Waiting => -- Waits for input
if DavM = '1' then
DavM <= '0';
State <= WriteData;
RS <= '1';
else
Busy <= '0';
end if;



when WriteData =>
RS <= '1';
RW <= '0';
Dout <= Din;
if Count = 1 then
E <= '1';
elsif Count = En_delay then
E <= '0';
end if;
if Count = Small_delay then
Count <= 0;
State <= WriteData;
else
Count <= Count + 1;
end if;


end case;
end if;
end if;
end process;




end Behavioral;
 

SgtWookie

Joined Jul 17, 2007
22,230
Seems to me that you need to re-send the "wake-up" code a few times (with 10mS waits between) to ensure that the display is actually ready to receive commands - that is, if your LCD's controller is a Hitachi 44780 controller.

You need to determine what the actual controller of your LCD is. The HD44780 is quite popular, but you may have a different controller.

I re-formatted your program using [ CODE] [ /CODE] tags.

Rich (BB code):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity LCD is

port(       clk:in std_logic;
            RST:in std_logic; 
            Tick : in std_logic;                      -- Tick at 250 kHz (one clock cycle long)
            Din : in std_logic_vector (7 downto 0);
            Dav  : in std_logic;                      -- Write Data command (1 clock cycle)  if Dav=1 , then write data
            Busy : out std_logic; 
            x : in std_logic_vector (7 downto 0);
            y : in std_logic_vector (7 downto 0);
            cs : in std_logic; -- choose segment to display   
---Lcd signals---------------------------------------
            RS:out std_logic; ---LCD R         R_sel
            RW:out std_logic; ---LCD Read/Write
            E:out std_logic; ---Enable
              CS1: out std_logic;---LCD chip select 1
            CS2: out std_logic;---LCD Chip select 2
            Dout: inout std_logic_vector(7 downto 0) --- LCD data
-----------------------------------------------------

    ); 

end LCD;

architecture Behavioral of LCD is
-----type defination----
--TYPE  State_type IS (  w_Z_SCROLL, w_X_PAGE, W_Y_COL, W_DATA, W_INS,
--                         DISPLAY_ON, DISPLaY_OFF, SEGMENT1, SEGMENT2,IDLE) ;
type State_type is (Boot, W_Z_SCROLL,W_Y_COL,W_X_PAGE,Display,Segment_Select  ,Waiting,WriteData);       
-----constant defination----

constant DON   : std_logic_vector(7 downto 0) := "00111111"; -- Display on
constant DOFF  : std_logic_vector(7 downto 0) := "00111110"; -- Display off
constant Y_ADD : std_logic_vector(7 downto 0) := "01000000"; -- Set Y address   01xxxxxx, xxxxxx is 0-127
constant X_ADD : std_logic_vector(7 downto 0) := "10111000"; -- Set X col 10111xxx, xxx is 0-7
constant Z_ADD : std_logic_vector(7 downto 0) := "11000000"; -- set z address 11xxxxxx, xxxxxx is 0-127
constant write : std_logic_vector(7 downto 0) := "00000000"; -- xxxxxxxx is the data want to write



constant Big_delay    : integer := 25000;  -- 25000/250 = 100 ms
constant Clr_delay    : integer := 5000;   -- 500/250= 2 ms
constant Small_delay  : integer := 120;    -- > 39 us after E down
constant En_delay     : integer := 20;
--constant LastPosition : integer := 16;

-----signal defination------
SIGNAL   State   : State_type;
--SIGNAL   Next_State   : State_type;
--SIGNAL    Count    : integer range 0 to Big_delay;
--SIGNAL   Count2   : std_logic_vector(7 downto 0);
SIGNAL   Z_SCROLL : std_logic_vector(7 downto 0);
SIGNAL   X_PAGE : std_logic_vector(7 downto 0);
SIGNAL   Y_COL : std_logic_vector(7 downto 0);
SIGNAL   DAT : std_logic_vector(7 downto 0);
SIGNAL   temp,temp2,INS : std_logic_vector(7 downto 0);
SIGNAL   active : std_logic;

signal DavM  : std_logic;
signal DataM : std_logic_vector (7 downto 0);
signal Position : integer range 0 to 32;
signal Count    : integer range 0 to Big_delay;

----------------------------
begin

--RW <= '0';-------- write mode
   process(clk,RST)
   begin
      if Rst = '1' then
      State    <= Boot;
      Position <= 0;
      Count    <= 0;
      DavM     <= '0';
      --Lcd_En   <= '0';
      --Lcd_Sel  <= '1';
      Busy     <= '1';
      RS         <= '1';
      RW         <= '0';
      E         <= '0';
      CS1      <= '0';
      CS2      <= '0';
      Dout     <= (others=>'0');
      
    elsif rising_edge(Clk) then

      if Dav = '1' then
        DavM  <= '1';
        DataM <= Din;
        Busy  <= '1';
      end if;

      if Tick = '1' then
      
        case State is

          when Boot =>                  -- Power up wait 30 ms
            RS  <= '1';
            E   <= '0';
            Busy <= '1';
            if Count = Big_delay then
              RS <= '0';
              Count <= 0;
              State <= W_Z_SCROLL;
            else
              Count <= Count + 1;
            end if;


         when W_Z_SCROLL =>               -- Set Function & Mode
            Dout    <= Z_ADD;
            RS        <= '0';
            if Count = 1 then
              E <= '1';
            elsif Count = En_delay then
              E <= '0';
            end if;
            if Count = Small_delay then
              State <= W_Y_COL;
              Count <= 0;
            else
              Count <= Count+1;
            end if;


          when W_Y_COL =>             -- set Entry Mode,
             temp    <= Y_ADD or y;
            Dout    <= temp;
            RS        <= '0';
            if Count = 1 then
              E <= '1';
            elsif Count = En_delay then
              E <= '0';
            end if;
            if Count = Small_delay then
              State <= W_X_PAGE;
              Count <= 0;
            else
              Count <= Count+1;
            end if;

         when W_X_PAGE =>             -- set Entry Mode,
             temp2    <= X_ADD or x;
            Dout    <= temp2;
            RS        <= '0';
            if Count = 1 then
              E <= '1';
            elsif Count = En_delay then
              E <= '0';
            end if;
            if Count = Small_delay then
              State <= Display;
              Count <= 0;
            else
              Count <= Count+1;
            end if;


          when Display =>               -- set Display ON
            Dout    <= DON;
            RS       <= '0';
            if Count = 1 then
              E <= '1';
            elsif Count = En_delay then
              E <= '0';
            end if;
            if Count = Small_delay then
              State <= Segment_Select;
              Count <= 0;
            else
              Count <= Count+1;
            end if;




            when Segment_Select =>               -- set Display ON

            if cs ='0' then ---- cs1 enable
            RS       <='0';
            RW       <='1';
            CS1      <='1';
            CS2      <='0';
            Dout       <= "00000000";
            
            if Count = 1 then
              E <= '1';
            elsif Count = En_delay then
              E <= '0';
            end if;
            if Count = Small_delay then
              State <= Waiting;
              Count <= 0;
            else
              Count <= Count+1;
            end if;

            elsif cs ='1' then -----cs2 enalbe
            RS       <='0';
            RW       <='1';
            CS1      <='0';
            CS2      <='1';
            Dout       <= "00000000";
            
            if Count = 1 then
              E <= '1';
            elsif Count = En_delay then
              E <= '0';
            end if;
            if Count = Small_delay then
              State <= Waiting;
              Count <= 0;
            else
              Count <= Count+1;
            end if;
            
            end if; 



          when Waiting =>               -- Waits for input
            if DavM = '1' then
              DavM    <= '0';
              State   <= WriteData;
              RS <= '1';
            else
              Busy <= '0';
            end if;

   

          when WriteData =>               
             RS <= '1';
             RW <= '0';
             Dout <= Din;
            if Count = 1 then
              E <= '1';
            elsif Count = En_delay then
              E <= '0';
            end if;
            if Count = Small_delay then
              Count    <= 0;
              State    <= WriteData;
            else
              Count <= Count + 1;
            end if;


        end case;
      end if;
    end if;
  end process;

   
   

end Behavioral;
 

Thread Starter

pruzr

Joined Mar 13, 2008
3
Thank you for your reply SgtWookie
Is that the Wake up code is the RST pin in my LCD controller?


GDM12864A
Features
?? Display format: 128*64 dots matrix graphic
?? STN yellow-green mode
?? Easy interface with 8-bit MPU
?? Low power consumption
?? LED back-light
?? Viewing angle: 6 O’clock
?? Driving method : 1/64 duty , 1/6.7 bias
?? LCD driver IC: KS0108B(2 ? )? KS0107B
?? Connector: Zebra

KS0108 Driver IC


4. Reset
The system can be initialized by setting RSTB terminal at low level when turning power on, receiving
instruction from MPU. When RSTB becomes low, following procedure is occurred.
1. Display off
2. Display start line register become set by 0.(Z-address 0)
While RSTB is low, No instruction except status read can by accepted. Therefore, execute other
instructions after making sure that DB4= (clear RSTB) and DB7=0 (ready) by status read instruction.
The conditions of power supply at initial power up are shown in table 1.
Table 1. Power Supply Initial Conditions
Item Symbol Min Typ Max Unit
Reset Time tRS 1.0 - - us
Rise Time tR - - 200 ns
 
Top