PIC8-Bit Trainer - Module LCD - EA-DIPS082 - ST7066 (HD44780 Compatible) - 2x8.

0.Contents

PIC18F Trainer : PIC18F2620 @8MHz Internal oscillator.

1.String & Custom Patterns - 8-Bit No Busy Flag - Permanent backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 8-Bit No Busy Flag.
// String & Custom Patterns.
// Permanent Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> GND.
// MODULE.06 -> MCU.RA1.
// MODULE.07 -> MCU.RB0.
// MODULE.08 -> MCU.RB1.
// MODULE.09 -> MCU.RB2.
// MODULE.10 -> MCU.RB3.
// MODULE.11 -> MCU.RB4.
// MODULE.12 -> MCU.RB5.
// MODULE.13 -> MCU.RB6.
// MODULE.14 -> MCU.RB7.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - D0 : 4/8-bit Backlight permanent.
// JP2 - Not use.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_E_TRIS									TRISAbits.TRISA1
#define ST7066_RS										LATAbits.LATA0
#define ST7066_E										LATAbits.LATA1
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;

	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);

	while(1){
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstruction(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_writeData(char cData)
{
	ST7066_RS = 1;
	ST7066_E = 1;
	ST7066_DATA = cData;
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeInstruction(char cData)
{
	ST7066_RS = 0;
	ST7066_E = 1;
	ST7066_DATA = cData;
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

2.String & Custom Patterns - 8-Bit With Busy Flag - Permanent backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 8-Bit With Busy Flag.
// String & Custom Patterns.
// Permanent Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> MCU.RA1.
// MODULE.06 -> MCU.RA2.
// MODULE.07 -> MCU.RB0.
// MODULE.08 -> MCU.RB1.
// MODULE.09 -> MCU.RB2.
// MODULE.10 -> MCU.RB3.
// MODULE.11 -> MCU.RB4.
// MODULE.12 -> MCU.RB5.
// MODULE.13 -> MCU.RB6.
// MODULE.14 -> MCU.RB7.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - D0 : 4/8-bit Backlight permanent.
// JP2 - Not use.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_BF										PORTBbits.RB7
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_RW_TRIS									TRISAbits.TRISA1
#define ST7066_E_TRIS									TRISAbits.TRISA2
#define ST7066_RS										LATAbits.LATA0
#define ST7066_RW										LATAbits.LATA1
#define ST7066_E										LATAbits.LATA2
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_readBusyFlag(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeInstructionNBF(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_RW_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;
	
	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);

	while(1){
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_readBusyFlag(void)
{
	ST7066_RS = 0;
	ST7066_RW = 1;
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0xff;
	do{
		ST7066_E = 0;
		ST7066_E = 1;
	}while(ST7066_BF);
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;
}

void st7066_writeData(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 1;
	ST7066_RW = 0;
	ST7066_RS = 1;
	ST7066_E = 1;
	ST7066_DATA = cData;
	ST7066_E = 0;
}

void st7066_writeInstruction(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_E = 1;
	ST7066_DATA = cData;
	ST7066_E = 0;
}

void st7066_writeInstructionNBF(char cData)
{
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_E = 1;
	ST7066_DATA = cData;
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

3.String & Custom Patterns - 4-Bit Low Nibble No Busy Flag - Permanent backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 4-Bit Low Nibble No Busy Flag.
// String & Custom Patterns.
// Permanent Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> GND.
// MODULE.06 -> MCU.RA1.
// MODULE.07 -> NC.
// MODULE.08 -> NC.
// MODULE.09 -> NC.
// MODULE.10 -> NC.
// MODULE.11 -> MCU.RB0.
// MODULE.12 -> MCU.RB1.
// MODULE.13 -> MCU.RB2.
// MODULE.14 -> MCU.RB3.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - D0 : 4/8-bit Backlight permanent.
// JP2 - Not use.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_E_TRIS									TRISAbits.TRISA1
#define ST7066_RS										LATAbits.LATA0
#define ST7066_E										LATAbits.LATA1
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_writeInstruction(char cData);
void st7066_writeData(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;

	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);
	
	while(1){
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstruction(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_writeData(char cData)
{
	ST7066_RS = 1;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeInstruction(char cData)
{
	ST7066_RS = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

4.String & Custom Patterns - 4-Bit Low Nibble With Busy Flag - Permanent backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 4-Bit Low Nibble With Busy Flag.
// String & Custom Patterns.
// Permanent Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> MCU.RA1.
// MODULE.06 -> MCU.RA2.
// MODULE.07 -> NC.
// MODULE.08 -> NC.
// MODULE.09 -> NC.
// MODULE.10 -> NC.
// MODULE.11 -> MCU.RB0.
// MODULE.12 -> MCU.RB1.
// MODULE.13 -> MCU.RB2.
// MODULE.14 -> MCU.RB3.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - D0 : 4/8-bit Backlight permanent.
// JP2 - Not use.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_BF										PORTBbits.RB3
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_RW_TRIS									TRISAbits.TRISA1
#define ST7066_E_TRIS									TRISAbits.TRISA2
#define ST7066_RS										LATAbits.LATA0
#define ST7066_RW										LATAbits.LATA1
#define ST7066_E 										LATAbits.LATA2
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_readBusyFlag(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeInstructionNBF(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_RW_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;

	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);
	
	while(1){
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_readBusyFlag(void)
{
	ST7066_RS = 0;
	ST7066_RW = 1;
	ST7066_DATA &= 0xf0;
	ST7066_DATA_TRIS = 0x0f;
	do{
		ST7066_E = 0;
		ST7066_E = 1;
	}while(ST7066_BF);
	ST7066_DATA = 0xf0;
	ST7066_DATA_TRIS = 0x00;
}

void st7066_writeData(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 1;
	ST7066_RW = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
}

void st7066_writeInstruction(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
}

void st7066_writeInstructionNBF(char cData)
{
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

5.String & Custom Patterns - 4-Bit High Nibble No Busy Flag - Permanent backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 4-Bit High Nibble No Busy Flag.
// String & Custom Patterns.
// Permanent Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> GND.
// MODULE.06 -> MCU.RA1.
// MODULE.07 -> NC.
// MODULE.08 -> NC.
// MODULE.09 -> NC.
// MODULE.10 -> NC.
// MODULE.11 -> MCU.RB4.
// MODULE.12 -> MCU.RB5.
// MODULE.13 -> MCU.RB6.
// MODULE.14 -> MCU.RB7.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - D0 : 4/8-bit Backlight permanent.
// JP2 - Not use.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_E_TRIS									TRISAbits.TRISA1
#define ST7066_RS										LATAbits.LATA0
#define ST7066_E 										LATAbits.LATA1
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_busyFlag(void);
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;

	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);
	
	while(1){
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstruction(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_writeData(char cData)
{
	ST7066_RS = 1;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeInstruction(char cData)
{
	ST7066_RS = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

6.String & Custom Patterns - 4-Bit High Nibble With Busy Flag - Permanent backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 4-Bit High Nibble With Busy Flag.
// String & Custom Patterns.
// Permanent Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> MCU.RA1.
// MODULE.06 -> MCU.RA2.
// MODULE.07 -> NC.
// MODULE.08 -> NC.
// MODULE.09 -> NC.
// MODULE.10 -> NC.
// MODULE.11 -> MCU.RB4.
// MODULE.12 -> MCU.RB5.
// MODULE.13 -> MCU.RB6.
// MODULE.14 -> MCU.RB7.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - D0 : 4/8-bit Backlight permanent.
// JP2 - Not use.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_BF										PORTBbits.RB7
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_RW_TRIS									TRISAbits.TRISA1
#define ST7066_E_TRIS									TRISAbits.TRISA2
#define ST7066_RS										LATAbits.LATA0
#define ST7066_RW										LATAbits.LATA1
#define ST7066_E 										LATAbits.LATA2
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_readBusyFlag(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeInstructionNBF(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_RW_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;

	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);

	while(1){
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_readBusyFlag(void)
{
	ST7066_RS = 0;
	ST7066_RW = 1;
	ST7066_DATA &= 0x0f;
	ST7066_DATA_TRIS = 0xf0;
	do{
		ST7066_E = 0;
		ST7066_E = 1;
	}while(ST7066_BF);
	ST7066_DATA = 0x0f;
	ST7066_DATA_TRIS = 0x00;
}

void st7066_writeData(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 1;
	ST7066_RW = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
}

void st7066_writeInstruction(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
}

void st7066_writeInstructionNBF(char cData)
{
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

7.String & Custom Patterns - 4-Bit Low Nibble No Busy Flag - PWM Controlled backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 4-Bit Low Nibble No Busy Flag.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> GND.
// MODULE.06 -> MCU.RA1.
// MODULE.07 -> MCU.RC2.
// MODULE.08 -> NC.
// MODULE.09 -> NC.
// MODULE.10 -> NC.
// MODULE.11 -> MCU.RB0.
// MODULE.12 -> MCU.RB1.
// MODULE.13 -> MCU.RB2.
// MODULE.14 -> MCU.RB3.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - Not use.
// JP2 - Backlight : 4-bit Backlight controlled.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_E_TRIS									TRISAbits.TRISA1
#define ST7066_RS										LATAbits.LATA0
#define ST7066_E										LATAbits.LATA1
// Backlight.
#define BACKLIGHT										CCPR1L
#define ST7066_BACKLIGHT								LATCbits.LATC2
#define ST7066_BACKLIGHT_TRIS							TRISCbits.TRISC2
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;
	// Output for Backlight.
	ST7066_BACKLIGHT = 0;
	ST7066_BACKLIGHT_TRIS = 0;

	// MCU Initialization.
	// Timer2 - 1KHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;

	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);
	
	uint8_t backlight = 0;
	while(1){
		for(backlight=0; backlight<0x80; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(100);
		}
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstruction(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_writeData(char cData)
{
	ST7066_RS = 1;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeInstruction(char cData)
{
	ST7066_RS = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

8.String & Custom Patterns - 4-Bit Low Nibble With Busy Flag - PWM Controlled backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 4-Bit Low Nibble With Busy Flag.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> MCU.RA1.
// MODULE.06 -> MCU.RA2.
// MODULE.07 -> MCU.RC2.
// MODULE.08 -> NC.
// MODULE.09 -> NC.
// MODULE.10 -> NC.
// MODULE.11 -> MCU.RB0.
// MODULE.12 -> MCU.RB1.
// MODULE.13 -> MCU.RB2.
// MODULE.14 -> MCU.RB3.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - Not use.
// JP2 - Backlight : 4-bit Backlight controlled.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_BF										PORTBbits.RB3
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_RW_TRIS									TRISAbits.TRISA1
#define ST7066_E_TRIS									TRISAbits.TRISA2
#define ST7066_RS										LATAbits.LATA0
#define ST7066_RW										LATAbits.LATA1
#define ST7066_E 										LATAbits.LATA2
// Backlight.
#define BACKLIGHT										CCPR1L
#define ST7066_BACKLIGHT								LATCbits.LATC2
#define ST7066_BACKLIGHT_TRIS							TRISCbits.TRISC2
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_readBusyFlag(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeInstructionNBF(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_RW_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;
	// Output for Backlight.
	ST7066_BACKLIGHT = 0;
	ST7066_BACKLIGHT_TRIS = 0;

	// PWM Initialization.
	// Timer2 - 1KHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;
	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);
	
	uint8_t backlight = 0;	
	while(1){
		for(backlight=0; backlight<0x80; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(100);
		}
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_readBusyFlag(void)
{
	ST7066_RS = 0;
	ST7066_RW = 1;
	ST7066_DATA &= 0xf0;
	ST7066_DATA_TRIS = 0x0f;
	do{
		ST7066_E = 0;
		ST7066_E = 1;
	}while(ST7066_BF);
	ST7066_DATA = 0xf0;
	ST7066_DATA_TRIS = 0x00;
}

void st7066_writeData(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 1;
	ST7066_RW = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
}

void st7066_writeInstruction(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
}

void st7066_writeInstructionNBF(char cData)
{
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= ((cData>>4) & 0x0f);
	ST7066_E = 0;
	ST7066_DATA &= 0xf0;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0x0f);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

9.String & Custom Patterns - 4-Bit High Nibble No Busy Flag - PWM Controlled backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 4-Bit High Nibble No Busy Flag.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> GND.
// MODULE.06 -> MCU.RA1.
// MODULE.07 -> MCU.RC2.
// MODULE.08 -> NC.
// MODULE.09 -> NC.
// MODULE.10 -> NC.
// MODULE.11 -> MCU.RB4.
// MODULE.12 -> MCU.RB5.
// MODULE.13 -> MCU.RB6.
// MODULE.14 -> MCU.RB7.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - Not use.
// JP2 - Backlight : 4-bit Backlight controlled.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_E_TRIS									TRISAbits.TRISA1
#define ST7066_RS										LATAbits.LATA0
#define ST7066_E										LATAbits.LATA1
// Backlight.
#define BACKLIGHT										CCPR1L
#define ST7066_BACKLIGHT								LATCbits.LATC2
#define ST7066_BACKLIGHT_TRIS							TRISCbits.TRISC2
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESS_FIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESS_SECOND_LINE			0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;
	// Output for Backlight.
	ST7066_BACKLIGHT = 0;
	ST7066_BACKLIGHT_TRIS = 0;

	// PWM Initialization.
	// Timer2 - 1KHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;

	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066U CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESS_FIRST_LINE);

	// Display Custom Patterns from ST7066U CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);
	
	uint8_t backlight = 0;
	while(1){
		for(backlight=0; backlight<0x80; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(100);
		}
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESS_SECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstruction(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_writeData(char cData)
{
	ST7066_RS = 1;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeInstruction(char cData)
{
	ST7066_RS = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

10.String & Custom Patterns - 4-Bit High Nibble With Busy Flag - PWM Controlled backlight.

// Configuration registers.
#pragma config IESO = OFF, FCMEN = OFF, OSC = INTIO7
#pragma config BORV = 3, BOREN = OFF, PWRT = OFF
#pragma config WDTPS = 32768, WDT = OFF
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC
#pragma config DEBUG = OFF, XINST = OFF, LVP = OFF, STVREN = ON
#pragma config CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF
#pragma config CPD = OFF, CPB = OFF
#pragma config WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
#pragma config WRTD = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF
#pragma config EBTRB = OFF

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 8000000
// PIC18F2620 - Compile with XC8(v2.00).
// PIC18F2620 - @8MHz Internal oscillator.

// LCD - EA-DIPS082-HNLED - ST7066 (HD44780 Compatible) - 4-Bit High Nibble With Busy Flag.
// String & Custom Patterns.
// PWM Controlled Backlight.

// Expansion Board - EA-DIPS082-HNLED - Rev.B.

// MODULE.01 -> GND.
// MODULE.02 -> VDD - 5V.
// MODULE.03 -> NC.
// MODULE.04 -> MCU.RA0.
// MODULE.05 -> MCU.RA1.
// MODULE.06 -> MCU.RA2.
// MODULE.07 -> MCU.RC2.
// MODULE.08 -> NC.
// MODULE.09 -> NC.
// MODULE.10 -> NC.
// MODULE.11 -> MCU.RB4.
// MODULE.12 -> MCU.RB5.
// MODULE.13 -> MCU.RB6.
// MODULE.14 -> MCU.RB7.
// MODULE.15 -> NC.
// MODULE.16 -> NC.

// JP1 - SCL Not use.
// JP2 - SDA Not use.
// JP3 - VEE Close, use P3 for brightness.
// JP4 - BCKL Not use.

// Expansion Board.
// JP1 - Not use.
// JP2 - Backlight : 4-bit Backlight controlled.

// Definitions.
// ST7066 Commands Port & Data Port.
#define ST7066_DATA										LATB
#define ST7066_DATA_TRIS								TRISB
#define ST7066_BF										PORTBbits.RB7
#define ST7066_RS_TRIS									TRISAbits.TRISA0
#define ST7066_RW_TRIS									TRISAbits.TRISA1
#define ST7066_E_TRIS									TRISAbits.TRISA2
#define ST7066_RS										LATAbits.LATA0
#define ST7066_RW										LATAbits.LATA1
#define ST7066_E 										LATAbits.LATA2
// Backlight.
#define BACKLIGHT										CCPR1L
#define ST7066_BACKLIGHT								LATCbits.LATC2
#define ST7066_BACKLIGHT_TRIS							TRISCbits.TRISC2
// ST7066 Instructions.
#define ST7066_CLEAR_DISPLAY							0x01
#define ST7066_RETURN_HOME								0x02
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_NOSHIFT		0x04
#define ST7066_ENTRY_MODE_DDRAM_DECREMENT_SHIFT			0x05
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT		0x06
#define ST7066_ENTRY_MODE_DDRAM_INCREMENT_SHIFT			0x07
#define ST7066_DISPLAY_OFF								0x08
#define ST7066_DISPLAY_ON_CURSOR_OFF					0x0C
#define ST7066_DISPLAY_ON_CURSOR_ON_NOBLINK				0x0E
#define ST7066_DISPLAY_ON_CURSOR_ON_BLINK				0x0F
#define ST7066_DISPLAY_CURSOR_SHIFT_LEFT				0x10
#define ST7066_DISPLAY_CURSOR_SHIFT_RIGHT				0x14
#define ST7066_DISPLAY_SCREEN_SHIFT_LEFT				0x18
#define ST7066_DISPLAY_SCREEN_SHIFT_RIGHT				0x1C
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x8		0x20
#define ST7066_FUNCTION_SET_4_BIT_ONE_LINE_FONT5x11		0x24
#define ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8		0x28
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x8		0x30
#define ST7066_FUNCTION_SET_8_BIT_ONE_LINE_FONT5x11		0x34
#define ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8		0x38
#define ST7066_SET_CGRAM_ADDRESS						0x40
#define ST7066_SET_DDRAM_ADDRESSFIRST_LINE				0x80
#define ST7066_SET_DDRAM_ADDRESSSECOND_LINE				0xC0

// Function prototypes.
void st7066_clearDisplay(void);
void st7066_initialize(void);
void st7066_readBusyFlag(void);
void st7066_writeData(char cData);
void st7066_writeInstruction(char cData);
void st7066_writeInstructionNBF(char cData);
void st7066_writeString(const char * cData);
void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data);

// Strings & Custom patterns.
const char string0[] = "Tronix";
const char custom_patterns[5][8] = {
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f},
	{0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}
};

// Main.
int main(void)
{
	// MCU Initialization.
	// Internal Oscillator 8MHz.
	OSCCONbits.IRCF2  = 1;
	OSCCONbits.IRCF1  = 1;
	OSCCONbits.IRCF0  = 1;
	OSCTUNEbits.PLLEN = 0;
	while(!OSCCONbits.IOFS);
	// Outputs for LCD command.
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_E = 0;
	ST7066_RS_TRIS = 0;
	ST7066_RW_TRIS = 0;
	ST7066_E_TRIS = 0;
	// Outputs for LCD data.
	ST7066_DATA = 0x00;
	ST7066_DATA_TRIS = 0x00;
	// Output for Backlight.
	ST7066_BACKLIGHT = 0;
	ST7066_BACKLIGHT_TRIS = 0;

	// PWM Initialization.
	// Timer2 - 1KHz @8MHz.
	T2CON = 0b00000110;
	TMR2 = 0x00;
	PR2 = 0x80;
	// PWM Mode.
	CCP1CON = 0b00001100;
	pwm_initialize();
	st7066_initialize();

	// Write 5x8 Dots Custom Patterns in ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_CGRAM_ADDRESS);
	uint8_t line = 0;
	uint8_t pattern = 0;
	for(pattern=0; pattern<5; pattern++){
		for(line=0; line<8; line++){
			st7066_writeData(custom_patterns[pattern][line]);
		}
	}
	
	// Display String.
	st7066_writeStringSetCursor(string0, ST7066_SET_DDRAM_ADDRESSFIRST_LINE);

	// Display Custom Patterns from ST7066 CGRAM.
	st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESSSECOND_LINE);
	st7066_writeData(0x00);
	st7066_writeData(0x01);
	st7066_writeData(0x02);
	st7066_writeData(0x03);
	st7066_writeData(0x04);

	uint8_t backlight = 0;	
	while(1){
		for(backlight=0; backlight<0x80; backlight++){
			BACKLIGHT = backlight;
			__delay_ms(100);
		}
		for(pattern=0; pattern<5; pattern++){
			st7066_writeInstruction(ST7066_SET_DDRAM_ADDRESSSECOND_LINE + 0x07);
			st7066_writeData(pattern);
			__delay_ms(800);
		}
	}
	return(0);
}

// Functions.
void st7066_clearDisplay(void)
{
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
}

void st7066_initialize(void)
{
	__delay_ms(20);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_8_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstructionNBF(ST7066_FUNCTION_SET_4_BIT_TWO_LINE_FONT5x8);
	st7066_writeInstruction(ST7066_DISPLAY_ON_CURSOR_OFF);
	st7066_writeInstruction(ST7066_CLEAR_DISPLAY);
	__delay_ms(2);
	st7066_writeInstruction(ST7066_ENTRY_MODE_DDRAM_INCREMENT_NOSHIFT);
}

void st7066_readBusyFlag(void)
{
	ST7066_RS = 0;
	ST7066_RW = 1;
	ST7066_DATA &= 0x0f;
	ST7066_DATA_TRIS = 0xf0;
	do{
		ST7066_E = 0;
		ST7066_E = 1;
	}while(ST7066_BF);
	ST7066_DATA = 0x0f;
	ST7066_DATA_TRIS = 0x00;
}

void st7066_writeData(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 1;
	ST7066_RW = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
}

void st7066_writeInstruction(char cData)
{
	st7066_readBusyFlag();
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
}

void st7066_writeInstructionNBF(char cData)
{
	ST7066_RS = 0;
	ST7066_RW = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= (cData & 0xf0);
	ST7066_E = 0;
	ST7066_DATA &= 0x0f;
	ST7066_E = 1;
	ST7066_DATA |= ((cData<<4) & 0xf0);
	ST7066_E = 0;
	__delay_us(40);
}

void st7066_writeString(const char * cData)
{
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

void st7066_writeStringSetCursor(const char * cData, uint8_t u8Data)
{
	st7066_writeInstruction(u8Data);
	while(*cData != '\0')
		st7066_writeData(*cData++);
}

08.2018