LCD damaged?

Discussion in 'General Electronics Chat' started by winson, Feb 1, 2009.

  1. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    Hi everybody,

    I was trying to write a simple LCD testing program to display "P" on 1st line and display "L" on the 2nd line, but my 16x2 LCD just show 2 line of grey square. I was using the Port C & Port D of my PIC16F877A and using 8-bits interface to display character on my LCD. I also try to put a pullup resistor to all the port's pins that used but the results is still the same. The 8 data pins of the LCD is connect to Port D and RS, RW, E is connect to the first 3 pins(RA0, RA1, RA2) of Port C.

    I was using CCS C compiler, to write this testing program i was refer to the information provided in the HD44780U datasheet.

    Anybody can give some suggestions regarding the error that i have make?
    The testing program is shown below.

    Any suggestion will be greatly appreciate.
    Thanks.

    Code ( (Unknown Language)):
    1.  
    2. #include <16F877A.h>
    3. #fuses hs, nowdt, nolvp, noprotect   //Config
    4. #use delay (clock = 20000000)      //20MHz Crystal
    5.  
    6. void init(void);      //Function Prototype
    7. void busy_test(void);
    8. void display(void);
    9. void send_command(void);
    10. void send_data(void);
    11.  
    12. unsigned char PORTC, TRISC, PORTD, TRISD, RS, RW, E, BF;
    13. unsigned char command, data;
    14.  
    15. #byte PORTC = 0x07
    16. #byte TRISC = 0x87
    17. #byte PORTD = 0x08
    18. #byte TRISD = 0x88
    19.  
    20. #bit RS = PORTC.0
    21. #bit RW = PORTC.1
    22. #bit E  = PORTC.2
    23. #bit BF = PORTD.7
    24.  
    25. void main()
    26. {
    27.    init();
    28.    display();
    29.    while (1)
    30.    {
    31.  
    32.    }  
    33. }
    34.  
    35. void init()
    36. {
    37.    PORTC = 0x00;   //Clear Port C
    38.    PORTD = 0x00;   //Clear Port D
    39.  
    40.    TRISC = 0x00;   //Set Port C As Output
    41.    TRISD = 0x00;   //Set Port D As Output
    42.  
    43.    delay_ms (500);   //Power-On Delay
    44.          //Busy Flag Valid Here
    45.  
    46.    //busy_test();   //Check Busy Flag
    47.    command = 0x38;   //8-Bits, 2-Lines, 5x7 Dots
    48.    send_command();   //Send Command To LCD
    49.  
    50.    delay_ms (10);
    51.  
    52.    //busy_test();   //Check Busy Flag
    53.    command = 0x38;   //8-Bits, 2-Lines, 5x7 Dots
    54.    send_command();   //Send Command To LCD
    55.  
    56.    delay_us (500);
    57.  
    58.    //busy_test();   //Check Busy Flag
    59.    command = 0x38;   //8-Bits, 2-Lines, 5x7 Dots
    60.    send_command();   //Send Command To LCD
    61.  
    62.    delay_ms (1);
    63.  
    64.    busy_test();   //Check Busy Flag
    65.    command = 0x38;   //8-Bits, 2-Lines, 5x7 Dots
    66.    send_command();   //Send Command To LCD
    67.  
    68.    delay_ms (1);
    69.  
    70.    busy_test();   //Check BF
    71.    command = 0x08;   //Display Off, Cursor Off, No-Blink
    72.    send_command();   //Send
    73.  
    74.    delay_ms (1);
    75.  
    76.    busy_test();
    77.    command = 0x01;   //Clear Display
    78.    send_command();
    79.  
    80.    delay_ms (5);
    81.  
    82.    busy_test();
    83.    command = 0x06;   //Increment Cursor Position, No-Shift
    84.    send_command();
    85.  
    86.    delay_ms (1);
    87.  
    88.    busy_test();
    89.    command = 0x0F;   //Display On, Cursor On, Blink
    90.    send_command();
    91.  
    92.    delay_ms (1);
    93. }
    94.  
    95.  
    96. void display()
    97. {
    98.  
    99.    busy_test();
    100.    command = 0x80;   //Set DDRAM Address To 0x00
    101.    send_command();
    102.  
    103.    delay_ms (1);
    104.  
    105.    busy_test();
    106.    data = 0x50;   //Display "P"
    107.    send_data();
    108.  
    109.    delay_ms (1);
    110.  
    111.    busy_test();
    112.    command = 0xC0;   //Set DDRAM Address To 0x40
    113.    send_command();
    114.  
    115.    delay_ms (1);
    116.  
    117.    busy_test();
    118.    data = 0x4C;   //Display "L"
    119.    send_data();
    120.  
    121.    delay_ms (1);
    122.  
    123. }
    124.  
    125.  
    126. void busy_test()
    127. {
    128.    while (1)
    129.    {
    130.       TRISD = 0xFF;      //Set Port D As Input
    131.       //RS = 0;            //Command
    132.       //RW = 1;            //Read Busy Flag
    133.       PORTC = 0x02;
    134.  
    135.       delay_cycles (2);   //Control Setup Time
    136.       //E  = 1;            //E-Line High
    137.       PORTC = 0x06;
    138.  
    139.       delay_cycles (6);   //Wait Data Return
    140.  
    141.       if (BF == 0)
    142.       {
    143.          TRISD = 0x00;   //Set Port D Back To Output
    144.          //E  = 0;         //E-Line Low
    145.          PORTC = 0x02;
    146.          return;
    147.       }
    148.  
    149.       //E  = 0;            //E-Line Low
    150.       PORTC = 0x02;
    151.    }      //End while loop
    152. }      //End Function
    153.  
    154.  
    155. void send_command()
    156. {  
    157.    //RS = 0;            //Command
    158.    //RW = 0;            //Write Instruction
    159.    PORTC = 0x00;
    160.  
    161.    delay_cycles (2);   //Control Setup Time
    162.    //E  = 1;            //E-Line High
    163.    PORTC = 0x04;
    164.  
    165.    delay_cycles (3);  
    166.    PORTD = command;   //Put Command To Port D
    167.  
    168.    delay_cycles (3);   //Data Setup Time
    169.    //E  = 0;            //E-Line Low
    170.    PORTC = 0x00;
    171.    delay_cycles (1);   //Control & Data Hold Time
    172. }
    173.  
    174.  
    175. void send_data()
    176. {
    177.    //RS = 1;            //Data
    178.    //RW = 0;            //Write data
    179.    PORTC = 0x01;
    180.    
    181.    delay_cycles (2);   //Control Setup Time
    182.    //E  = 1;            //E-Line High
    183.    PORTC = 0x05;
    184.  
    185.    delay_cycles (3);
    186.    PORTD = data;      //Put Data To Port D
    187.  
    188.    delay_cycles (3);   //Data Setup Time
    189.    //E  = 0;            //E-Line Low
    190.    PORTC = 0x01;
    191.    delay_cycles (1);   //Control & Data Hold Time
    192. }
    193.  
     
  2. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    Finally the LCD is able to display. The problem is on the supply voltage.
     
  3. Wendy

    Moderator

    Mar 24, 2008
    20,765
    2,536
    Thanks for the feedback. Most people don't, always appriciated when you do.
     
  4. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    The problem is in the power supply. The 5V Vdd supply voltage drop to 4.33V when it is connect to the LCD. I was using a battery for the LCD, due to high supply current of the 9V battery, thus have to put a current limiting resistor to limit the current that goes into the LCD, And i think because of the LCD consist of certain amount of internal resistance(from calculation it is around 23.23K ohms), this resistance will form a voltage divider with my current limiting resistor and make the supply voltage to the LCD drop to 4.33V. Normally, for LCD it's Vdd range is from 4.5V to 5.5V in order for it to work correctly.

    After adjust the value of the current limiting resistor to get back a Vdd which is around 4.6V then the LCD work nicely. Besides, for the Vo of the LCD i was directly connect it to ground to get maximum contrast, this is to avoid the variable resistor(pot) that use to control the contrast from disturbing the voltage value of the Vdd.

    For the send_command() and send_data() function i was modify the code to first load the data to the Port D then toggle the E signal from low to high then goes back to low again. I think it also work by set the E signal to high first then load data to Port D and after that set E to low, but since the LCD is working then i will follow the modified code.
     
  5. NavjeetSingh

    New Member

    Feb 8, 2009
    9
    0
    Thanks for the second post. I never knew that the LCD resistance could be such a big problem. You have explained it quite well, giving the numerical details along with explanation.

    Would you please take the pain of explaining the way you did troubleshooting. I always get stuck whenever I'm asked to do troubleshooting. Would you name the instruments too (those you used to troubleshoot).
     
  6. winson

    Thread Starter Member

    Dec 3, 2008
    23
    0
    Hi NavjeetSingh,

    To troubleshoot my LCD problem, i was not using many instruments just my tiny digital multimeter. During that first time when problem occur, a 3.3K ohms current limiting resistor was connected in series with the Vdd pin of the LCD and what i doing is just use the multimeter to measure the voltage in the point between the 3.3k resistor and Vdd of LCD with respect to ground and the value that i get is 4.33V which insufficient for a typical LCD display. Then i just using the formula of the voltage divider rule to calculate out the resistance of the LCD by just assume we have 2 resistors, one is the 3.3k another one is the LCD resistance. To obtain the correct value of the current limiting resistor i was just using the voltage divider rule again with LCD resistance value(23.23k) that i calculated just now to calculate out the value of the current limiting resistor which can give 4.6V and 2.5mA. For a typical LCD it need 4.5V to 5.5V and around 3mA of current to it's Vdd pin.
     
    Last edited: Feb 8, 2009
Loading...