PIC18F452, LCD HD44780 compatible issues

Status
Not open for further replies.

oxygen8d

Newbie level 2
Joined
Oct 30, 2009
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
UK
Activity points
1,297
Hello forum

I am working on a project, I am currently trying to get some LCD code attached to drive my LCD, the LCD is HD44780 compatible and the driver is written for it. However, my circuit has a 20Mhz crystal so I think the delays that are defined at the beginning of the code must be incorrect. Could someone please help with this. I have my LCD wired like this:

RB0 -> D4
RB1 -> D5
RB2 -> D6
RB3 -> RS
RB5 -> E

I have a 10k pot connected to Vo for contrast. I am getting a line of solid balck boxes when the contrast is fully up. I have the required curent going to the backlight. So I think it must be my code: I need help with the delay as the code was written for a PIC16F876 with a clock of 3.876Mhz.

Thanks in advance

Jim

Code:
#include <p18f452.h>

// LCD Driver module
// LCD module is connected as follows:
// RB0 - RB3 -> DB4 - DB7
// RB4 -> RS
// RB5 -> E

// define constants
#define RS PORTBbits.RB4			// RS control line is bit 4 of port B
#define E  PORTBbits.RB5			// E control line is bit 5 of port B 
#define LCD_INIT 0x33		// command to initialise LCD display
#define FOUR_BIT_MODE 0x32	// command to make the LCD transfer instructions and data in 4 bit chunks rather than 8
#define TWO_LINE_MODE 0x2c	// command to put the LCD in two-line mode
#define MOVE_AFTER_WRITE 0x06	// command to increment cursor position automatically
#define DISPLAY_INIT 0x0c	// command to turn display on, switch off the cursor and stop it blinking

#define WRITE_DELAY 200		// constant used to set write delay time (50 us required)
#define BIT_DELAY 2		// constant used to set pulse duration (a few us required)
#define INST_DELAY 1000		// constant used to det instruction delay (1.53 ms required)

//#define WRITE_DELAY 270		// constant used to set write delay time (50 us required)	200ns * 270 = 54us
//#define BIT_DELAY 15		// constant used to set pulse duration (a few us required)		200 ns * 15 = 3us	
//#define INST_DELAY 3000		// constant used to det instruction delay (1.53 ms required) 200ns * 7500 = 1.5ms

// FUNCTION EXTERNAL FUNCTION REFERENCES


// FUNCTION ADVANCE DECLARATIONS
void LCD_write(unsigned char c, unsigned char rs);	// basic write function (instruction or data depending on rs)
void LCD_initialise(void);				// send initialisation commands to LCD
void LCD_clear(void);					// function to clear LCD display and home the cursor
void LCD_delay(unsigned int D);				// function to generate a delay 
void pulse_E(void);					// function to pulse E pin high then low
void LCD_putch(unsigned char c);			// character output routine
void LCD_puts(unsigned char *s);                        // Writes string s to LCD
void LCD_cursor (unsigned char x, unsigned char y );    // Moves cursor to x,y
void LCD_cursor_on (void);                              // Turn cursor on
void LCD_cursor_off (void);                             // Turn cursor off
void LCD_display_value (unsigned int value);           // Display a numeric value (0-999)

// Initialise LCD module
void LCD_initialise(void)
{

	// INITIALISE LCD
	LCD_write(LCD_INIT, 0);		// command to initialise LCD display, (RS = 0)
	LCD_delay(INST_DELAY);		// call function to wait until LCD has completed instruction

	// Set LCD for 4-bit mode
	LCD_write(FOUR_BIT_MODE, 0);	// command to set LCD in 4-bit mode, (RS = 0)
	LCD_delay(INST_DELAY);		// call function to wait until LCD has completed instruction

	// set LCD in up for two lines
	LCD_write(TWO_LINE_MODE, 0);	// command to set LCD for two lines, (RS = 0)
	LCD_delay(INST_DELAY);		// call function to wait until LCD has completed instruction

	// Select move after write	
	LCD_write(MOVE_AFTER_WRITE, 0);	// command to set LCD to increment cursor pos. automatically (RS = 0)
	LCD_delay(INST_DELAY);		// call function to wait until LCD has completed instruction

	// Configure display & cursor
	LCD_write(DISPLAY_INIT, 0);	// command to configure display, (RS = 0)
	LCD_delay(INST_DELAY);		// call function to wait until LCD has completed instruction
	
	LCD_clear();
}


	
// LCD_write() function is a basic write subroutine that could be an instruction or data
void LCD_write(unsigned char c, unsigned char rs)
{
	unsigned char temp;		// temporary variable to hold ms 4 bits of c
	unsigned char RSmask = 0;	// used to set or reset bit 4 of PORTB
	unsigned char TRISB_BAK;        // Current status of port B data direction register

	// INITIALISATION
//	RP0 = 1;        		// get ready to write to data direction registers
	TRISB_BAK = TRISB;              // Get current state of TRISB register
	TRISB = 0x00;			// Set PORTB bits 0 - 7 as outputs
//	RP0 = 0;		        // get ready to use ports

	if (rs == 1) RSmask = 0x10;	// set up bit mask for RS line

	// set MS 4 bits of c up on RB0 - RB3
	temp = c;
	LATB = (temp >> 4) | RSmask;	// shift MS 4 bits into LS 4 bits, set/rst RS and present on PORTB

	// pulse E high then low
	pulse_E();			// call function to strobe data to LCD module

	// set LS 4 bits up on RB0 - RB3
	LATB = (c & 0x0F) | RSmask;	// present LS 4 bits on RB0 - RB3 and set/rst RS line

	// pulse E high then low
	pulse_E();			// Call function to strobe data to LCD module
	
	LATB = 0x10;			// set E high again  to avoid annoying LED flicker

//	RP0 = 1;		        // get ready to write to data direction registers
	TRISB = TRISB_BAK;		// Restore state of TRISB register
//	RP0 = 0;		        // get ready to use ports
}


//putch(c) function is character output routine
void LCD_putch(unsigned char c)
{
	LCD_write(c, 1);		// call basic LCD write routine with RS high (send data)
	LCD_delay(WRITE_DELAY);		// call function to wait until LCD has completed write operation
}

//LCD_clear() function is an instruction to clear all data from LCD display and return cursor to beginning of display
void LCD_clear(void)
{
	LCD_write(1, 0);		// call basic write function with instruction 1, (clear display) and RS 0, (write instruction)
	LCD_delay(INST_DELAY);		// Call function to wait until LCD has completed instruction
	LCD_write(2, 0);		// call basic write function with instruction 2, (cursor home) and RS = 0, (write instruction)
	LCD_delay(INST_DELAY);		// call function to wait until LCD has completed instruction
}

// function to pulse E pin high then low with a duration of a few usecs
void pulse_E(void)
{
	// set E high and wait a bit
	E = 1;		                // set E line high
	LCD_delay(BIT_DELAY);		// pulse delay for E

	// set E low and wait a bit
	E = 0;		                // set E line low
	LCD_delay(BIT_DELAY);		// pulse delay for E	
	
}

// Function to generate a delay
void LCD_delay(unsigned int D)
{
	unsigned int counter;		// variable used as delay loop counter
	for (counter = 0; counter < D; counter++);
}

// Function to write null terminated string to LCD display
void LCD_puts(unsigned char *s)
{
        unsigned char c = 255;
        unsigned char i = 0;
        while ((c > 0) && (i < 16)) //16 is the maximum length of the string
        {
          c = s[i];
          if (c != 0) LCD_putch(c);
          i++;
        }
}        

void LCD_cursor (unsigned char x, unsigned char y )
{
    if ( y==0 ) 
    {
        /* position for line 0     */
        y=0x80 ;
    }
    else 
    {
        /* position for line 1     */
        y=0xc0 ;
    }
    
    LCD_write( y+x, 0) ;
}

void LCD_cursor_on ( void )       // Turn cursor on
{
    LCD_write(0x0f, 0);
}

void LCD_cursor_off ( void )      // Turn cursor off
{
    LCD_write (0x0c, 0);
}

void LCD_display_value ( unsigned int value ) 
{
    unsigned char hunds, tens, units ;
    
    /*  first get the digits  */
    
    units = value % 10 ;
    value = value / 10 ;
    tens = value % 10 ;
    value = value / 10 ;
    hunds = value % 10 ;
    
    /*  now display them      */ 
    
    LCD_putch('0' + hunds ) ;
    LCD_putch('0' + tens);
    LCD_putch('0' + units);
}
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…