Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

HD44780 Timing problem

Status
Not open for further replies.
Hi,

Code:
}

void LCD_Delay(){
    Delay10KTCYx(6);    // Equal to about 5 milliseconds with a 48MHz clock
}
You're running your PIC at 48Mhz? Try at 4Mhz to get your LCD routines working then step up the speed. Get rid of those delays in the LCD enable routine.

The busy flag isn't really that important if you're code isn't timing critical but it's there and not much bother to use once you figure it out. Get your code working with delays so you know the rest of your code is good then have another stab at the busy routine.
 
I think I've found your problem, you're not turning the comparators off and so RD3 is analogue and always reads zero. Try adding CMCON=7;

Mike.
 
Hi,
You're running your PIC at 48Mhz? Try at 4Mhz to get your LCD routines working then step up the speed. Get rid of those delays in the LCD enable routine.

The busy flag isn't really that important if you're code isn't timing critical but it's there and not much bother to use once you figure it out. Get your code working with delays so you know the rest of your code is good then have another stab at the busy routine.

Hi yep all of the routines are working at 48MHz. According to the datasheet I have, the Enable cycle needs to be a minimum of 1000ns, so I need the delays, although I padded them out a bit.
 
I think I've found your problem, you're not turning the comparators off and so RD3 is analogue and always reads zero. Try adding CMCON=7;

Mike.

BINGO!!

You sir are a legend. All working fine now :)
 
Thanks for the help guys.

Here's the code working @ 48MHz if anybody is interested:

Code:
// Include the necessary device header file
#include <p18f4685.h>
#include <timers.h>

//Defines for the LCD screen
#define LCD_RS		LATEbits.LATE0		// Defines which pin the LCD RS signal is connected to
#define LCD_RW		LATEbits.LATE1		// Defines which pin the LCD RW signal is connected to
#define LCD_E 		LATEbits.LATE2   	// Defines which pin the LCD Enable signal is connected to
#define LCD_Port 	LATD   				// Defines which port the LCD data lines are connected to (The high bits of the LCD must be connected to the low bits of the port (e.g. D4=Port?.0, D7=Port?.3)
#define LCD_Tris	TRISD				// Defines the tristate latch byte for the data prot
#define Busy_Flag	PORTDbits.RD3

unsigned char Data;

// Function prototypes
void InterruptHandlerLow(void); /* Interupt Service Routine */
void Delay10KTCYx( unsigned char unit );
void Delay1KTCYx( unsigned char unit );
void Delay100TCYx( unsigned char unit );
void Delay10TCYx( unsigned char unit );
void Pulse_E( void );
void LCD_Delay(void);
void LCD_init(void);
void write2LCD (void);
void PrintLCD (unsigned char Data);
void AddressLCD (unsigned int Data);
void LCD_Busy (void);

#pragma code
#pragma interrupt InterruptHandlerLow
void InterruptHandlerLow(){						
}


#pragma code lowvector=0x18			// Low priority interrupts will end up here
void lowvector(void){
		_asm goto InterruptHandlerLow _endasm;
	}
#pragma code

#pragma code highvector=0x08			// Low priority interrupts will end up here
void highvector(void){
		_asm goto InterruptHandlerLow _endasm;
	}
#pragma code




// Main code section. Execution starts here.
void main(void){
 
  // Set all of PortA and PortD tristate latches
  TRISA=0b00000000; // 0 = output, 1 = input
  TRISB=0b00000000; // 0 = output, 1 = input
  TRISC=0b00000000; // 0 = output, 1 = input
  TRISD=0x00000000; // 0 = output, 1 = input
  TRISE=0x00000000; // 0 = output, 1 = input

  // Clear the PortA and PortD data latches
  LATA=0b00000000;
  LATB=0b00000000;
  LATC=0b00000000;
  LATD=0b00000000;
  LATE=0b00000000;
  
  ADCON1=0b00001111;    // Set all analog pins as digital I/O
  CMCON = 0x07;

LCD_init();		// Initialises the LCD display

AddressLCD(0x00);
PrintLCD(' ');
PrintLCD('T');
PrintLCD('h');
PrintLCD('e');
PrintLCD(' ');
PrintLCD('b');
PrintLCD('u');
PrintLCD('s');
PrintLCD('y');
PrintLCD(' ');
PrintLCD('f');
PrintLCD('l');
PrintLCD('a');
PrintLCD('g');
PrintLCD(' ');
PrintLCD(' ');

AddressLCD(0x40);
PrintLCD(' ');
PrintLCD('i');
PrintLCD('s');
PrintLCD(' ');
PrintLCD('y');
PrintLCD('o');
PrintLCD('u');
PrintLCD('r');
PrintLCD(' ');
PrintLCD('f');
PrintLCD('r');
PrintLCD('i');
PrintLCD('e');
PrintLCD('n');
PrintLCD('d');
PrintLCD(' ');

  // loop that never ends since '1' never changes
  while(1){
		
  }


}
  // end of main

 
// Start of our functions
// These functions are for the HD44780 LCD Display ////////////////////////////////////////////
void LCD_Busy (void) { 
    LCD_Tris |= 0x0f; 	// Sets the LCD port to an input
    LCD_RS = 0;   			  // Makes sure the register select is 0
    LCD_RW = 1;   			  
    LCD_E = 1;
	Delay10TCYx(1); 
    while (Busy_Flag); 
    LCD_E = 0; 
    LCD_RW = 0; 
    LCD_Tris &= 0xf0; 	// Sets the LCD Port back to an output 
	Delay10TCYx(1);
}



void 	Pulse_E(){   		// Pulses the LCD Enable line
	LCD_E = 1;
	Delay10TCYx(3);
	LCD_E = 0;
	Delay10TCYx(3);
}

void LCD_Delay(){
	Delay10KTCYx(6);	// Equal to about 5 milliseconds with a 48MHz clock
}

void PrintLCD(){
	Data = WREG;
	LCD_Busy();
	LCD_RS = 1;
	write2LCD();
}

void AddressLCD(){
	Data = WREG;
	LCD_Busy();
	Data +=  128;
	LCD_RS = 0;
	write2LCD();
}

void write2LCD (){
	LCD_Port = ((Data >> 4) & 0xf);    // swap nibbles. After swap, 'AND' upper 4 port bits (mask them)
	Pulse_E();
	LCD_Port = (Data & 0xf);
	Pulse_E();   
}

void LCD_init(){
// This next part of the code initialises the LCD Display
	Delay10KTCYx(160);					// Waits 100 milliseconds to make sure the LCD is powered on properly
	LCD_Port &= 0xF0;	//Clears the bits of the LCD data port
	LCD_Port += 3;			// Puts the first initialisation data onto the port
	Pulse_E();
	LCD_Delay();
	Pulse_E();
	LCD_Delay();
	Pulse_E();
	LCD_Delay();
	
	LCD_Port -= 1;			// Sets LCD to 4 bit mode
	Pulse_E();
	LCD_Delay();
// end of software reset

	Data = 0x28;						// 2 Rows; 4-bit; 5x7.
	write2LCD();
	LCD_Delay();

	Data = 0x0C;						// Display on; Cursor off; Blink off
	write2LCD();
	LCD_Delay();

	Data = 0x01;						// Clear screen
	write2LCD();
	LCD_Delay();

	Data = 0x06;						// Increment mode
	write2LCD();
	LCD_Delay();
}
 
Status
Not open for further replies.

Latest threads

Back
Top