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.

Unable to write characters to LCD from PIC with HiTech C

Status
Not open for further replies.

the_merovingian

Member level 1
Joined
Jul 25, 2009
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
UK
Activity points
1,558
I'm converting some of my code from assembler to HiTech PICC C. I'm using a PIC16F672A.

The following code doesn't seem to work correctly. It correctly initiates the LCD (i.e. I can see the dim glow of both lines as it's 2x16, the cursor is present & blinks etc), but when the code goes to write some character data the LCD just goes blank.

I've tested RS and it does go high.

RB0:3 = DB4:7
RA1 = EN
RA3 = RS

Any ideas?

Code:
#include <htc.h>

__CONFIG(BOREN & UNPROTECT & UNPROTECT & PWRTEN & WDTDIS & LVPDIS & MCLREN & INTIO);

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

#ifndef _XTAL_FREQ
 // Unless specified elsewhere, 4MHz system frequency is assumed
 #define _XTAL_FREQ 4000000
#endif

#define	LCD_RS RA3
#define  LCD_EN RA1

#define  LCD_DATA	PORTB

#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)
{
	__delay_ms(40);
	LCD_DATA = ( ( c >> 4 ) & 0x0F );
	LCD_STROBE();
	LCD_DATA = ( c & 0x0F );
	LCD_STROBE();
}

/*
 * 	Clear and home the LCD
 */

void
lcd_clear(void)
{
	LCD_RS = 0;
	lcd_write(0x1);
	__delay_ms(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
	lcd_write( c );
}


/*
 * 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()
{
	char init_value;

	init_value = 0x3;
	TRISA=0;
	TRISB=0;
	LCD_RS = 0;
	LCD_EN = 0;
	/* LCD_RW = 0; not required - RW tied low */
	
	__delay_ms(15);	// wait 15mSec after power applied,
	LCD_DATA	 = init_value;
	LCD_STROBE();
	__delay_ms(5);
	LCD_STROBE();
	__delay_ms(50);
	LCD_STROBE();
	__delay_ms(50);
	LCD_DATA = 2;	// Four bit mode
	LCD_STROBE();

	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
	lcd_write(0x2); // return home
}

void main(void)
{
	lcd_init();

	__delay_ms(50);

/* this doesn't work:
	lcd_puts("Hello world");
*/

/* ...neither does this, which should present the character "U" : */

	LCD_RS = 1;
	__delay_ms(50);
   LCD_DATA = 0x05;
	LCD_STROBE();
	__delay_ms(50);
   LCD_DATA = 0x05;
	LCD_STROBE();

	for(;;);

}

Added after 2 hours 48 minutes:

I've figured this one out myself... I forgot to disable the onboard comparators!!

Amendment for those of you interest:

Code:
void main(void)
{
   
   CMCON = 0x07; // disable comparators

	lcd_init();
 

The problem you are facing is due to timings. Check out the lcd datasheet and apply proper timing for each instructions

Nandhu
 

No - as I stated above the problem was related to the comparators being enabled.

There is nothing wrong with those timings - they are over generous if anything.
 

hello friends

as per my knowledge

In 16X2 LCD, There is ADDRESS for each location(one Matrix(5x7) of black dot) .

and The Address for first line is start from 0x80 to 0x8f
and the address for second line is start from 0xC0 to 0xCF

to write any character to LCD
first send address for location and then send character to print that location

sorry for my poor English

Regards

Ghanshym dudhat
 

Yes, you are correct, hence the:

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

But, as stated above, that wasn't the problem.
 

in your above code ,

from where, you are calling function(lcd_write();)

i think, your main function is write to like this type

void main(void)
{
lcd_init();

__delay_ms(50);


lcd_goto(0x00);

lcd_puts("Hello world");



/* ...neither does this, which should present the character "U" : */


lcd_goto(0x00);

LCD_RS = 1;
__delay_ms(50);
LCD_DATA = 0x05;
LCD_STROBE();
__delay_ms(50);
LCD_DATA = 0x05;
LCD_STROBE();

for(;;);

}



Regard

Ghanshyam
 

For the first write it is in the correct position, this is due to the following code:

Code:
lcd_write(0x2); // return home
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top