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.

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

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top