LCD Initialization issue | Display Hello World on LCD

Thread Starter

kumquat_9

Joined Jun 14, 2025
7
Description:
------------
A C program for 8052 microcontroller to display Hello World message on a LCD.
LCD is a 2x16 character type.

Hello must be on the first line.
World on the second line.
Clear the screen after 10 seconds and repeat.

The microcontroller used is Nuvoton W78E052DDG.
It works at 11.0592 frequency.

1602A 2x16 LCD

The datasheets of microcontroller and LCD are included in the zip file.

Challenges:
-----------
During LCD initialization, I want to do the following:
1. Clear the display
2. Turn on the display
3. Turn on the cursor
4. Blink the cursor
5. Cursor position must be on the first line at the first character
6. Set the LCD in 8-bit mode.

I ran the code on Proteus.
The backlight turned on but nothing happened on the screen.
It's blank.
There is no cursor.

I have gone through the LCD datasheet but I'm having hard time converting the instructions into code.

Am I doing the initialization correct?

I want to observe and control the behavior the LCD using the instructions.
I believe that's essential.

The second challenge I'm facing is when writing commands and data.
Especially at lcdDataPort. The command/data is loaded into lcdDataPort.
I want to pass the data/command to LCD.
I enable EN, call delay function, and disable EN.

I don't know exactly what's happening here.

What do I want?
---------------
1. I would be grateful if you help me figure out the challenges.
2. Am I following best practices?
3. How should I structure a project for a embedded system?

Constructive criticism is welcomed.
 

Attachments

MrChips

Joined Oct 2, 2009
34,714
Welcome to AAC!

We don't open .zip files. Please post the text code directly into the post using code tags as follows:

[code=C]your code ... [/code]
 

Thread Starter

kumquat_9

Joined Jun 14, 2025
7
Welcome to AAC!

We don't open .zip files. Please post the text code directly into the post using code tags as follows:

[code=C]your code ... [/code]
Hi, MrChips!

Sure! Here's my code.

Delay.h:
void delayMilliSeconds(const unsigned char msec);
Delay.c:
#ifndef DELAY_H
#define DELAY_H

#include "Delay.h"

#endif

void delayMilliSeconds(const unsigned char msec)
{
    unsigned char i = 0;
    unsigned char j = 0;
    
    for(i=0; i<msec; i++)
    for(j=0; j<120; j++);
}
LCD.h:
void lcdInit(void);
void lcdWriteCommand(const unsigned char command);
void lcdWriteByte(const unsigned char dataToWrite);
LCD.c:
#ifndef LCD_H
#define LCD_H

#include "Delay.h"
#include "LCD.h"
#include<reg52.h>

#endif

sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;

sfr lcdDataPort = 0xB0; // PORT3

void lcdInit(void)
{
    delayMilliSeconds(100);
    lcdDataPort = 0x30;
    delayMilliSeconds(10);
    lcdWriteCommand(0x38);
    lcdWriteCommand(0x08);
    lcdWriteCommand(0x01);
    lcdWriteCommand(0x08);
}

void lcdWriteCommand(const unsigned char command)
{
    delayMilliSeconds(100);
    RS = 0;
    RW = 0;
    
    lcdDataPort = command;
    EN = 1;
    delayMilliSeconds(3);
    EN = 0;
}

void lcdWriteByte(const unsigned char dataToWrite)
{
    delayMilliSeconds(100);
    RS = 1;
    RW = 0;
    
    lcdDataPort = dataToWrite;
    EN = 1;
    delayMilliSeconds(3);
    EN = 0;
}
main.c:
#ifndef MAIN_H
#define MAIN_H

#include "Delay.h"
#include "LCD.h"
#include<reg52.h>

#endif

void main(void)
{
    const unsigned char message_1[] = "Hello";
    const unsigned char message_2[] = "World";
        
    unsigned char i = 0;
    
    lcdInit();
    
    while(1)
    {
        lcdWriteCommand(0x80);
        for(i=0; i<5; i++)
            lcdWriteByte(message_1[i]);
        
        lcdWriteCommand(0xC0);
        
        for(i=0; i<5; i++)
            lcdWriteByte(message_2[i]);
        
        delayMilliSeconds(10000);
        lcdWriteCommand(0x01);
    }
}
 

MrChips

Joined Oct 2, 2009
34,714
When attempting to get code working, start off with the simplest program in order to isolate the problem.
Here is an example in 3 steps:

1. Initialize the hardware.
2. Initialize the LCD.
3. Write a single character to the screen, for example, the letter A.
 

Thread Starter

kumquat_9

Joined Jun 14, 2025
7
When attempting to get code working, start off with the simplest program in order to isolate the problem.
Here is an example in 3 steps:

1. Initialize the hardware.
2. Initialize the LCD.
3. Write a single character to the screen, for example, the letter A.
Thanks for the reply, MrChips.

My problem is with initializing the LCD.
I'm not sure where am I doing wrong.

I want to know what goes into LCD initialization.
Would you happen to know the steps for initialization?
 

MrChips

Joined Oct 2, 2009
34,714
I would never think of testing an LCD on a simulator. I would always do this with real hardware.

Step 1. Initialize the hardware.
Did you initialize the hardware?
Can you test that the hardware is properly configured to generate R/W, RS, E, and DATA?

Step 2. Initialize the LCD.
Every LCD uses an LCD controller chip. You need to read the datasheet of the controller to determine what initialization steps are required.

How is the LCD interfaced to the MCU?
Is it UART, SPI, I2C, 4-bit parallel interface, 8-bit parallel interface?

The most common failure with real LCD initialization is that there is nothing visible on the screen, not even black rectangles on line 1. The immediate remedy is to adjust the contrast setting of the LCD until you see black rectangles.

Obviously, one cannot do this with a simulator.

Here are my LCD initialization steps with the Hitachi HD44780 LCD controller.

C:
void LCD_init(void)
{
  LCD_ir(0x28);         // dual line, 4 bits
  LCD_ir(0x06);         // increment mode
  LCD_ir(0x0C);         // cursor turned off
  LCD_ir(0x10);         // cursor right
  LCD_ir(0x01);         // clear display
}
 

Thread Starter

kumquat_9

Joined Jun 14, 2025
7
I would never think of testing an LCD on a simulator. I would always do this with real hardware.

Step 1. Initialize the hardware.
Did you initialize the hardware?
Can you test that the hardware is properly configured to generate R/W, RS, E, and DATA?

Step 2. Initialize the LCD.
Every LCD uses an LCD controller chip. You need to read the datasheet of the controller to determine what initialization steps are required.

How is the LCD interfaced to the MCU?
Is it UART, SPI, I2C, 4-bit parallel interface, 8-bit parallel interface?

The most common failure with real LCD initialization is that there is nothing visible on the screen, not even black rectangles on line 1. The immediate remedy is to adjust the contrast setting of the LCD until you see black rectangles.

Obviously, one cannot do this with a simulator.

Here are my LCD initialization steps with the Hitachi HD44780 LCD controller.

C:
void LCD_init(void)
{
  LCD_ir(0x28);         // dual line, 4 bits
  LCD_ir(0x06);         // increment mode
  LCD_ir(0x0C);         // cursor turned off
  LCD_ir(0x10);         // cursor right
  LCD_ir(0x01);         // clear display
}
Thanks for the pointers.
LCD is interfaced to MCU through 8-bit parallel interface.
I'm facing the common issues you've mentioned.

What do you use to test the hardware configuration is correct? An oscilloscope?
I've never done this before. I'm kind of feeling lost.
Hope you don't mind me asking obvious questions.
 

MrChips

Joined Oct 2, 2009
34,714
Are you testing with simulator or real hardware?
If you have real hardware, do you have access to an oscilloscope?
What IDE (integrated development environment) software package are you using?
 

Thread Starter

kumquat_9

Joined Jun 14, 2025
7
Are you testing with simulator or real hardware?
If you have real hardware, do you have access to an oscilloscope?
What IDE (integrated development environment) software package are you using?
I have access to real hardware. It's 8051 development board.
I could try to get access to an oscilloscope as well.
IDE is Keil uVision.
 

MrChips

Joined Oct 2, 2009
34,714
I have access to real hardware. It's 8051 development board.
I could try to get access to an oscilloscope as well.
IDE is Keil uVision.
Having an oscilloscope is ideal.
Otherwise, in the meantime you can do some simple tests with an LED.
Please post a photo or a link to the development board.

Choose a GPIO pin and write a short program to make an LED flash at about 1 Hz. The frequency is not critical as long as we can see it flash.
 

Irving

Joined Jan 30, 2016
5,070
Welcome to AAC

Is this homework or school project?

I agree with MrChips, its much easier on real hardware with a 'scope, however without a scope a voltmeter or even an LED and resistor will serve to check logic levels.

I'm not sure you are enabling the ports correctly. In the simulator, write a simple routine to wiggle EN, RS, RW in sequence and check with the 'scope tools to view the correct hardware signalling.
 

Thread Starter

kumquat_9

Joined Jun 14, 2025
7
Having an oscilloscope is ideal.
Otherwise, in the meantime you can do some simple tests with an LED.
Please post a photo or a link to the development board.

Choose a GPIO pin and write a short program to make an LED flash at about 1 Hz. The frequency is not critical as long as we can see it flash.
This is the link to the development board: https://nskelectronics.in/8051 DEVELOPMENT BOARD?search=8051

I will have access to lab tomorrow.
Will check it then.

Also, I'll write short program to flash a LED.

Thank you for the support, MrChips.
 

Thread Starter

kumquat_9

Joined Jun 14, 2025
7
Welcome to AAC

Is this homework or school project?

I agree with MrChips, its much easier on real hardware with a 'scope, however without a scope a voltmeter or even an LED and resistor will serve to check logic levels.

I'm not sure you are enabling the ports correctly. In the simulator, write a simple routine to wiggle EN, RS, RW in sequence and check with the 'scope tools to view the correct hardware signalling.
Hi, Irving.

Thanks for welcoming me.

It's neither homework nor school project.
I'm learning embedded programming.

I thought I could just dump the code on a simulator and get done with it. Hahaha.
Point noted.

Which simulator do you recommend?
I have Proteus.
 

Irving

Joined Jan 30, 2016
5,070
Sadly Proteus isn't free so can't help you there. Why the 8051? Did you just happen to have the dev board?

As suggested by MrChips, start with something simple to verify hardware. The classic Blink program is a good way to verify hardware and IDE are in step and all is well. Apologies if you've already done this but we've no way to assess knowledge level at this stage.

Your dev board probably has an on-board user accessible LED.

Something like:
Code:
void delayMilliSeconds(const unsigned char msec)
{
    unsigned char i = 0;
    unsigned char j = 0;
    
    for(i=0; i<msec; i++)
    for(j=0; j<120; j++);
}

sbit LED Px^n ; //where x and n are port # and bit # for on-board LED

void main(void)
{
  while(true){  // forever
   LED = 0;  //LED off
   delayMilliSeconds(1000);
   LED = 1; // LED on
   delayMilliSeconds(1000);
  }
}
When that is working you extend the idea to the required pins EN/RW/RS

I note your board comes with test programs for LED and LCD. Have you tried them?
 

MrChips

Joined Oct 2, 2009
34,714
I would skip the simulation and go straight to the hardware development kit.
Find an LED on the board that is available and write the program to flash the LED.
Even if there are already examples given, see if you can figure this out on your own. That is the best way to learn this stuff.

Here is what you need to know.

Which GPIO port is connected to the selected LED?
How to configure the port as output?
How to modify a single bit versus all 8 bits of a port?

While
sbit LED Px^n ;
might do the job, it is not intuitive to me. I don't think sbit is native C code, at least not to me.
 
Top