This is my first time programming for a character LCD, and I am having a bit of trouble getting this 2x8 LCD to work with my PIC18f4550. I am using MPLAB v8.76 with C18 Lite compiler (for programming in C).
I will be programming the LCD in 4-bits at a time (Info about LCD below).
Here is a diagram of the connections:
The connections are as follows:
RB5 --> RS
RB4 --> R/W
RB3 --> DB7
RB2 --> DB6
RB1 --> DB5
RB0 --> DB4
VDD --> VDD
VSS --> VSS
RD7 --> E
Here is the data sheet for the LCD I am using: http://www.newhavendisplay.com/specs/NHD-0208BZ-RN-GBW.pdf
It is a 2x8 14pin (no backlight) character LCD display
The data sheet provides me with the following code layout for the initialization:
I have modified the above code to:
I have looked at a few other tutorials, but I am still left a bit confused. Even without looking at my modified code how should those functions look like when translated into code the PIC18F can work with and understand?
I understand the delay part, but I am a bit confused about the lines involving "P1 and D_I" commands. I just want to get to the point where I can at least display the letter "A" anywhere. Any help or suggestions is greatly appreciated. Thanks in advance for your time and assistance.
I will be programming the LCD in 4-bits at a time (Info about LCD below).
Here is a diagram of the connections:

The connections are as follows:
RB5 --> RS
RB4 --> R/W
RB3 --> DB7
RB2 --> DB6
RB1 --> DB5
RB0 --> DB4
VDD --> VDD
VSS --> VSS
RD7 --> E
Here is the data sheet for the LCD I am using: http://www.newhavendisplay.com/specs/NHD-0208BZ-RN-GBW.pdf
It is a 2x8 14pin (no backlight) character LCD display
The data sheet provides me with the following code layout for the initialization:
Rich (BB code):
4-bit Initialization:
/**********************************************************/
void command(char i)
{
P1 = i; //put data on output Port
D_I =0; //D/I=LOW : send instruction
R_W =0; //R/W=LOW : Write
Nybble(); //Send lower 4 bits
i = i<<4; //Shift over by 4 bits
P1 = i; //put data on output Port
Nybble(); //Send upper 4 bits
}
/**********************************************************/
void write(char i)
{
P1 = i; //put data on output Port
D_I =1; //D/I=HIGH : send data
R_W =0; //R/W=LOW : Write
Nybble(); //Clock lower 4 bits
i = i<<4; //Shift over by 4 bits
P1 = i; //put data on output Port
Nybble(); //Clock upper 4 bits
}
/**********************************************************/
void Nybble()
{
E = 1;
Delay(1); //enable pulse width >= 300ns
E = 0; //Clock enable: falling edge
}
/**********************************************************/
void init()
{
P1 = 0;
P3 = 0;
Delay(100); //Wait >15 msec after power is applied
P1 = 0x30; //put 0x30 on the output port
Delay(30); //must wait 5ms, busy flag not available
Nybble(); //command 0x30 = Wake up
Delay(10); //must wait 160us, busy flag not available
Nybble(); //command 0x30 = Wake up #2
Delay(10); //must wait 160us, busy flag not available
Nybble(); //command 0x30 = Wake up #3
Delay(10); //can check busy flag now instead of delay
P1= 0x20; //put 0x20 on the output port
Nybble(); //Function set: 4-bit interface
command(0x28); //Function set: 4-bit/2-line
command(0x10); //Set cursor
command(0x0F); //Display ON; Blinking cursor
command(0x06); //Entry Mode set
}
/**********************************************************/
Rich (BB code):
//turns watch dog timer off, turn low voltage programming off
#pragma config WDT=OFF, LVP=OFF, DEBUG=ON
//Internal oscillator, port function on RA6, EC used by USB
#pragma config FOSC = INTOSCIO_EC
#include <p18f4550.h>
#include <delays.h>
//LCD (Port B and 1 pin PortD)
#define RS LATBbits.LATB5 //Define LCD pinout RS
#define R_W LATBbits.LATB4 //Define LCD pinout R/W
#define DB7 LATBbits.LATB3 //Define LCD pinout DB7
#define DB6 LATBbits.LATB2 //Define LCD pinout DB6
#define DB5 LATBbits.LATB1 //Define LCD pinout DB5
#define DB4 LATBbits.LATB0 //Define LCD pinout DB4
#define E LATDbits.LATD7 //Define LCD pinout E
void command(char);
void write(char);
void Nybble(void);
void init(void);
void main()
{
while(!OSCCONbits.IOFS); //wait for osc stable
ADCON1 = 0x0F; //make RA0 digital
//data direction register all 0's mean all pins are set to output
//all 1's mean all pins are set to operate as inputs
TRISB = 0x00;
//main program loop
while(1)
{
init();
//after initialization call function for outputting character to LCD with appropriate command
}
}
/**********************************************************/
//4-bit methods for LCD
/**********************************************************/
void command(char i)
{
// P1 = i; //put data on output Port
// D_I =0; //D/I=LOW : send instruction
//send lower bits of char (masking bits)
DB7 = i&08;
DB6 = i&04;
DB5 = i&02;
DB4 = i&01;
R_W =0; //R/W=LOW : Write
Nybble(); //Send lower 4 bits
i = i<<4; //Shift over by 4 bits
//since sifted sending upper bits of char
DB7 = i&08;
DB6 = i&04;
DB5 = i&02;
DB4 = i&01;
Nybble(); //Send upper 4 bits
}
void write(char i)
{
//P1 = i; //put data on output Port
//D_I =1; //D/I=HIGH : send data
DB7 = i&08;
DB6 = i&04;
DB5 = i&02;
DB4 = i&01;
R_W =0; //R/W=LOW : Write
Nybble(); //Clock lower 4 bits
i = i<<4; //Shift over by 4 bits
// P1 = i; //put data on output Port
DB7 = i&08;
DB6 = i&04;
DB5 = i&02;
DB4 = i&01;
Nybble(); //Clock upper 4 bits
}
/**********************************************************/
void Nybble(void)
{
E = 1;
Delay1TCY(); //enable pulse width >= 300ns (used 4uS)
E = 0; //Clock enable: falling edge
}
/**********************************************************/
void init(void)
{
//P1 = 0;
//P3 = 0;
DB7 = 0;
DB6 = 0;
DB5 = 0;
DB4 = 0;
Delay1KTCYx(5); //Wait >15 msec after power is applied (used 20mS)
//P1 = 0x30; //put 0x30 on the output port
DB7 = 0;
DB6 = 0;
DB5 = 1;
DB4 = 1;
Delay1KTCYx(1.25); //must wait 5ms, busy flag not available (used 5ms)
Nybble(); //command 0x30 = Wake up
Delay10TCYx(5); //must wait 160us, busy flag not available (used 160uS)
Nybble(); //command 0x30 = Wake up #2
Delay10TCYx(5); //must wait 160us, busy flag not available (used 160uS)
Nybble(); //command 0x30 = Wake up #3
Delay10TCYx(5); //can check busy flag now instead of delay
//P1= 0x20; //put 0x20 on the output port
DB7 = 0;
DB6 = 0;
DB5 = 1;
DB4 = 0;
Nybble(); //Function set: 4-bit interface
command(0x28); //Function set: 4-bit/2-line
command(0x10); //Set cursor
command(0x0F); //Display ON; Blinking cursor
command(0x06); //Entry Mode set
}
/**********************************************************/
//End methods for LCD
/**********************************************************/
I understand the delay part, but I am a bit confused about the lines involving "P1 and D_I" commands. I just want to get to the point where I can at least display the letter "A" anywhere. Any help or suggestions is greatly appreciated. Thanks in advance for your time and assistance.
Last edited: