lcd1602 weird problem

Discussion in 'Embedded Systems and Microcontrollers' started by bug13, Feb 16, 2015.

  1. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Hi guys

    I am this LCD here:
    http://www.newhavendisplay.com/specs/NHD-C0216CZ-FSW-FBW-3V3.pdf

    W
    hen it power up, it some time works, some time just show nothing. Say 30-40% of the time it just show nothing on the display.

    I believe it's not a hardware problem, as the LCD is on a demo board, and it works fine on their demo firmware.

    Here is my code to initialize the LCD: (feel free to ask if more codes is needed)

    Code (Text):
    1. void LCD_Initialize(void)
    2. {  
    3.     LCD_CS = 1;
    4.     LCD_RESET = 0;  
    5.     //DELAY_ms(8);
    6.     DELAY_ms(8);
    7.     LCD_RESET = 1;
    8.     //DELAY_ms(80);
    9.     DELAY_ms(20);
    10.     LCD_WriteCmd(LCD_WAKEUP);
    11.     //DELAY_ms(8);
    12.     DELAY_ms(2);
    13.     LCD_WriteCmd(LCD_WAKEUP);
    14.     LCD_WriteCmd(LCD_WAKEUP);
    15.     LCD_WriteCmd(LCD_FUNCTION_SET);
    16.     LCD_WriteCmd(LCD_INT_OSC);
    17.     LCD_WriteCmd(LCD_PWR_CTRL);
    18.     LCD_WriteCmd(LCD_FOLLOWER_CTRL);
    19.    
    20.     LCD_WriteCmd(LCDCMD_CONTRASTSET_LOWBYTE);
    21.     LCD_WriteCmd(LCD_ON);
    22.     LCD_WriteCmd(LCD_ENTRY_MODE);
    23.     LCD_WriteCmd(LCDCMD_CLEARDISPLAY);
    24.     DELAY_ms(40);
    25. }
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    Did you install a 0.1μF capacitor across the power rails at the LCD module?
     
  3. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    According the datasheet of the demo board. It has a 0.1uF cap across the power rails at the LCD module. I am guessing its my codes/complier, as the LCD is fine with the demo software. I am using the free version of the XC8 compiler in MPLAP X.
     
  4. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    Isnt the demo source code included?
    Not a compiler issue.

    There are a couple of reasons which can lead to problems for these modules.
     
  5. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Hi

    Yes I am using the demo source code. And it happens to the demo source code too.
     
  6. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    Try powering on the LCD through IO after some waiting, with all the lines set as output + correct state.
     
  7. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    Are you waiting >40ms after Vcc stable before sending commands?
    E line pulled low external to the uC to avoid spurrious commands while the uC is in RESET?
    Have you checked the detailed init sequences in the ST7032 controller's datasheet?

    If you do the init properly, the display will come up and run. You don't need to power it from the IO. The fact that it runs properly with the demo code confirms this.

    Which uC are you using?

    Good luck!

    EDIT: be sure your compiler knows what your clock frequency is so that it can compute the delays accurately.

    Also, note that there is a >26.3 uS delay called out between each instruction during init (and probably between displayed characters as well). You don't have any explicit delay between many of these. If the LCD output routines poll the busy flag you are good but only after the 2ed or 3rd Function-Set. You need delays between these always. If not checking busy be sure that the execution time between the LCD_WriteCmd instructions is long enough to generate the >26.3us or add delays between them.
     
    Last edited: Feb 17, 2015
  8. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Hi guys

    Thanks for all your inputs, after reading all replies and trying a few things, the following works, thanks JohnInTX for pointing this out:

    Code (Text):
    1. void LCD_Initialize(void)
    2. {  
    3.     LCD_CS = 1;
    4.     LCD_RESET = 0;  
    5.     //DELAY_ms(8);
    6.     DELAY_ms(8);
    7.     LCD_RESET = 1;
    8.     //DELAY_ms(80);
    9.     DELAY_ms(20);
    10.     LCD_WriteCmd(LCD_WAKEUP);
    11.     //DELAY_ms(8);
    12.     DELAY_ms(2);
    13.     LCD_WriteCmd(LCD_WAKEUP);
    14.     DELAY_ms(1);
    15.     LCD_WriteCmd(LCD_WAKEUP);
    16.     DELAY_ms(1);
    17.     LCD_WriteCmd(LCD_FUNCTION_SET);
    18.     DELAY_ms(1);
    19.     LCD_WriteCmd(LCD_INT_OSC);
    20.     DELAY_ms(1);
    21.     LCD_WriteCmd(LCD_PWR_CTRL);
    22.    DELAY_ms(1);
    23.     LCD_WriteCmd(LCD_FOLLOWER_CTRL);
    24.     DELAY_ms(1);
    25.     LCD_WriteCmd(LCDCMD_CONTRASTSET_LOWBYTE);
    26.     DELAY_ms(1);
    27.     LCD_WriteCmd(LCD_ON);
    28.     DELAY_ms(1);
    29.     LCD_WriteCmd(LCD_ENTRY_MODE);
    30.     DELAY_ms(1);
    31.     LCD_WriteCmd(LCDCMD_CLEARDISPLAY);
    32.     DELAY_ms(40);
    33. }
     
  9. JohnInTX

    Moderator

    Jun 26, 2012
    2,347
    1,029
    Well done.

    Now.. if you are not polling the busy flag, write your character out routine to ensure that it takes at least 30uS (from the example in the controller's datasheet) between characters. For 30uS, I'd probably just do some housekeeping (bump a pointer to the next character etc.) and make sure it took at least 30uS to execute - maybe add an inline assembler delay to make up any difference. I'd try to avoid the 1ms delay between chars if possible. I don't like burning any more CPU time than I have to. Eventually, it always seems to come back and bite me.

    I find things in this time range problematic - you don't want to use a 1ms delay for 30uS intervals. An interrupt-driven timer for 30uS delay would essentially be a dumb delay because the interrupt service latency would likely take the 30uS anyway so I'd just try to do whatever housekeeping I could towards using up 30uS and burn the few uS left in NOPs or some other short delay.

    Looks good, though. Have fun.
     
    Last edited: Feb 18, 2015
    bug13 likes this.
  10. bug13

    Thread Starter Well-Known Member

    Feb 13, 2012
    1,208
    38
    Thanks for your help. I will change my code to poll the busy flag. The above code just something quick and dirty to get it working. Thanks a lot!
     
Loading...