Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

HELP: Interfacing LCD with PIC18f4520 (MpLab C18 Compiler)

Status
Not open for further replies.

Ayie29

New Member
Currently doing for my final year project and want to test my lcd qy1602a with simple program. I had construct the circuit and coding like in this thread: https://www.electro-tech-online.com/threads/pic-18f4550-2x8-lcd-character-display-assistance.122251/

It cant work in proteus and my hardware. I using pickit2 as my programmer. isnt any setting that i miss out?

I had change abit in the coding as i want to use external oscillator.

Code:
[CODE]//turns watch dog timer off, turn low voltage programming off
#pragma config WDT=OFF, LVP=OFF, DEBUG=ON, MCLRE = OFF

#pragma config OSC=HS
 
#include <p18f4520.h>
#include <delays.h>

#define _XTAL_FREQ 10000000
 
//LCD (PortD)
#define  E            LATDbits.LATD6
#define  R_W       LATDbits.LATD5 
#define  RS          LATDbits.LATD4
#define  LCDdata LATD
 
void command(unsigned char);
void write(unsigned char);
void Nybble(unsigned char);
void init(void);
void PutMessage(rom char *);
 
void main()
{
	while(!OSCCONbits.IOFS);      //wait for osc stable
   	ADCON1 = 0x0F;                //make RA0 digital
 
    //data direction registers all 0's mean that all pins are set to output
	//all 1's means that all of the pins are set to operate as inputs
	TRISA = 0x00;  
	TRISB = 0x00; 
	TRISD = 0x00;
        init();
        PutMessage("Hello World!");
        command(0xc0);
        PutMessage("WELCOME");
        while(1);
}
 
//Write a string to the LCD
void PutMessage(rom char *Message)
{
	rom char *Pos = Message;
	while(*Pos!=0)
	    write(*Pos++);
}
 
/**********************************************************/
//4-bit methods for LCD
/**********************************************************/
void command(unsigned char i)
{
	RS =0;
	R_W =0;          //R/W=LOW : Write
	Nybble(i>>4);    //Send upper 4 bits
	Nybble(i);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait at least 2mS (2*1000*4/1e6 = 8ms used)
}
 
void write(unsigned char i)
{
	RS =1;
	R_W =0;          //R/W=LOW : Write
	Nybble(i>>4);    //Send upper 4 bits
	Nybble(i);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait 2mS
}
 
/**********************************************************/
void Nybble(unsigned char dat)
{
    dat &= 0x0f;             //clear top bits of dat
    LCDdata &= 0xf0;         //clear bottom bits of port (interested only in DB7-DB4)
    LCDdata |= dat;          //or the two and store at port
    E = 1;
    Delay1TCY();             //enable pulse width >= 300ns (used 4uS)
    E = 0;                   //Clock enable: falling edge
}
 
/**********************************************************/
void init(void)
{
    LCDdata=0x00; 
    Delay1KTCYx(15);    //Wait >15 msec after power is applied (used 20mS)
    Nybble(0x3); 	//command 0x30 = Wake up
    Delay1KTCYx(5);     //must wait 160us, busy flag not available (used 160uS)
    Nybble(0x3); 	//command 0x30 = Wake up #2
    Delay1KTCYx(5); 	//must wait 160us, busy flag not available (used 160uS) 
 
    command(0x20);      //Function set: 4-bit/2-line
    command(0x2c);      //Function set: 4-bit/2-line
    command(0x10);      //Set cursor
    command(0x01);      //Clear Display (Added)
    command(0x06);      //Entry Mode set
    command(0x0c);
}
/**********************************************************/
//End methods for LCD
/**********************************************************/
[/CODE]

View attachment 62167
 
Last edited:
Just remove this line

Code:
while(!OSCCONbits.IOFS);      //wait for osc stable

There is also a small problem with the "rom char* ... rename it to "const rom char*"

Once that is out of the way you'll need to work on your delays.... they are all too small... There's an issue initialising the LCD...

Sorry for being vague... I would show you, but I'll have to finish work first..
 
It's ok. I'm new to all these. thanks for your patience in teaching me. the delays how to change? my proteus still din show anything.
 
Last edited:
Ok I'm at home now... I'll shove it on Proteus and see what happens.

Code:
void init(void)
{
    LCDdata=0x00; 
    Delay1KTCYx(40);    //Wait >15 msec after power is applied (used 20mS)
    Nybble(0x3); 	//command 0x30 = Wake up
    Delay1KTCYx(15);     //must wait 160us, busy flag not available (used 160uS)
    Nybble(0x2); 	//command 0x30 = Wake up #2
    Delay1KTCYx(15); 	//must wait 160us, busy flag not available (used 160uS) 

    command(0x2C);      //Function set: 4-bit/2-line
    command(0xC);      //Set cursor
    command(0x06);      //Entry Mode set
    command(0x01);
}

Use this to initialize the LCD (remember to change the other issues I mentioned)
 
Last edited:
Thanks Ian. My proteus finally work on these code! Now gonna proceed to hardware for real try. If work at proteus, isnt mean that work on hardware also?

My final coding:
Code:
//turns watch dog timer off, turn low voltage programming off
#pragma config WDT=OFF, LVP=OFF, DEBUG=ON, MCLRE = OFF
 
#pragma config OSC=HS
#define _XTAL_FREQ 20000000

#include <p18f4520.h>
#include <delays.h>
 

//LCD (PortD)
#define  E LATDbits.LATD6
#define  R_W LATDbits.LATD5 
#define  RS  LATDbits.LATD4
#define LCDdata LATD
 
 
void command(unsigned char);
void write(unsigned char);
void Nybble(unsigned char);
void init(void);
void PutMessage(const rom char *);
 
void main()
{   
   	ADCON1 = 0x0F;                //make RA0 digital
 
       //data direction registers all 0's mean that all pins are set to output
	//all 1's means that all of the pins are set to operate as inputs
	TRISA = 0x00;  
	TRISB = 0x00; 
	TRISD = 0x00;
        init();
        PutMessage(" Hello World!");
        command(0xc0);
        PutMessage(" WELCOME");
        while(1);
}
 
//Write a string to the LCD
void PutMessage(const rom char *Message)
{
const rom char *Pos = Message;
	while(*Pos!=0)
	    write(*Pos++);
}
 
/**********************************************************/
//4-bit methods for LCD
/**********************************************************/
void command(unsigned char i)
{
	RS =0;
	R_W =0;          //R/W=LOW : Write
	Nybble(i>>4);    //Send upper 4 bits
	Nybble(i);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait at least 2mS (2*1000*4/1e6 = 8ms used)
}
 
void write(unsigned char i)
{
	RS =1;
	R_W =0;          //R/W=LOW : Write
	Nybble(i>>4);    //Send upper 4 bits
	Nybble(i);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait 2mS
}
 
/**********************************************************/
void Nybble(unsigned char dat)
{
    dat &= 0x0f;             //clear top bits of dat
    LCDdata &= 0xf0;         //clear bottom bits of port (interested only in DB7-DB4)
    LCDdata |= dat;          //or the two and store at port
    E = 1;
    Delay1TCY();             //enable pulse width >= 300ns (used 4uS)
    E = 0;                   //Clock enable: falling edge
}
 
/**********************************************************/

void init(void)
{
    LCDdata=0x00; 
    Delay1KTCYx(40);    //Wait >15 msec after power is applied (used 20mS)
    Nybble(0x3); 	//command 0x30 = Wake up
    Delay1KTCYx(15);     //must wait 160us, busy flag not available (used 160uS)
    Nybble(0x2); 	//command 0x30 = Wake up #2
    Delay1KTCYx(15); 	//must wait 160us, busy flag not available (used 160uS) 
 
    command(0x2C);      //Function set: 4-bit/2-line
    command(0xC);      //Set cursor
    command(0x06);      //Entry Mode set
    command(0x01);
}
/**********************************************************/
//End methods for LCD
/**********************************************************/

View attachment 62213
 
Last edited:
There are two ways.... Firstly, have you included the LCD routines <XLCD.H>?

If you want to output an integer you need to convert it to ascii first. Then you either write your own output function, or you use printf() or sprintf().

I use sprintf() as its easier for me... If you use printf() you need to specify....

Code:
stdout = _H_USER
at the beginning of your code. Then write a function
Code:
void _user_putc(unsigned char ch)
   {
   WriteDataXLCD(ch);
   }
 
hi

i am using pic18f4620 and using c18
i having problem initialize the lcd
the lcd only shows blackscreen

attached is the lcd datasheet
 
Last edited:
my apologies
i did not mention i copy Ayie29 codes
my output port also the same as Ayie29

only the micro controller is different


Code:
//turns watch dog timer off, turn low voltage programming off
#pragma config WDT=OFF, LVP=OFF, DEBUG=ON, MCLRE = OFF
 
#pragma config OSC=HS
 
#include <p18f4620.h>
#include <delays.h>
 
 
//LCD (PortD)
#define  E LATDbits.LATD6
#define  R_W LATDbits.LATD5 
#define  RS  LATDbits.LATD4
#define LCDdata LATD
 
 
void command(unsigned char);
void write(unsigned char);
void Nybble(unsigned char);
void init(void);
void PutMessage(const rom char *);
 
void main()
{   
   	ADCON1 = 0x0F;                //make RA0 digital
 
       //data direction registers all 0's mean that all pins are set to output
	//all 1's means that all of the pins are set to operate as inputs
	TRISA = 0x00;  
	TRISB = 0x00; 
	TRISD = 0x00;
        init();
        PutMessage(" Hello World!");
        command(0xc0);
        PutMessage(" WELCOME");
        while(1);
}
 
//Write a string to the LCD
void PutMessage(const rom char *Message)
{
const rom char *Pos = Message;
	while(*Pos!=0)
	    write(*Pos++);
}
 
/**********************************************************/
//4-bit methods for LCD
/**********************************************************/
void command(unsigned char i)
{
	RS =0;
	R_W =0;          //R/W=LOW : Write
	Nybble(i>>4);    //Send upper 4 bits
	Nybble(i);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait at least 2mS (2*1000*4/1e6 = 8ms used)
}
 
void write(unsigned char i)
{
	RS =1;
	R_W =0;          //R/W=LOW : Write
	Nybble(i>>4);    //Send upper 4 bits
	Nybble(i);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait 2mS
}
 
/**********************************************************/
void Nybble(unsigned char dat)
{
    dat &= 0x0f;             //clear top bits of dat
    LCDdata &= 0xf0;         //clear bottom bits of port (interested only in DB7-DB4)
    LCDdata |= dat;          //or the two and store at port
    E = 1;
    Delay1TCY();             //enable pulse width >= 300ns (used 4uS)
    E = 0;                   //Clock enable: falling edge
}
 
/**********************************************************/
 
void init(void)
{
    LCDdata=0x00; 
    Delay1KTCYx(40);    //Wait >15 msec after power is applied (used 20mS)
    Nybble(0x3); 	//command 0x30 = Wake up
    Delay1KTCYx(15);     //must wait 160us, busy flag not available (used 160uS)
    Nybble(0x2); 	//command 0x30 = Wake up #2
    Delay1KTCYx(15); 	//must wait 160us, busy flag not available (used 160uS) 
 
    command(0x2C);      //Function set: 4-bit/2-line
    command(0xC);      //Set cursor
    command(0x06);      //Entry Mode set
    command(0x01);
}
/**********************************************************/
//End methods for LCD
/**********************************************************/
 
i connected the vss to mirco ground
it succeeded to show the hello world
but when i reset it, the words are blurred
after a few tries, it is blank
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top