- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Labels:
-
PSoC 3
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
/*******************************************************************************
* 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 */
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.