NHD-0420DZW-AY5 with scrambled display

Comments

6 comments

  • Saurabh_B
    Hi,

    From past experiences, it's usually a timing issue that causes strange characters to appear onto the display. This usually happens after the units have been running for a while. Usually when the timing commands are right on the threshold of the specifications.

    I was wondering if you could tell me what interface you were using?
     
    « Last Edit: July 30, 2015, 02:54:48 PM by Saurabh_B »
    0
  • hvilleneuve

    Hi,
    we are using the parallel interface, 6800 mode (default).

    In our case, the timing is not on the margin, far from it. For example, the specifications requires a minimum pulse width of 250nS for the enable signal, we are at 350uS.

    0
  • Saurabh_B

    Would it be possible to take a look at the code you are using to initialize the LCD and write to it?

    0
  • hvilleneuve
    /* LCD commands */
    #define CHARLCD_CMD_CLEAR   0x01
    #define CHARLCD_CMD_HOME    0x02
    #define CHARLCD_CMD_ENTRY   0x04
    #define CHARLCD_CMD_DISPLAY 0x08
    #define CHARLCD_CMD_FS      0x20  /* function set */
    #define CHARLCD_CMD_ADDR_DD 0x80
    #define CHARLCD_CMD_ADDR_CG 0x40

    /* Bit fields */
    #define CHARLCD_CMD_FS_D8  (1<<4) /* 8bit display */
    #define CHARLCD_CMD_FS_2L  (1<<3) /* two lines */
    #define CHARLCD_CMD_FS_5x8 (0<<2) /* 5x8 font */
    #define LCD_DISPLAY_ON     (1<<2)
    #define LCD_DISPLAY_OFF    (0<<2)
    #define LCD_CURSOR_ON      (1<<1)
    #define LCD_CURSOR_OFF     (0<<1)

    #define LCD_FONT_ENG_JAP      (0x00)
    #define LCD_FONT_WEST_EUROPE1 (0x01)
    #define LCD_FONT_ENG_RUSSIAN  (0x02)
    #define LCD_FONT_WEST_EUROPE2 (0x03)

    #define CHARLCD_STAT_BUSY  0x80

    /* Maximum execution time is for the CLEAR DISPLAY command. */
    #define MAX_EXECUTION_TIME_MS 2

    void WriteLCD(qint8 controls, qint8 data)
    {
        LCD_device_->WriteI2Cint((quint16)(data * 256 + controls));
        /*
         * No need to introduce delay here: the maximum setup time between
         * any commands is 250nS, and the previous command takes around 300uS
         * to execute.
         */
    }

    void WriteCommand(qint8 command)
    {
        WaitReady();
        WriteLCD(0x00, command); /* RS=0, R/W=0, E=0 */
        WriteLCD(ENABLE_LCD, command); /* E=1 */
        WriteLCD(0x00, command); /* E=0 */

    }

    void WriteData(qint8 data)
    {
        WaitReady();
        WriteLCD(DATA_SELECT, data); /* RS=1, R/W=0 */
        WriteLCD(DATA_SELECT | ENABLE_LCD, data); /* RS=1, R/W=0, E=1 */
        WriteLCD(DATA_SELECT, data); /* E=0 */
    }

    qint8 ReadLCDStatus()
    {
        uint8_t returned_value[2];

        returned_value[0] = 0;
        returned_value[1] = 0;

        WriteLCD(READ_nWRITE, LCD_DATA_BUS_INPUT); /* RS=0, R/W=1, E=0 */
        WriteLCD(ENABLE_LCD | READ_nWRITE, LCD_DATA_BUS_INPUT);
        LCD_device_->ReadI2C(returned_value, sizeof(returned_value));
        WriteLCD(READ_nWRITE, LCD_DATA_BUS_INPUT); /* RS=0, R/W=1, E=0 */

        return returned_value[1];
    }

    void lcd_init(void)
    {
        uint8_t v;

        /* Initial state: RS=0, R/W=0, E=0, data bus is input */
        WriteLCD(0x00, LCD_DATA_BUS_INPUT);

        /*
         * Make sure to configure 8-bit interface first.
         * Send the command 3 times, to take into account the fact that the LCD
         * could be in 4 bit mode, and not in sync.
         */
        v = CHARLCD_CMD_FS |   /* Function set */
            CHARLCD_CMD_FS_D8; /* 8-bit interface */
        WriteCommand(v);
        WriteCommand(v);
        WriteCommand(v);

        v = CHARLCD_CMD_FS |     /* Function set */
            CHARLCD_CMD_FS_D8 |  /* 8-bit interface */
            CHARLCD_CMD_FS_2L |  /* 2 lines mode */
            CHARLCD_CMD_FS_5x8 | /* 5x8 font */
            LCD_FONT_WEST_EUROPE1;
        WriteCommand(v);

        /* From this point on, the BUSY flag and address counters can be read. */
        busy_flag_valid = true;

        /* Turn display OFF. */
        WriteCommand(CHARLCD_CMD_DISPLAY | LCD_DISPLAY_OFF);

        /* Clear display */
        WriteCommand(CHARLCD_CMD_CLEAR);

        /* Entry mode set */
        WriteCommand(CHARLCD_CMD_ENTRY | LCD_MODE_INCREMENT);

        /* Return home. */
        WriteCommand(CHARLCD_CMD_HOME);

        /* Turn display ON. */
        WriteCommand(CHARLCD_CMD_DISPLAY | LCD_DISPLAY_ON);
    }
    0
  • Saurabh_B

    Hi,
    I was wondering what that WaitReady function?

    I still suspect timing might be the issue.

    For the Write LCD function you mention that the execution time for previous command is around 300us. In the Table of command it does mention that most of the commands do have a 600us max execution time.

    0
  • hvilleneuve

    The 300uS in the comment refers to the SETUP time, not the MAX EXECUTION TIME. These are two separate things.

    The WaitReady function polls the STATUS bit to know when the LCD is ready to accept new commands.

    0

Please sign in to leave a comment.