Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

problem with controlling LCD 16x2 with PIC 16f877

Status
Not open for further replies.

wanbong

Newbie level 5
Joined
Sep 23, 2008
Messages
10
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,350
pic16f877 lcd

hi guys, I'm just an newbie with PIC
I'm trying to control the LCD 16x2 (model SC1602-B) with a PIC 16f877

The simulation of my code on the Proteus 7 can run but when I work with real thing it couldn't print out anything

please help me out, below is my code

/*

* PORTB bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
* PORTA bit 2 is connected to the LCD RS input (register select)
* PORTA bit 3 is connected to the LCD EN bit (enable)
*
* To use these routines, set up the port I/O (TRISA, TRISB) then
* call lcd_init(), then other routines as required.
*
*/

//Define compiler error message.
#ifndef __CPU_16F877__
#error "This program is tailored for PIC16F877 controller"
#endif

//Include required header files here.
#include "io16f877.h" //the hardware register definition file.
//-----------------------------------------------------------------delay---------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------
void DelayUs(int count)
{
int i;
int j;
for(i=0;i<count;i++)
{
for(j=0;j<5;j++);
//This for loop has 5 NOPs & wastes 1 uS for our PIC clock frequency of 20MHz.
}
}

void DelayMs(int count)
{
int i;
for(i=0;i<count;i++)
{DelayUs(4000);}
}
//---------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------

#define LCD_RS RA2 // Register select
#define LCD_EN RA3 // Enable

#define LCD_STROBE ((LCD_EN = 1),(LCD_EN=0))


/* write a byte to the LCD in 4 bit mode */

void
lcd_write(unsigned char c)
{
PORTB = (PORTB & 0xF0) | (c >> 4);
LCD_STROBE;
PORTB = (PORTB & 0xF0) | (c & 0x0F);
LCD_STROBE;
DelayUs(40);
}

/*
* Clear and home the LCD
*/

void
lcd_clear(void)
{
LCD_RS = 0;
lcd_write(0x1);
DelayMs(2);
}

/* write a string of chars to the LCD */

void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}

/* write one character to the LCD */

void
lcd_putch(char c)
{
LCD_RS = 1; // write characters
PORTB = (PORTB & 0xF0) | (c >> 4);
LCD_STROBE;
PORTB = (PORTB & 0xF0) | (c & 0x0F);
LCD_STROBE;
DelayUs(40);
}


/*
* Go to the specified position
*/

void
lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write(0x80+pos);
}

/* initialise the LCD - put into 4 bit mode */

void
lcd_init(void)
{
LCD_RS = 0; // write control bytes
DelayMs(15); // power on delay
PORTB = 0x3; // attention!
LCD_STROBE;
DelayMs(5);
LCD_STROBE;
DelayUs(100);
LCD_STROBE;
DelayMs(5);
PORTB = 0x2; // set 4 bit mode
LCD_STROBE;
DelayUs(40);
lcd_write(0x28); // 4 bit mode, 1/16 duty, 5x8 font
lcd_write(0x08); // display off
lcd_write(0x0F); // display on, blink curson on
lcd_write(0x06); // entry mode
}
void IniPort()
{
ADCON1=0x06;
TRISA=0x00;
TRISB=0x00;
PORTA=0x00;
PORTB=0x00;


}

char text[]="len di\n";
int count=0;
void main(void)
{
IniPort();
lcd_init();
while (text[count]!='\n')
{
lcd_putch(text[count]);
count++;
}
DelayUs(100);
while(1){}
}

Added after 5 hours 48 minutes:

after I ground all the unused pins, there is array of blocks appear in the second line :( the LCD still can not print out anything
 

io16f877.h

Hi, I think you have problem with pin connection,
for example, I have two tipe of 1602-b LCD,
look on attached pictures,
regards
 
pic lcd 16x2

here is my pins connection
1 GND
2 Vdd
3 GND
4 RA2
5 GND
6 RA3
7->10 GND
11->14 RB0->RB3
15 5V
16 GND
 

connection between pic16f877 with 16x2 lcd

You need an adjustable contrast, put a 10K pot between power, gnd and pin 3 (pin 3 should not be ground but often just slightly above. it can even be negative on some old LCDs) check the datasheet.
 

pic lcd problem

Hi,

1. In lcdinit, change
PORTB = 0x3; // attention
to 0x2 .

2. lcd RAM address is not inited in lcdinit ( By command 0x01 , for CLR display) nor called in the Main function.

3. R/W- pin to be grounded

Regards,
Laktronics
 

lcd 16x2 4bit

thanks for all ur reply :D finally my LCD can work
the prob is that I connected RS pin wrongly :D
the point that blueroomelectronics is also correct. If we don't put a potentionmeter for changing the contrast sometimes we can not see the displayed character
 
lcd (16x2 @ 4 bit) c programming

I'm working on something similar, but I'm having trouble getting my LCD (Sanyo DM1622, datasheet at http://www.datasheetcatalog.com/datasheets_pdf/D/M/1/6/DM1622.shtml) to display anything besides 2 rows of 16 squares. Mainly I think it's the initialisation process that's tripping me up.

Pin setup is as follows:
1 GND
2 +5V
3 -5V
4 RA2
5 GND
6 RA3
7->10 GND
11->14 RB0->RB3
15 5V
16 GND

I don't understand some parts of the OP's code.
void IniPort()
{
ADCON1=0x06;
TRISA=0x00;
TRISB=0x00;
PORTA=0x00;
PORTB=0x00;


}

lcd_init(void)
{
LCD_RS = 0; // write control bytes
Why do you need to set LCD_RS = 0 in lcd_init again? When you set PORTA=0x00 in IniPort, isn't LCD_RS already set to 0?

void
lcd_init(void)
{
LCD_RS = 0; // write control bytes
DelayMs(15); // power on delay
PORTB = 0x2; // attention! Was originally 0x3, but laktronics suggested changing it to 0x2. Why?
LCD_STROBE; Step 1
DelayMs(5);
LCD_STROBE; Step 2
DelayUs(100);
LCD_STROBE; Step 3
DelayMs(5);
PORTB = 0x2; // set 4 bit mode
LCD_STROBE; Step 4
DelayUs(40);
lcd_write(0x28); // 4 bit mode, 1/16 duty, 5x8 font
lcd_write(0x08); // display off
lcd_write(0x0F); // display on, blink curson on
lcd_write(0x06); // entry mode
}
Right now I'm interpreting the lcd_init function as doing the following.

Step 1:
DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 1 0 ? ? ? ?
Nothing happens yet, only first 4 bits written

Step 2:
DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 1 0 0 0 1 0
The LCD is given the command to do a function set of 4 bits, 1 line, 5*7 dots.

Step 3
DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 1 0 ? ? ? ?
Nothing happens yet, only first 4 bits written

Step 4
DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 1 0 0 0 1 0
The LCD is given the command to do a function set of 4 bits, 1 line, 5*7 dots.



From the information I get from this page http://www.8051projects.net/lcd-interfacing/lcd-4-bit-programming.php
the initialisation for 4-bit mode for a similar LCD is as follows
void lcd_reset()
{
lcd_port = 0xFF;
delayms(20);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(10);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(1);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(1);
lcd_port = 0x02+LCD_EN;
lcd_port = 0x02;
delayms(1);
}
How do you have
lcd_port = 0xFF;
when you're only using 4 bits?
lcd.png
 

Re: lcd (16x2 @ 4 bit) c programming

I am also facing the same problem
 

Re: lcd (16x2 @ 4 bit) c programming

I am also facing the same problem

Why are you digging out a year old problem and saying "same problem".

Instead you can start a new thread explaining your problem.
 

Can someone tell me what was wrong in wanbong's coding and what was changed? I would like a full correct coding of it if possible. Thanks.
 

CSS C compiler has the built in function of controlling LCD.
16x2 LCD interfacing with PIC-16f877a is available.
To get this and to get complete help regarding this feel free to contact on asharwahid@yahoo.com
 

Attachments

  • lcd.jpg
    lcd.jpg
    88.6 KB · Views: 122

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top