18F452 LCD Program will not work

Author
Grandpa Jay
Super Member
  • Total Posts : 279
  • Reward points : 0
  • Joined: 2006/11/21 17:08:59
  • Location: Fuquay Varina, NC
  • Status: offline
2014/10/07 12:32:56 (permalink)
0

18F452 LCD Program will not work

Gentlemen
I have been trying to get this program to work for several days.  It builds and programs OK but nothing shows on the LCD except the highlighted blocks.  This code is from PyroElectro.com with some additions.  I am using a OLIMEX 40 pin board with 20MHz crystal.  I would like someone to look at the code and see what is wrong.  I am not using xlcd.h due to different ports and pins.  I am wired for 4 bit operation.
I am having a hard time attaching a file.
Jay
 
#1

16 Replies Related Threads

    Grandpa Jay
    Super Member
    • Total Posts : 279
    • Reward points : 0
    • Joined: 2006/11/21 17:08:59
    • Location: Fuquay Varina, NC
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/07 12:39:21 (permalink)
    0
    Still trying to add file.
    post edited by Grandpa Jay - 2014/10/07 13:55:58

    Attachment(s)

    Attachments are not available: Download requirements not met
    #2
    ric
    Super Member
    • Total Posts : 22101
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/07 14:10:17 (permalink)
    +1 (1)
    Just some quick comments looking at that code
     
    commd() is not setting the RS pin, just assuming it is low.
    Both commd() and prnt() are specifying an unsigned 16 bit parameter, when they really only want an 8 bit parameter. That's just wasting resources.
     
    Timing is critical during the first few writes to the display to initialise it. I see you have some delays, but they are in clock cycles. It would be easier to follow if you used the macros for us and ms delays, and carefully double check that your delays match what the LCD datasheet specifies.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #3
    vegipete
    Junior Member
    • Total Posts : 115
    • Reward points : 0
    • Joined: 2009/03/09 16:27:18
    • Location: Sol 3
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/07 14:31:44 (permalink)
    +2 (2)
    I would suggest changing your prnt and commd functions so that RS is set or cleared once at the start and never touched again. You should also write the 4 bits to LATC, not PORTC.
     
    Finally, that lcd init sequence looks odd. You can't send 2 nibbles per command until you've set the LCD to 4 bit mode. Sending "0x3?" sets 8 bit mode. Sending "0x2?" sets 4 bit mode but requires sending these as all 8 bits at once. The "?" part is unimportant because those lower 4 bits are not connected. The delays between commands also need to be considered - some take a while, 30 milliseconds or more.
     
    You'll need another function, commd8, that clears RS, sets LATC = commd >> 4 and toggles E high then low before exiting. That will send '8 bit' commands to the LCD where the lower 4 bits are ignored.
    #4
    Grandpa Jay
    Super Member
    • Total Posts : 279
    • Reward points : 0
    • Joined: 2006/11/21 17:08:59
    • Location: Fuquay Varina, NC
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 08:52:49 (permalink)
    0
    Thank you gents
    I think that I have changed so much that I lost track.  The program still does not work.  When I use debug it steps through everything  as I think it should.  The print and commd show up as 16 bit words and they do not change.  The LATC changes as it should.  Most of the delays are set according to  the data sheet.  Should I set them higher?  
    Jay 

    Attachment(s)

    Attachments are not available: Download requirements not met
    #5
    Ian.M
    Super Member
    • Total Posts : 13114
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 09:35:59 (permalink)
    +1 (1)
    There's currently a *NASTY* compiler bug affecting delays with parts in this family. See the current topic: Delay with 18F252
     
    I normally code the delays from the LCD datasheet in ms or us as #defines then apply them with a #defined multiplier.  1.1 is good for normal use - 10% slower than the minimum delays in the datasheet,  but for initial testing and debugging a multiplier of 2 is good - double all the delays.
    One old genuine Hitachi display I have *needs* double the datasheet delay or it just doesn't work.    Your delays seem to be rather mixed up and the init timing and sequence is incorrect
     
    Also you are going to run into RMW problems with:
    #define  RW_PIN   PORTDbits.RD1   /* PORT for RW */
    #define  RS_PIN   PORTDbits.RD2   /* PORT for RS */
    #define  E_PIN    PORTDbits.RD0   /* PORT for E  */

    as you are bit-banging those pins individually.  You *MUST* change those defines to the corrisponding LAT bits.

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #6
    Grandpa Jay
    Super Member
    • Total Posts : 279
    • Reward points : 0
    • Joined: 2006/11/21 17:08:59
    • Location: Fuquay Varina, NC
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 11:20:10 (permalink)
    0
    Ian
    I changed most of PORTx to LATx them but forgot these.  The init timing is from my data sheet GDM1602K.  Where can I find the correct sequence for the init?
    Jay
    #7
    Ian.M
    Super Member
    • Total Posts : 13114
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 12:28:45 (permalink)
    +1 (1)
    I believe the GDM1602K uses a clone of a Samsung KS0066U controller which is itself supposed to be Hitachi HD44780U compatible.  Can you post a link to the datasheet(s) you are actually working from?
     
    The Samsung 4 bit initialisation sequence is known to have problems if Vdd doesn't come up fast enough to trigger the automatic 8 bit initialisation or if it glitches on power up.
     
    Try the Hitachi 4-Bit Interface initialisation sequence (page 46 of the HD44780U datasheet) but make sure none of the delays are shorter than the equivalent ones from your datasheet.
     
     
     
    post edited by Ian.M - 2015/12/12 04:30:12

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #8
    Grandpa Jay
    Super Member
    • Total Posts : 279
    • Reward points : 0
    • Joined: 2006/11/21 17:08:59
    • Location: Fuquay Varina, NC
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 14:39:29 (permalink)
    0
    Ian
    Yes my LCD is a clone of the .  Sparkfun only supplied the first 9 pages of the datasheet.  Otherwise it's the same.  The sequence is a little different than the HD44780U datasheet.
    In looking at the Samsung datasheet pg 42:
    1. Where do the other 4 bits go?
    2. How do you handle the first 8 bit word step 2.
    3. Is DB4-7 shifted out first or last?
    4. Step 3 is the data 0b001000xx?
    5. Step 3 requires a reset.  How is this done?
    I think that I should start over with a 18F4520 that I have and maybe a new program.
    In debug mode why can I not get the commd and prnt to show as 8 bit.  They also do not show data.  I do not see where they are defined.
    Jay
    #9
    ric
    Super Member
    • Total Posts : 22101
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 14:56:09 (permalink)
    +1 (1)
    Grandpa Jay
    In looking at the Samsung datasheet pg 42:

    Which Samsung datasheet? The KS0066U sheet that Ian posted only goes up to page 33.
     

    1. Where do the other 4 bits go?

    They are "don't care" in 4 bit mode. It's usual to tie them low.
     

    2. How do you handle the first 8 bit word step 2.

    Just do one write per instruction. You are supplying the upper 4 bits. The lower 4 bits are "don't care".
     

    3. Is DB4-7 shifted out first or last?

    Not relevant. You're only doing one write.
     

    4. Step 3 is the data 0b001000xx?
    5. Step 3 requires a reset.  How is this done?

    I'm not sure what "step 3" is on the page you are looking at.
     

    In debug mode why can I not get the commd and prnt to show as 8 bit.  They also do not show data.  I do not see where they are defined.

    I don't understand what you are asking here. commd() and prnt() are functions in your program. What do you mean "show as 8 bit" ?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #10
    Grandpa Jay
    Super Member
    • Total Posts : 279
    • Reward points : 0
    • Joined: 2006/11/21 17:08:59
    • Location: Fuquay Varina, NC
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 16:44:27 (permalink)
    0
    Ric
    the questions refer to the HD44780U datasheet.  My program is setup with reference to the Samsung datasheet.
    In debug mode the Watch window lists the commd() and prnt() as 16 bit.  I would think that they should display the character value 8 bit.  They are listed in the global symbols.
    Jay
    #11
    ric
    Super Member
    • Total Posts : 22101
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 16:59:33 (permalink)
    0
    Grandpa Jay
    ...
    the questions refer to the HD44780U datasheet.

    I see. It's a little confusing to say "looking at the Samsung datasheet" when you mean the Hitachi datasheet.
     
    You should treat each line in the Hitachi datasheet as a single write to the panel. As vegipete mentioned above, don't start doing the "two writes to transfer two nibbles" until after you have finished setting the display to 4 bit mode.
    This means you can NOT use your commd() function to send the initialisation commands.
     
    In debug mode the Watch window lists the commd() and prnt() as 16 bit.  I would think that they should display the character value 8 bit.  They are listed in the global symbols.

    I'm not sure what you think adding a function to the watch window will do. It is probably showing the address of the function. Did you think it would show the parameter being passed TO the function?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #12
    Grandpa Jay
    Super Member
    • Total Posts : 279
    • Reward points : 0
    • Joined: 2006/11/21 17:08:59
    • Location: Fuquay Varina, NC
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 17:37:12 (permalink)
    0
    Ric
    Sorry my mistake on that datasheet mixup.
    I thought that if it is listed as a global symbol along with all the others that it would show data correctly.
    The more I dig the farther behind I get.
    In the Hitachi datasheet pg 42 (4 bit) the Function Set is entered 3 times.
    Thank you for trying.
    Jay
    #13
    Ian.M
    Super Member
    • Total Posts : 13114
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 19:03:41 (permalink)
    +3 (3)
    The key thing to realise about the Hitachi 4 bit initialisation sequence is that the HD44780U, the KS0066U and clones of them are *INCREDIBLY* fussy about the conditions to successfully execute their power on reset sequence that is supposed to put them into "ready to run" 8 bit mode:
    • Display clear
    • Function set: DL = 1 (8-bit interface data), N = 0 (1-line display), F = 0 (5x8 dot character font)
    • Display on/off control: D = 0 (Display off), C = 0 (Cursor off), B = 0 (Blinking off)
    • Entry mode set: I/D = 1 (Increment cursor), S = 0 (No shift)
    If module Vdd does not rise smoothly from zero to 90% in well under 10ms, at random it can power up in 4 bit mode and even half way through a 4 bit command entry.
     
    The Hitachi initialisation sequences start with the command to set 8 bit mode (0011xxxx) strobed in three times:
    • The first time, if the module is in 8 bit mode, it may work immediately. then the following two repeats don't change anything.
    • However if it is in 4 bit mode it may either be:
      • interpreted as the first nibble of a command with one more nibble needed to complete the command.  The second strobe sets 8 bit mode and the third (now in 8 bit mode) doesn't change anything.
      • interpreted as the second nibble of a (bogus) command which will have a random effect. The next strobe is the first nibble and the third strobe finally sets 8 bit mode.
    At this point the module's interface is in a known state and is receptive to further commands.  There are a few pitfalls:
    • The correct powerup delay must be allowed before the first strobe pulse. 
    • As the bogus 4 bit command is not known, the delay between the first and second strobes must be long enough to allow for the very slow 'Clear' or 'Home' commands. 
    • The delay between the second and third strobes is small (the 4 bit mode inter-nibble delay) because in the first two states it could have been in, it doesn't matter if the third strobe gets ignored due to the display not being ready as 8 bit mode has already been successfully set.
    • The delay after the third strobe must be long enough to execute a normal (short) command.
      So the full 4 bit initialisation psuedocode is:
    1. Set all control and data lines low
    2. Wait T_Powerup
    3. Set R/W low, RS low and output 0011 to the high nibble of the display data bus
    4. Wait T_Nibble  // The setup time is less than the delay between 4 bit nibbles
    5. Strobe EN (Pulse EN high for T_Strobe)
    6. Wait T_SlowCmd
    7. Strobe EN
    8. Wait T_Nibble
    9. Strobe EN
    10. Wait T_Cmd
      • At this point the display is guaranteed to be in 8 bit mode, ready for a command.
    11. Output 0010 to the high nibble of the display data bus
    12. Wait T_Nibble
    13. Strobe EN
    14. Wait T_Cmd
      • At this point the display is guaranteed to be in 4 bit mode and ready for a command. The remainder of the init sequence can use your write() subroutine which should send (strobe out) two nibbles with correct timing.
    15. Send 'Function Set', (0x20, 0x24, 0X28 or 0x2C depending on the number of logical lines and font size of the LCD module)
      • The command *MUST* stay in 4 bit mode. Don't  use 'Function Set' again unless doing a full reinit.
    16. Either wait T_Cmd or poll the busy bit (using your two nibble read() routine)
    17. Send 'Display Off' // You want to hide powerup garbage A.S.A.P.
    18. Either wait T_Cmd or poll the busy bit
    19. Send 'Display Clear'
    20. Either wait T_SlowCmd or poll the busy bit
    21. Send 'Entry Mode Set'
    22. Either wait T_Cmd or poll the busy bit
    23. Send 'Display On'
    24. Either wait T_Cmd or poll the busy bit
    25. Set RS high
    The display is now ready to use,  and will display characters sent to it.
     
    8 bit initialisation is very similar - leave out steps 11 to 14 and use a 8 bit mode 'function set' command in step 15.
     
    Edit: Corrected sense of RS signal in psuedocode to match HD44780 datasheet.  Thanks MRR for pointing out my mistake.
    post edited by Ian.M - 2015/03/30 09:41:41

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #14
    ric
    Super Member
    • Total Posts : 22101
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 19:30:46 (permalink)
    +1 (1)
    Great description Ian. :)
    I'd always just followed the Hitachi instructions, and never had a problem.
    I didn't bother analysing why such a convoluted process was necessary, because it always worked if I followed their recommendations. Your description makes it clear.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #15
    Ian.M
    Super Member
    • Total Posts : 13114
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/08 21:36:06 (permalink)
    +1 (1)
    It should be noted that the PLIB XLCD initialisation is extremely poorly written, buggy and difficult to maintain:

    #include <p18cxxx.h>
    #include "delays.h"
    #include <xlcd.h>

    /********************************************************************
    *       Function Name:  OpenXLCD                                    *
    *       Return Value:   void                                        *
    *       Parameters:     lcdtype: sets the type of LCD (lines)       *
    *       Description:    This routine configures the LCD. Based on   *
    *                       the Hitachi HD44780 LCD controller. The     *
    *                       routine will configure the I/O pins of the  *
    *                       microcontroller, setup the LCD for 4- or    *
    *                       8-bit mode and clear the display. The user  *
    *                       must provide three delay routines:          *
    *                       DelayFor18TCY() provides a 18 Tcy delay     *
    *                       DelayPORXLCD() provides at least 15ms delay *
    *                       DelayXLCD() provides at least 5ms delay     *
    ********************************************************************/
    void OpenXLCD(unsigned char lcdtype)
    {
            // The data bits must be either a 8-bit port or the upper or
            // lower 4-bits of a port. These pins are made into inputs
    #ifdef BIT8                             // 8-bit mode, use whole port
            DATA_PORT = 0;
            TRIS_DATA_PORT = 0x00;
    #else                                   // 4-bit mode
    #ifdef UPPER                            // Upper 4-bits of the port
            DATA_PORT &= 0x0f;
            TRIS_DATA_PORT &= 0x0F;
    #else                                   // Lower 4-bits of the port
            DATA_PORT &= 0xf0;
            TRIS_DATA_PORT &= 0xF0;
    #endif
    #endif
            TRIS_RW = 0;                    // All control signals made outputs
            TRIS_RS = 0;
            TRIS_E = 0;
            RW_PIN = 0;                     // R/W pin made low
            RS_PIN = 0;                     // Register select pin made low
            E_PIN = 0;                      // Clock pin made low

            // Delay for 15ms to allow for LCD Power on reset
            DelayPORXLCD();
     //-------------------reset procedure through software----------------------       
             WriteCmdXLCD(0x30);
                Delay10KTCYx(0x05);

             WriteCmdXLCD(0x30);
                Delay10KTCYx(0x01);


             WriteCmdXLCD(0x32);
            while( BusyXLCD() );
    //------------------------------------------------------------------------------------------


            // Set data interface width, # lines, font
            while(BusyXLCD());              // Wait if LCD busy
            WriteCmdXLCD(lcdtype);          // Function set cmd

            // Turn the display on then off
            while(BusyXLCD());              // Wait if LCD busy
            WriteCmdXLCD(DOFF&CURSOR_OFF&BLINK_OFF);        // Display OFF/Blink OFF
            while(BusyXLCD());              // Wait if LCD busy
            WriteCmdXLCD(DON&CURSOR_ON&BLINK_ON);           // Display ON/Blink ON

            // Clear display
            while(BusyXLCD());              // Wait if LCD busy
            WriteCmdXLCD(0x01);             // Clear display

            // Set entry mode inc, no shift
            while(BusyXLCD());              // Wait if LCD busy
            WriteCmdXLCD(SHIFT_CUR_LEFT);   // Entry Mode

            // Set DD Ram address to 0
            while(BusyXLCD());              // Wait if LCD busy
            SetDDRamAddr(0x80);                // Set Display data ram address to 0

            return;
    }

     
    The first oddity is that after the 3rd strobe, the display is in 8 bit mode, but if the interface is 4 bit BusyXLCD() polls the bus twice discarding the second read of the BUSY bit!  This isn't actually a bug but is certainly bad style - especially without any comments.
     
    The second oddity is the use of  Delay10KTCYx() with absolute numeric parameters. It only works because its *MUCH* slower that it needs to be - even with a Fosc of 64MHz.   If you are ambling along at 4MHz, the initialisation display is starting to get noticeable to the human eye.  You can have garbage on the display for nearly a tenth of a second!
     
    The third oddity is the  use of WriteCmd() in the early stages of the initialisation. If 4 bit mode is selected, the second strobe for the low nibble will be ignored as the display will be busy executing the command. 
     
    If one works your way through the nibbles sent and the timing on can show it will work with original HD44780U or KS055U controllers.  However it relies on the display ignoring nibbles that are sent too quickly and will break if used with a display that latches the data in hardwareon the trailing edge of EN.
     
    The programmer who wrote it must have been smoking the wackky-baccy and whoever let it through code review was either a sado-masochist or a moron!
     
    Here's the  4 bit initialisation from the LCDdemo supplied with  HiTech C for PIC10/12/16 v9.83:

    #define    LCD_STROBE()    ((LCD_EN = 1),(LCD_EN=0))
     
    /* initialise the LCD - put into 4 bit mode */
    void
    lcd_init()
    {
        char init_value;

        ADCON1 = 0x06;    // Disable analog pins on PORTA

        init_value = 0x3;
        TRISA=0;
        TRISD=0;
        LCD_RS = 0;
        LCD_EN = 0;
        LCD_RW = 0;
        
        __delay_ms(15);    // wait 15mSec after power applied,
        LCD_DATA     = init_value;
        LCD_STROBE();
        __delay_ms(5);
        LCD_STROBE();
        __delay_us(200);
        LCD_STROBE();
        __delay_us(200);
        LCD_DATA = 2;    // Four bit mode
        LCD_STROBE();

        lcd_write(0x28); // Set interface length
        lcd_write(0xF); // Display On, Cursor On, Cursor Blink
        lcd_clear();    // Clear screen
        lcd_write(0x6); // Set entry Mode
    }

    This does follow the Hitachi sequence properly as long as Fosc is 8MHz or under - otherwise the strobe pulse needs added NOPs for setup time and to keep it wide enough.  Its got hard coded timing constants so isn't *WELL* written but its an order of magnitude more intelligible and maintainable than the XLCD version.
     
    Finally, I have found Christopher Burian's HD44780 LCD FAQ to be far clearer than most of the LCD controller datasheets.  Unfortunately its no longer updated, but it can be found at: http://www.repairfaq.org/filipg/LINK/F_Tech_LCD.html
    A slightly older PDF version is at:
    http://www.avrfreaks.net/sites/default/files/Hitachi%20HD44780%20LCD%20FAQ.pdf
     
    Do verify timings against your actual LCD module datasheet.  They are only valid if the controller is running at its nominal clock frequency and especially for older extended temperature range displays, may be slower than the HD44780U timings by a factor of two or more!

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #16
    Grandpa Jay
    Super Member
    • Total Posts : 279
    • Reward points : 0
    • Joined: 2006/11/21 17:08:59
    • Location: Fuquay Varina, NC
    • Status: offline
    Re: 18F452 LCD Program will not work 2014/10/10 04:57:14 (permalink)
    +1 (1)
    Gentelmen 
    I think I may have found my problem.  A bad LCD.  D5 pulls the signal low, not like the other pins.  I will be ordering a new LCD.
    Thank you
    Jay
    #17
    Jump to:
    © 2018 APG vNext Trial Version 4.5