NHD-0420DZW-AY5 with scrambled display
We are using a NHD-0420DZW-AY5. The display works fine, but after a few hours/days of operation, we sometimes observe that the the display is full of strange symbols. Those symbols are not part of the listed characters in any of the ROM character tables in the datasheet. Even if we restart the software and reinitialize the LCD, we cannot recover from this condition. The only solution seems to remove and then reapply the +5V supply.
If we reinitialize the CGRAM data, it doesnt change anything either.
During our initialization sequence, we always write 10 characters and check after each of them that the auto-incremented address reported by the LCD is valid. This test passes with success during this scrambled mode. So the LCD is responding correctly to the HOST commands, but it seems that its character table is somewhat invalid.
The timing has been verified on an oscilloscope, and all signals are well within the specified ranges.
We have seen this behavior in at least three of our products, so this has not happened on a single LCD.
Any idea?
[attachment deleted by admin]
-
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 -
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 -
Would it be possible to take a look at the code you are using to initialize the LCD and write to it?
0 -
/* 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 -
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 -
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.
Comments
6 comments