New Haven LCD NHD-C0220AZ-FSW-FTW with CY8C3866LTI-030

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi,

   

I wanted to share an issue I had when trying to communicate with a New Haven LCD.

   

It is a 2x20 character LCD with 4-bit data interface.

   

I dragged and dropped a Char_LCD component to my design and compiled to generate the  LCD.h and LCD.c (the name of my component).

   

the issue I had was the inhability to print a string on either the first or second line if it was longer than 7 or 8 characters.

   

I performed several tests and analyze the code to figure out that there's a DO-WHILE in the function LCD_IsReady().

   

So far, this function waits for the bit 4 is not 0. I commented the DO and the WHILE but I let the code between the brackets uncommented.

   

Now, everything is working fine. I posted the code below if it can help anyone.

0 Likes
2 Replies
Anonymous
Not applicable

/*******************************************************************************
* Function Name: LCD_IsReady
********************************************************************************
*
* Summary:
*  Polls the LCD until the ready bit is set.
*
* Parameters:
*  None.
*
* Return:
*  None.
*
* Note:
*  Changes the pins to High-Z.
*
*******************************************************************************/
void LCD_IsReady(void)
{
    uint8 value;

    /* Clear LCD port*/
    LCD_PORT_DR_REG &= ((uint8)(~LCD_PORT_MASK));

    /* PSoC4 has a little different from PSoC3/5 port/pin organization for setting Drive Modes.
 
    */
    #if (CY_PSOC4)
       
        /* Mask off data pins to clear old values out */
        value = LCD_PORT_PC_REG & ((uint32) (~ LCD_DM_DATA_MASK));
        /* Load in high Z values for data pins, others unchanged */
        LCD_PORT_PC_REG = value | LCD_HIGH_Z_DATA_DM;

    #else
   
        /* Change Port to High-Z Status on data pins */

        /* Mask off data pins to clear old values out */
        value = LCD_PORT_DM0_REG & ((uint8)(~LCD_DATA_MASK));
        /* Load in high Z values for data pins, others unchanged */
        LCD_PORT_DM0_REG = value | (LCD_HIGH_Z_DM0 & LCD_DATA_MASK);

        /* Mask off data pins to clear old values out */
        value = LCD_PORT_DM1_REG & ((uint8)(~LCD_DATA_MASK));
        /* Load in high Z values for data pins, others unchanged */
        LCD_PORT_DM1_REG = value;

        /* Mask off data pins to clear old values out */
        value = LCD_PORT_DM2_REG & ((uint8)(~LCD_DATA_MASK));
        /* Load in high Z values for data pins, others unchanged */
        LCD_PORT_DM2_REG = value;
   
    #endif /* CY_PSOC4 */
   
    /* Make sure RS is low */
    LCD_PORT_DR_REG &= ((uint8)(~LCD_RS));

    /* Set R/W high to read */
    LCD_PORT_DR_REG |= LCD_RW;

    //do
    //{
        /* 40 ns delay required before rising Enable and 500ns between neighbour Enables */
        CyDelayUs(0u);

        /* Set E high */
        LCD_PORT_DR_REG |= LCD_E;

        /* 360 ns delay setup time for data pins */
        CyDelayUs(1u);

        /* Get port state */
        value = LCD_PORT_PS_REG;

        /* Set enable low */
        LCD_PORT_DR_REG &= ((uint8)(~LCD_E));

        /* This gives true delay between disabling Enable bit and polling Ready bit */
        CyDelayUs(0u);

        /* Extract ready bit */
        value &= LCD_READY_BIT;

        /* Set E high as we in 4-bit interface we need extra operation */
        LCD_PORT_DR_REG |= LCD_E;

        /* 360 ns delay the setup time for data pins */
        CyDelayUs(1u);

        /* Set enable low */
        LCD_PORT_DR_REG &= ((uint8)(~LCD_E));

        /* Repeat until bit 4 is not zero. */

    //} while (value != 0u);

    /* Set R/W low to write */
    LCD_PORT_DR_REG &= ((uint8)(~LCD_RW));

    /* Clear LCD port*/
    LCD_PORT_DR_REG &= ((uint8)(~LCD_PORT_MASK));

    #if (CY_PSOC4)
       
        /* Mask off data pins to clear old values out */
        value = LCD_PORT_PC_REG & ((uint32)(~ LCD_DM_DATA_MASK));
        /* Load in high Z values for data pins, others unchanged */
        LCD_PORT_PC_REG = value | LCD_STRONG_DATA_DM;

    #else

        /* Change Port to Output (Strong) on data pins */
        /* Mask off data pins to clear high z values out. Configure data pins
        * to Strong Drive, others unchanged.
        */
        LCD_PORT_DM0_REG &= ((uint8)(~LCD_DATA_MASK));
        /* Mask off data pins to clear high z values out */
        value = LCD_PORT_DM1_REG & ((uint8)(~LCD_DATA_MASK));
        /* Configure data pins to Strong Drive, others unchanged */
        LCD_PORT_DM1_REG = value | (LCD_STRONG_DM1 & LCD_DATA_MASK);

        /* Mask off data pins to clear high z values out */
        value = LCD_PORT_DM2_REG & ((uint8)(~LCD_DATA_MASK));
        /* Configure data pins to Strong Drive, others unchanged */
        LCD_PORT_DM2_REG = value | (LCD_STRONG_DM2 & LCD_DATA_MASK);
   
    #endif /* CY_PSOC4 */
}

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

You really do not need to do any pin config as the component does that

   

for you. If the controller is Hitachi/Renesas 44780 compatible it will take

   

care of all the timing and all you have to do is position the cursor and write

   

the string out. The constraint for the component is all control lines have

   

to be in one port.

   

 

   

But Kees did a component that spans multiple ports -

   

 

   

    

   

          http://www.cypress.com/?app=forum&id=0&rID=70447&start=21

   

 

   

Regards, Dana.

0 Likes