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.

Interfacing Hitachi HD44780 2x16 LCD with PIC 16F877

Status
Not open for further replies.

bjerkely

Member level 4
Member level 4
Joined
May 26, 2004
Messages
72
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,286
Location
Turkiye
Activity points
589
hd44780 pic

I'm using Hi-tech PicC-lite compiler,it comes with some sample C codes.The routines in LCD.c work quite fine for 16F84 but when I change to 16F877 with the same pin connections nothing promts on LCD. The code is below....

Thanx in advance...
/*
* LCD interface header file
* See lcd.c for more info
*/

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

extern void lcd_write(unsigned char);

/* Clear and home the LCD */

extern void lcd_clear(void);

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

extern void lcd_puts(const char * s);

/* Go to the specified position */

extern void lcd_goto(unsigned char pos);

/* intialize the LCD - call before anything else */

extern void lcd_init(void);

extern void lcd_putch(char);

/* Set the cursor position */

#define lcd_cursor(x) lcd_write(((x)&0x7F)|0x80)


LCD.C
/*
* LCD interface example
* Uses routines from delay.c
* This code will interface to a standard LCD controller
* like the Hitachi HD44780. It uses it in 4 bit mode, with
* the hardware connected as follows (the standard 14 pin
* LCD connector is used):
*
* 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.
*
*/

#include <pic.h>
#include "lcd.h"
#include "delay.h"

static bit LCD_RS @ ((unsigned)&PORTA*8+2); // Register select
static bit LCD_EN @ ((unsigned)&PORTA*8+3); // 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
}
 

hitachi hd44780

On the 16F877 PORTA is switched to analog input on reset.

If you want to use it as digital I/O you must put this into your init routine:
ADCON1=6;

Check the datasheet ...

hope this helps and best regards
 

    bjerkely

    Points: 2
    Helpful Answer Positive Rating
hd44780 2x16

Hi,

I need C routine in 8bit mode....for 16f84!! Any help...

Thanks
 

16f877 lcd

Hi all.
I try to make volt meter with ht-picc on lcd.I solve my problem with lcd but i cant use adc in 10 bit. can you help me.
Here is my project with some change.
 

pic hd44780

C-Man wrote:
If you want to use it as digital I/O you must put this into your init routine:
ADCON1=6;

I set the ADCON1 register to 6 but it's no good,nothing promts again...
May anyone give me a link to assembly LCD routines...
Regards
 

lcd 2x16 hitachi

Are you sure the mico is working correctly?

What are your fuse settings?

Which type of oscillator are you using?

Have you tried to get a simle flashing led programm going?

best regards
 

hitachi hd44780 lcd

Hi all.
I make 8-ch voltmeter with ht-picc.it works good in proteuse But have some error in real.it works with 4meg xtal and when i change it to 24 meg even lcd doesn't work.
can you help me to change the xtal.
Thanks
 

hitachi hd44780 lcd controller

I had the same problem,try to change the crystal type in your configuration register
like that __config _HS_OSC & _WDT_OFF & _PWRTE_ON

This helped me...
 

16f877 lcd interface

I have another problem now.when i turn my pic on, the lcd doesn't turn on (in 90% of times),is there another setting t oset this.
 

4 bit lcd c code for 16f877a

Hi,

There are few ways to see how to solve your problems with the LCD.
1. Go to Microchip web site and look under the App Note for LCD. There you will see few notes on how to do this. **broken link removed**

2. Again in the Microchip web site, go to the PICDEM2+ EV Board directory, and download the source code. It is used with the F877 and it demonstrates the LCD. In the User manual you will also find the Electronic circuit that you will have to compare to your design so the output pines will match.
Direct link: **broken link removed**

3. Last but not list, is a very useful web site ( Its not Microchip web site ): www.microchipc.com

If you found my answer useful, click on the button that says Helped me. ( NO points will be taken from you! )


Good luck.
 
  • Like
Reactions: areeckal

    bjerkely

    Points: 2
    Helpful Answer Positive Rating

    areeckal

    Points: 2
    Helpful Answer Positive Rating
    V

    Points: 2
    Helpful Answer Positive Rating
#include <pic.h>
//#include <delay.h>

void delay_ms()
{
for(int k=0;k<100;k++);
}
void lcd_cmd(char ch)
{
PORTD=ch; //sending character element on port
PORTC=0x04;
delay_ms(100); //to wait for character to write on lcd
PORTC=0x00;
}
void lcd_data(char ch)
{
PORTD=ch;
PORTC=0x05;
delay_ms(100);
PORTC=0x01;
}
void init_lcd()
{
lcd_cmd(0x38); // function set (set interface length)
lcd_cmd(0x0E); //enable cursor display
//lcd_cmd(0x01); //clear display
//lcd_cmd(0x06); //entry mode set
//lcd_cmd(0x1C); //move cursor

}

void main(void)
{
char str[] = "Welcome";
int len;
int i;
TRISC=0;
TRISD=0;
init_lcd();

len=sizeof(str);
for( i=0;i<=len;i++) //for sending commands character by character
{
lcd_data(str);
}
lcd_cmd(0x0c);
lcd_cmd(0x02);
}









this will work better :)
 

#include <pic.h>
//#include <delay.h>

void delay_ms()
{
for(int k=0;k<100;k++);
}
void lcd_cmd(char ch)
{
PORTD=ch; //sending character element on port
PORTC=0x04;
delay_ms(100); //to wait for character to write on lcd
PORTC=0x00;
}
void lcd_data(char ch)
{
PORTD=ch;
PORTC=0x05;
delay_ms(100);
PORTC=0x01;
}
void init_lcd()
{
lcd_cmd(0x38); // function set (set interface length)
lcd_cmd(0x0E); //enable cursor display
//lcd_cmd(0x01); //clear display
//lcd_cmd(0x06); //entry mode set
//lcd_cmd(0x1C); //move cursor

}

void main(void)
{
char str[] = "Welcome";
int len;
int i;
TRISC=0;
TRISD=0;
init_lcd();

len=sizeof(str);
for( i=0;i<=len;i++) //for sending commands character by character
{
lcd_data(str);
}
lcd_cmd(0x0c);
lcd_cmd(0x02);
}









this will work better :)


Very useful code. Is it written for any LCD having a Hitachi HD44780 controller chip?

Secondly whats the function of following commands

lcd_cmd(0x0c);
lcd_cmd(0x02);

Thanks
 

Very useful code. Is it written for any LCD having a Hitachi HD44780 controller chip?

Secondly whats the function of following commands

lcd_cmd(0x0c);
lcd_cmd(0x02);

Thanks

LCD_cmd(0x0c) means to display the cursor off of the Lcd

& 0x02 i think it means to clear dislay ...m not sure about it..you can refer the datsheet
 

#include <pic.h>
//#include <delay.h>

void delay_ms()
{
for(int k=0;k<100;k++);
}
void lcd_cmd(char ch)
{
PORTD=ch; //sending character element on port
PORTC=0x04;
delay_ms(100); //to wait for character to write on lcd
PORTC=0x00;
}
void lcd_data(char ch)
{
PORTD=ch;
PORTC=0x05;
delay_ms(100);
PORTC=0x01;
}
void init_lcd()
{
lcd_cmd(0x38); // function set (set interface length)
lcd_cmd(0x0E); //enable cursor display
//lcd_cmd(0x01); //clear display
//lcd_cmd(0x06); //entry mode set
//lcd_cmd(0x1C); //move cursor

}

void main(void)
{
char str[] = "Welcome";
int len;
int i;
TRISC=0;
TRISD=0;
init_lcd();

len=sizeof(str);
for( i=0;i<=len;i++) //for sending commands character by character
{
lcd_data(str);
}
lcd_cmd(0x0c);
lcd_cmd(0x02);
}









this will work better :)


can i use the same for HD44780 20x4 LCD also (with pic16f767)?
 

I am relatively new with this PIC programming and I am also having difficulty getting HD44780 based LCD to dance with me. I am using Hitec C and trying to get the LCD example to work. First about my wiring. I've got control lines connected to RD6 and RD7 (R/W grounded). I am trying to get 4-bit interface to work so my data wires (DB4..DB7) are connected to RB4..RB7 on the pic. PIC I am using is 16F877A.

I can get something on the screen, but it is random pixels with-in character segment. Cursor is blinking fine and the best I got was roughly equal amount of scribble int the screen as there were supposed to be characters.

My lcd_init code looks like this:
Code:
void lcd_init()
{
	char init_value;

	init_value = 0x3;
	TRISB=0;
	TRISD=0;
	LCD_RS = 0;
	LCD_EN = 0;

	DelayMs(15);	// wait 15mSec after power applied,
	LCD_DATA = init_value;
	lcd_EN_toggle();
	DelayMs(50);
        LCD_DATA = init_value;
	lcd_EN_toggle();
	DelayUs(200);
        LCD_DATA = init_value;
	lcd_EN_toggle();
	DelayUs(200);
	LCD_DATA = 2;	// Four bit mode
	lcd_EN_toggle();

	lcd_write(0x28); // Set interface length
	lcd_write(0xF); // Display On, Cursor On, Cursor Blink
	lcd_clear();	// Clear screen
	lcd_write(0x6); // Set entry Mode
}
The write function is pretty much straight from the example:
Code:
void lcd_write(unsigned char c)
{
    DelayUs(400);
    LCD_DATA = ( ( c >> 4 ) & 0x0f );
    lcd_EN_toggle();
    LCD_DATA = ( c & 0x0f );
    lcd_EN_toggle();
}

Ports have been defined like this:
Code:
#define	LCD_RS RD7
//#define	LCD_RW RB0
#define LCD_EN RD6
#define LCD_DATA PORTB

Delay function I found somewhere and it is like this
Code:
#define DelayUs(x) { unsigned char _dcnt; \
_dcnt = (x)/((12MHZ)/(XTAL_FREQ))|1; \
while(--_dcnt != 0) \
continue; }

I have the free version of Hitec C and I haven't found any built in delay functions so I am not sure how accurate the above macro is. I am using 4Mhz crystal.

Any ideas where I should look for the solution?

Btw. is there any harm using RB0..RB2 ports for the control wires since those aren't used for anything else? Or is there something that must be done differently for data port definition?

---------- Post added at 14:58 ---------- Previous post was at 13:51 ----------

Any ideas where I should look for the solution?

Btw. is there any harm using RB0..RB2 ports for the control wires since those aren't used for anything else? Or is there something that must be done differently for data port definition?

Ok so it was the wiring. I had to change DB4...DB7 lines to RB0..RB3 ports and it works. This is not ideal situation for me, so the question remains. How should I configure the PIC to only use four outputs of port B for data wires and two for the control wires?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top