// 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();
}