CFAH1604A-NYG-JP black boxes

Dhvanish

New member
I am using CFAH1604A-NYG-JP connected with LPC2106 microcontroller. My cable connections are as follows:

Pin# Symbol Description
1 Vss GND
2 Vdd +4.5V
3 Vo GND
4 RS P0.0
5 R/W P0.2
6 E P0.4
7 DB0 P0.6
8 DB1 P0.8
9 DB2 P0.10
10 DB3 P0.12
11 DB4 P0.14
12 DB5 P0.16
13 DB6 P0.18
14 DB7 P0.20
15 A +4.5V
16 K GND


After connection as described, all I see is LCD backlight and 1st and 3rd row with black boxes. The complete software code is below. Somehow there is no effect of any initialization instructions. To debug, I have LED connected to E pin(P0.4). I also have two extra debug LED connected at pin P0.5(return from status-busy indication) and P0.7(status-busy indication). After execution, I observe that the program execution indicates proper returns from the busy state. This means that the module is operating properly and is not losing instructions because of busy state. Still there is no effect on display and all I see is the same display of black boxes in 1st and 3rd row. Even my function set instruction is not accepted as it should be enabling 2 line display. In other words at the end of my function set instruction, I should see black boxes in 2nd and 4th line as well.

Any clues where is the problem? Maybe broken LCDs?(I have 2 LCD modules... both have same display).


Code:
/********************************************************************
Module: sw2.c

Version		Date		Initials		Description
0.0.1		02/05/07	DHC				First version inherited from
                                        sw.c
0.0.2       02/07/07    DHC             Incremental & Decremental LEDs
                                        functioality added  
0.0.3       02/27/07    DHC             Modified for LCD Display                                      
********************************************************************/


//LPC2100 definitions
#include "LPC2100_addrs.h"

//write address to register macro
#define REG(addr) (*(volatile unsigned long *) (addr))

//local functions
void lcd_init(void);
void startup_display(void);
void wait1(void);
void checkbusy(void);
void wait2(void);
void lcd_disp(void);
void busycheck(void);


//program main
int main(void)

	{
     unsigned long i;
        //Initialization

    //SET DIRECTIONS OF GPIO PORT
    REG(GPIO_IODIR) = 0x00155555;

    wait2();
    REG(GPIO_IOCLR) = 0x00155555;
    wait2();

    //REG(GPIO_IOSET) = 0x00155545;

    

    lcd_init();
    lcd_disp();
    while(1);

    }

/*******************************************************************
Function Prototypes
*******************************************************************/

void lcd_init(void)
{
     unsigned long j,i;

     
     for(i=0;i<40;i++)
     {
         wait2();

     }
     
     //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION  I
     REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     wait1();

     for(i=0;i<10;i++)
     {
         wait2();
     }


       //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION  II
      REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0 
      REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
      REG(GPIO_IOSET) = 0x00015000; //DB = 0x38       
      wait1();                                        
                                                      
      for(i=0;i<10;i++)                                
      {                                               
          wait2();                                    
      } 

     
     //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION   III
     REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     wait1();

     wait2();


     for(i=0;i<10;i++)
     {
         wait2();
     }

     busycheck();

     REG(GPIO_IOSET) = 0x00000020;
     wait2();
     wait2();
     REG(GPIO_IODIR) = 0x00155555;
     wait2();
     wait2();

     //FUNCTION SET
     REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     wait1();

     wait2();


     for(i=0;i<10;i++)
     {
         wait2();
     }

     busycheck();

     REG(GPIO_IOSET) = 0x00000020;
     wait2();
     wait2();
     REG(GPIO_IODIR) = 0x00155555;
     wait2();
     wait2();


    //DISPLAY ON/OFF CONTROL
    REG(GPIO_IOCLR) = 0x00155515; //DB = 0x00, RS = 0, R/W = 0
    wait2();
    wait2();
    REG(GPIO_IOSET) = 0x00001400; //DB = 0x0C
    //REG(GPIO_IOSET) = 0x00001540; //DB = 0x0E
    //REG(GPIO_IOSET) = 0x00001000; //Display = OFF
    wait1();

    wait2();

    for(i=0;i<10;i++)
    {
        wait2();
    }

    busycheck();

    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();

    //DISPLAY CLEAR
    REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
    REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOSET) = 0x00000040; //DB = 0x01
    wait2();
    wait1();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }


    busycheck();
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    
   
    //ENTRY MODE SET
    REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
    REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOSET) = 0x00000500; //DB = 0x06
    wait2();
    wait1();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }


    busycheck();
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    
   
     //while(1);
}



void wait1(void)
{
   unsigned long j;

   REG(GPIO_IOCLR) = 0x00000010; //E = 0
   for(j=0;j<250000;j++);
   REG(GPIO_IOSET) = 0x00000010; //E = 1
   for(j=0;j<500000;j++);
   REG(GPIO_IOCLR) = 0x00000010; //E = 0
   for(j=0;j<250000;j++);

 }



void wait2(void)
{
    unsigned long j;
     for(j=0;j<250000;j++); //250 ~ 1 msec
}



void lcd_disp(void)
{
     //Display characters
    unsigned long i;

    busycheck();

    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();

    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00
    REG(GPIO_IOSET) = 0x00100000; //Set DDRAM Address

    wait2();
    wait1();
    wait2();




    //busycheck();
    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00

    REG(GPIO_IOSET) = 0x00000001;  //RS = 1, R/W = 0
    REG(GPIO_IOSET) = 0x00041000;  //H
    wait2();
    wait1();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

    busycheck();

    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();

    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00

    REG(GPIO_IOSET) = 0x00000001;  //RS = 1, R/W = 0
    REG(GPIO_IOSET) = 0x00041040;  //I
    wait2();
    wait1();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

    busycheck();

    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();

    REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00

    REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOSET) = 0x00000100; // Return home


    wait2();
    wait2();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

    busycheck();

    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();

}


void busycheck(void)
{
    unsigned long i;
    unsigned short x; //changed to short from char
    unsigned long w;

    REG(GPIO_IOCLR) = 0x00155540;

    for(i=0;i<10;i++)
    {
        wait2();
    }

    REG(GPIO_IODIR) = 0x000000E5; //E, RS, R/W => outputs
     
    REG(GPIO_IOCLR) = 0x00000001;
    wait2();
    REG(GPIO_IOSET) = 0x00000014; //RS =0, R/W = 1, E = 1

    wait2();
    wait2();


    
   
    //while(x & 0x00100000 == 0x00100000)
    //while(1)
    for(i=0;i<10;i++)
     {
         x = REG(GPIO_IOPIN);
         wait2();
         wait2();
         //if(REG(GPIO_IOPIN) & 1048576 == 1048576)
         if(REG(GPIO_IOPIN) & 0x100000 == 0x100000)
         //while(REG(GPIO_IOPIN) & 1048576)
         {
             REG(GPIO_IOSET) = 0x00000080;
             //wait1();
             wait2();
             wait2();
         }
         else
         {
             break;
         }
     }

    REG(GPIO_IOCLR) = 0x00000080;
    wait2();
}


Thanks in advance....
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 
In other words at the end of my function set instruction, I should see black boxes in 2nd and 4th line as well.
Not really. A successful init will leave all 4 lines clear.

I looked at your code, but it is very hard to understand. I am not familiar with the cpu you use, but why are you using even numbered I/O bits instead of just using sequential bits?
 

Dhvanish

New member
Cosmicvoid I have tried to introduce some extra comments in the code. Hope it helps better. If not, let me know I will try to post an algorithm for the code. In particular the function to be observed closely in this code is the lcdinit() function.

Reason for using even pins is that I have been using microcontroller development kit which has even pins in a row which I am connecting using a ribbon cable.

Please help me out with this LCD module as I am not able to figure out what exactly is wrong here.



Code:
/********************************************************************
Module: sw2.c

Version		Date		Initials		Description
0.0.1		02/05/07	DHC				First version inherited from
                                        sw.c
0.0.2       02/07/07    DHC             Incremental & Decremental LEDs
                                        functioality added  
0.0.3       02/27/07    DHC             Modified for LCD Display                                      
********************************************************************/


//LPC2100 definitions
#include "LPC2100_addrs.h"



//write address to register macro
#define REG(addr) (*(volatile unsigned long *) (addr))

//local functions
void lcd_init(void);
void startup_display(void);
void wait1(void);
void checkbusy(void);
void wait2(void);
void lcd_disp(void);
void busycheck(void);


//program main
int main(void)

	{
     unsigned long i;
        //Initialization

    //SET DIRECTIONS OF GPIO PORT
    //Direction: 0 = Input, 1 = Output
    //Set DB[0:7], RS, R/W, E as outputs
    REG(GPIO_IODIR) = 0x00155555; 

    wait2();  //Delay
    //Initialize DB[0:7], RS, R/W, E to 0
    REG(GPIO_IOCLR) = 0x00155555;
    wait2();
    
    lcd_init();    //Call LCD initalization routine
    lcd_disp();    //LCD Display routine
    while(1);

    }

/*******************************************************************
Function Prototypes
*******************************************************************/

void lcd_init(void)
{
     unsigned long j,i;

     //Long Delay before we start initialization
     for(i=0;i<40;i++)
     {
         wait2();

     }
     
     //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION  I
     REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00(Clear the contents of DB[0:7])
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     //Pulse E high to low
     wait1();
     //Delay
     for(i=0;i<10;i++)
     {
         wait2();
     }


       //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION  II
      REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0 
      REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00(Clear the contents of DB[0:7])
      REG(GPIO_IOSET) = 0x00015000; //DB = 0x38       
      //Pulse E high to low
      wait1();                                        
      //Delay                                                
      for(i=0;i<10;i++)                                
      {                                               
          wait2();                                    
      } 

     
     //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION   III
     REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00(Clear the contents of DB[0:7])
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     //Pulse E high to low
     wait1();
     //Delay
     wait2();

     //Extra delay before checking the busy flag
     for(i=0;i<10;i++)
     {
         wait2();
     }
     //Check the busy flag
     busycheck();
     //Following instructions display that the module is not busy anymore
     //that is, it has come out of "wait until busy" routine.  Indication
     //is by turning on the LED at P0.5
     REG(GPIO_IOSET) = 0x00000020;//LED@P0.5 = ON
     wait2();                     //Delay to make LED indication clear
     wait2();
     REG(GPIO_IODIR) = 0x00155555; //Set direction of DB, RS, R/W, E as outputs
     wait2();                      //Delay
     wait2();

     //FUNCTION SET
     REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     wait1(); //Pulse E high to low

     wait2();

     ///////Delay....
     for(i=0;i<10;i++)
     {
         wait2();
     }

     busycheck();  //Check for busy flag
     //////////As above..........
     REG(GPIO_IOSET) = 0x00000020;
     wait2();
     wait2();
     REG(GPIO_IODIR) = 0x00155555;
     wait2();
     wait2();
     /////////////////////////

    //DISPLAY ON/OFF CONTROL
    REG(GPIO_IOCLR) = 0x00155515; //DB = 0x00, RS = 0, R/W = 0
    wait2();
    wait2();
    REG(GPIO_IOSET) = 0x00001400; //DB = 0x0C
    //Pulse E high to low
    wait1();

    wait2();
    //.....Delay..........
    for(i=0;i<10;i++)
    {
        wait2();
    }

    busycheck();  //Check for busy flag
    //...........As above.........
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    ///////////////////////////

    //DISPLAY CLEAR
    REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
    REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOSET) = 0x00000040; //DB = 0x01
    wait2();
    wait1(); //Pulse E high to low
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }


    busycheck(); //Check for busy flag
    //...........As above.................
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    /////////////////////////////////////
   
    //ENTRY MODE SET
    REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00
    REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOSET) = 0x00000500; //DB = 0x06
    wait2();
    wait1();  //Pulse E high to low
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }


    busycheck();  //Check for busy flag
    //...........As above..............
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    
   
     //while(1);
}


//Function to Pulse E high to low
void wait1(void)
{
   unsigned long j;

   REG(GPIO_IOCLR) = 0x00000010; //E = 0
   for(j=0;j<250000;j++);
   REG(GPIO_IOSET) = 0x00000010; //E = 1
   for(j=0;j<500000;j++);
   REG(GPIO_IOCLR) = 0x00000010; //E = 0
   for(j=0;j<250000;j++);

 }


//Function to introduce a fixed delay
void wait2(void)
{
    unsigned long j;
     for(j=0;j<250000;j++); //250 ~ 1 msec
}


//LCD Display function
void lcd_disp(void)
{
     //Display characters
    unsigned long i;
    //Check for busy flags
    busycheck();
    //.......As above...........
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    /////////////////////////////
    //Setting the DDRAM Address......
    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00
    REG(GPIO_IOSET) = 0x00100000; //Set DDRAM Address

    wait2(); //Delay
    wait1(); //Pulse E high to low
    wait2(); //Delay




    //busycheck();
    //Display character H in 1st place
    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00

    REG(GPIO_IOSET) = 0x00000001;  //RS = 1, R/W = 0
    REG(GPIO_IOSET) = 0x00041000;  //H
    wait2();
    wait1(); //Pulse E high to low
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

    busycheck(); //Check for busy flag

    //...........As above............
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    ////////////////////////////////

    //Display character I in 2nd place
    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00

    REG(GPIO_IOSET) = 0x00000001;  //RS = 1, R/W = 0
    REG(GPIO_IOSET) = 0x00041040;  //I
    wait2();
    wait1(); //Pulse E high to low
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

    busycheck(); //Check for busy flag

    //.............As above..............
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    ////////////////////////////////////

    //Return home instruction
    REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00

    REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOSET) = 0x00000100; // Return home


    wait2();
    wait2();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

    busycheck(); //Check for busy flag

    //..............As above...............
    REG(GPIO_IOSET) = 0x00000020;
    wait2();
    REG(GPIO_IODIR) = 0x00155555;
    wait2();
    //////////////////////////////////////

}


void busycheck(void)
{
    unsigned long i;
    unsigned short x; //changed to short from char
    unsigned long w;

    REG(GPIO_IOCLR) = 0x00155540;

    for(i=0;i<10;i++)
    {
        wait2();
    }

    REG(GPIO_IODIR) = 0x000000E5; //E, RS, R/W => outputs
     
    REG(GPIO_IOCLR) = 0x00000001;
    wait2();
    REG(GPIO_IOSET) = 0x00000014; //RS =0, R/W = 1, E = 1

    wait2();
    wait2();


    
   
    //while(x & 0x00100000 == 0x00100000)
    //while(1)
    for(i=0;i<10;i++)
     {
         x = REG(GPIO_IOPIN);
         wait2();
         wait2();
         //if(REG(GPIO_IOPIN) & 1048576 == 1048576)
         if(REG(GPIO_IOPIN) & 0x100000 == 0x100000)
         //while(REG(GPIO_IOPIN) & 1048576)
         {
             REG(GPIO_IOSET) = 0x00000080;
             //wait1();
             wait2();
             wait2();
         }
         else
         {
             break;
         }
     }

    REG(GPIO_IOCLR) = 0x00000080;
    wait2();
}
 
I see what your code is doing, and it seems like it should work. The init sequence is taken from the data sheet. If your init isn't working, something must be wrong with your wiring or signal timing.

You don't mention your clock speed, so there is no way for me to judge the time delays in your wait loops. Since it looks like you are using these HUGE delays, I would comment out all of the code dealing with the busy check and port direction changes. The busy check would only be useful if you had no delays, and it may be introducing a problem that you can't see. Only a couple commands have a 1.5 mS execution time, the rest are around 40 uS.

Do you have a way to look at your control signal waveforms (other than LEDs)? An oscilloscope would be a good tool to see if your timing is OK.

If I were doing this code, I would use more "symbolism" and less 32 bit numbers. Such as:
#define WR 4
#define RS 1
#define E 16
#define DATA 0x00155510
etc.

and then use expressions like:
REG(GPIO_IOCLR) = RS + RW; //RS = 0, R/W = 0
REG(GPIO_IOCLR) = DATA; //DB = 0x00
etc.

to make it easier to read by humans. As for your even numbered bits, I would have made the made the wiring more difficult by using sequential bits, in order to make the code easier to write and read.

One last idea: make a piece of test code which toggles only one output bit slowly, for a while, and then advances to the next bit, and use that to check that your wiring is good. Check the signal at the display input pin.
 

Dhvanish

New member
The oscillator frequency is 14 MHz. I also commented out the busycheck and port direction change routines as per your suggestion. Below is the updated version of the code.

It seems like there is some serious problem with the LCD. What I tried is that I connected Vdd, Vss and Vo to the LCD module and removed all the connections to the microcontroller. Output on all pins except E are at Vdd. E has a square wave output. Now, after connecting to microcontroller board, RS goes low, E varies as per program, but somehow R/W stays at Vdd which is 4.5 V. It does not even go to +3.3V which should be the high output of my microcontroller. As per my program it should be going down to 0V, which never happens all throughout the program. At a point, I was thinking of connecting R/W to GND(which fortunately I didn't do).

It still has those black boxes in 1st and 3rd lines. As per HD44780U datasheet, RS, R/W and E are inputs by default and thus there should be no output voltage on them whatsoever. Any ideas why is it operating like this?


Code:
/********************************************************************
Module: sw2.c

Version		Date		Initials		Description
0.0.1		02/05/07	DHC				First version inherited from
                                        sw.c
0.0.2       02/07/07    DHC             Incremental & Decremental LEDs
                                        functioality added  
0.0.3       02/27/07    DHC             Modified for LCD Display                                      
********************************************************************/


//LPC2100 definitions
#include "LPC2100_addrs.h"

//write address to register macro
#define REG(addr) (*(volatile unsigned long *) (addr))

//local functions
void lcd_init(void);
void startup_display(void);
void wait1(void);
void checkbusy(void);
void wait2(void);
void lcd_disp(void);
void busycheck(void);


//program main
int main(void)

	{
     unsigned long i;
        //Initialization

    //SET DIRECTIONS OF GPIO PORT
    REG(GPIO_IODIR) = 0x00155555;

    wait2();

    REG(GPIO_IOCLR) = 0x00155555;

    for(i=0;i<1000;i++)
    {
        wait2();
    }
        wait2();

    //REG(GPIO_IOSET) = 0x00155545;

    

    lcd_init();
    lcd_disp();
    while(1);

    }

/*******************************************************************
Function Prototypes
*******************************************************************/

void lcd_init(void)
{
     unsigned long j,i;

     
     for(i=0;i<40;i++)
     {
         wait2();

     }
     
     //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION  I
     //REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155515; //DB = 0x00, RS = 0, R/W = 0
     wait2();
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     wait1();

     for(i=0;i<10;i++)
     {
         wait2();
     }


       //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION  II
      //REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0 
      REG(GPIO_IOCLR) = 0x00155515; //DB = 0x00, RS = 0, R/W = 0
      wait2();
      REG(GPIO_IOSET) = 0x00015000; //DB = 0x38       
      wait1();                                        
                                                      
      for(i=0;i<10;i++)                                
      {                                               
          wait2();                                    
      } 

     
     //BF CANNOT BE CHECKED BEFORE THIS INSTRUCTION   III
     //REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00, RS = 0, R/W = 0
     wait2();
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     wait1();

     wait2();


     for(i=0;i<10;i++)
     {
         wait2();
     }

//      busycheck();
//
//      REG(GPIO_IOSET) = 0x00000020;
//      wait2();
//      wait2();
//      REG(GPIO_IODIR) = 0x00155555;
//      wait2();
//      wait2();

     //FUNCTION SET
     //REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
     REG(GPIO_IOCLR) = 0x00155515; //DB = 0x00, RS = 0, R/W = 0
     wait2();
     REG(GPIO_IOSET) = 0x00015000; //DB = 0x38
     wait1();

     wait2();


     for(i=0;i<10;i++)
     {
         wait2();
     }

//      busycheck();
//
//      REG(GPIO_IOSET) = 0x00000020;
//      wait2();
//      wait2();
//      REG(GPIO_IODIR) = 0x00155555;
//      wait2();
//      wait2();


    //DISPLAY ON/OFF CONTROL
    REG(GPIO_IOCLR) = 0x00155515; //DB = 0x00, RS = 0, R/W = 0
    wait2();
    REG(GPIO_IOSET) = 0x00001400; //DB = 0x0C
    //REG(GPIO_IOSET) = 0x00001540; //DB = 0x0E
    //REG(GPIO_IOSET) = 0x00001000; //Display = OFF
    wait1();

    wait2();

    for(i=0;i<10;i++)
    {
        wait2();
    }

//     busycheck();
//
//     REG(GPIO_IOSET) = 0x00000020;
//     wait2();
//     REG(GPIO_IODIR) = 0x00155555;
//     wait2();

    //DISPLAY CLEAR
    //REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOCLR) = 0x00155515; //DB = 0x00, RS = 0, R/W = 0
    wait2();
    REG(GPIO_IOSET) = 0x00000040; //DB = 0x01
    wait2();
    wait1();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }


//     busycheck();
//     REG(GPIO_IOSET) = 0x00000020;
//     wait2();
//     REG(GPIO_IODIR) = 0x00155555;
//     wait2();
    
   
    //ENTRY MODE SET
    //REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOCLR) = 0x00155515; //DB = 0x00
    wait2();
    REG(GPIO_IOSET) = 0x00000500; //DB = 0x06
    wait2();
    wait1();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }


//     busycheck();
//     REG(GPIO_IOSET) = 0x00000020;
//     wait2();
//     REG(GPIO_IODIR) = 0x00155555;
//     wait2();
    
   
     //while(1);
}



void wait1(void)
{
   unsigned long j;

   REG(GPIO_IOCLR) = 0x00000010; //E = 0
   //for(j=0;j<250000;j++);
   //for(j=0;j<2500;j++);
   for(j=0;j<250;j++);
   REG(GPIO_IOSET) = 0x00000010; //E = 1
   //for(j=0;j<500000;j++);
   //for(j=0;j<5000;j++);
   for(j=0;j<500;j++);
   REG(GPIO_IOCLR) = 0x00000010; //E = 0
   //for(j=0;j<250000;j++);
   //for(j=0;j<2500;j++);
   for(j=0;j<250;j++);
 }



void wait2(void)
{
    unsigned long j;
     //for(j=0;j<250000;j++); //250 ~ 1 msec
    for(j=0;j<25000;j++); //250 ~ 1 msec
}



void lcd_disp(void)
{
     //Display characters
    unsigned long i;

//     busycheck();
//
//     REG(GPIO_IOSET) = 0x00000020;
//     wait2();
//     REG(GPIO_IODIR) = 0x00155555;
//     wait2();

    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00
    REG(GPIO_IOSET) = 0x00100000; //Set DDRAM Address

    wait2();
    wait1();
    wait2();




    //busycheck();
    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00

    REG(GPIO_IOSET) = 0x00000001;  //RS = 1, R/W = 0
    REG(GPIO_IOSET) = 0x00041000;  //H
    wait2();
    wait1();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

//     busycheck();
//
//     REG(GPIO_IOSET) = 0x00000020;
//     wait2();
//     REG(GPIO_IODIR) = 0x00155555;
//     wait2();

    REG(GPIO_IOCLR) = 0x00155514; //DB = 0x00

    REG(GPIO_IOSET) = 0x00000001;  //RS = 1, R/W = 0
    REG(GPIO_IOSET) = 0x00041040;  //I
    wait2();
    wait1();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

//     busycheck();
//
//     REG(GPIO_IOSET) = 0x00000020;
//     wait2();
//     REG(GPIO_IODIR) = 0x00155555;
//     wait2();

    REG(GPIO_IOCLR) = 0x00155510; //DB = 0x00

    REG(GPIO_IOCLR) = 0x00000005; //RS = 0, R/W = 0
    REG(GPIO_IOSET) = 0x00000100; // Return home


    wait2();
    wait2();
    wait2();
    for(i=0;i<10;i++)
    {
        wait2();
    }

//     busycheck();
//
//     REG(GPIO_IOSET) = 0x00000020;
//     wait2();
//     REG(GPIO_IODIR) = 0x00155555;
//     wait2();

}


void busycheck(void)
{
    unsigned long i;
    unsigned short x; //changed to short from char
    unsigned long w;

    REG(GPIO_IOCLR) = 0x00155540;

    for(i=0;i<10;i++)
    {
        wait2();
    }

    REG(GPIO_IODIR) = 0x000000E5; //E, RS, R/W => outputs
     
    REG(GPIO_IOCLR) = 0x00000001;
    wait2();
   /* REG(GPIO_IOSET) = 0x00000014; //RS =0, R/W = 1, E = 1  */

    wait2();
    wait2();


    
   
    //while(x & 0x00100000 == 0x00100000)
    //while(1)
    for(i=0;i<10;i++)
     {
         x = REG(GPIO_IOPIN);
         wait2();
         wait2();
         //if(REG(GPIO_IOPIN) & 1048576 == 1048576)
         if(REG(GPIO_IOPIN) & 0x100000 == 0x100000)
         //while(REG(GPIO_IOPIN) & 1048576)
         {
             REG(GPIO_IOSET) = 0x00000080;
             //wait1();
             wait2();
             wait2();
         }
         else
         {
             break;
         }
     }

    REG(GPIO_IOCLR) = 0x00000080;
    wait2();
}
 
The oscillator frequency is 14 MHz. I also commented out the busycheck and port direction change routines as per your suggestion. Below is the updated version of the code.

It seems like there is some serious problem with the LCD. What I tried is that I connected Vdd, Vss and Vo to the LCD module and removed all the connections to the microcontroller. Output on all pins except E are at Vdd. E has a square wave output.
You are saying that the E pin on the display, when not connected to the cpu, is a square wave? At what frequency? Are you using a scope to view this? This may not be important, but it seems peculiar to me.
Now, after connecting to microcontroller board, RS goes low, E varies as per program, but somehow R/W stays at Vdd which is 4.5 V. It does not even go to +3.3V which should be the high output of my microcontroller. As per my program it should be going down to 0V, which never happens all throughout the program. At a point, I was thinking of connecting R/W to GND(which fortunately I didn't do).
At this point, I am wondering if the 3.3v outputs of the cpu are marginal as a 1 state for the display. I know the data sheet says that a 1 state input minimum is 2.2v, but I am just pointing out possible problems. Maybe putting 2Kohm to 5Kohm pullups on the display inputs would help, or maybe not.

As for the R/W not going to 0 state, that sounds like the killer problem. My guess is a wiring error, or the port pin is not being set as an output. As for tying R/W to ground, why not do that? If you don't do the busy check, R/W can always be low (at least until you get things working, and then you can change from the delay method to the busy check method).
It still has those black boxes in 1st and 3rd lines.
Which is normal for an uninitialized display.
As per HD44780U datasheet, RS, R/W and E are inputs by default and thus there should be no output voltage on them whatsoever. Any ideas why is it operating like this?
Don't know. Maybe some implimentations of HD44780 clones have weak pullups on the inputs. Since they are inputs, they shouldn't be left unconnected anyway. The performance of an unconnected display is not specified, AFAIK.

Have you tried my earlier suggestion of test code that toggles one output at a time, so you can verify the wiring is correct?
 

Dhvanish

New member
got it working

:)

Got it working.....

Problem was something unique. My microcontroller kit has been using P0.7 and P0.6 for JTAG debug TMS and TDI respectively. The reason that this thing got undetected was that this leaded to P0.7 to be high all the time, which is also the busy output of the LCD module. So, it used to imply that somehow LCD module was busy processing previous instruction. It's working great now. Thanks Crystalfontz LCD forum for your support. Special thanks to cosmicvoid for prompt precise solutions.
 
Top