#include "hd447780.h" void XLCDInit(void) { // The data bits must be either a 8-bit port or the upper or // lower 4-bits of a port. These pins are made into inputs #ifdef BIT8 // 8-bit mode, use whole port DATA_PORT = 0; TRIS_DATA_PORT = 0xff; #else // 4-bit mode #ifdef UPPER // Upper 4-bits of the port DATA_PORT &= 0x0f; TRIS_DATA_PORT |= 0xf0; #else // Lower 4-bits of the port DATA_PORT &= 0xf0; TRIS_DATA_PORT |= 0x0f; #endif #endif TRIS_RS = 0; TRIS_E = 0; RS_PIN = 0; // Register select pin made low E_PIN = 0; // Clock pin made low // Delay for 15ms to allow for LCD Power on reset __delay_ms(15); // Setup interface to LCD #ifdef BIT8 // 8-bit mode interface TRIS_DATA_PORT = 0; // Data port output DATA_PORT = 0b00110000; // Function set cmd(8-bit interface) #else // 4-bit mode interface #ifdef UPPER // Upper nibble interface TRIS_DATA_PORT &= 0x0f; DATA_PORT &= 0x0f; DATA_PORT |= 0b00100000; // Function set cmd(4-bit interface) #else // Lower nibble interface TRIS_DATA_PORT &= 0xf0; DATA_PORT &= 0xf0; DATA_PORT |= 0b00000010; // Function set cmd(4-bit interface) #endif #endif E_PIN = 1; // Clock the cmd in __delay_us(1); E_PIN = 0; // Delay for at least 4.1ms __delay_ms(4); // Setup interface to LCD #ifdef BIT8 // 8-bit interface DATA_PORT = 0b00110000; // Function set cmd(8-bit interface) #else // 4-bit interface #ifdef UPPER // Upper nibble interface DATA_PORT &= 0x0f; // Function set cmd(4-bit interface) DATA_PORT |= 0b00100000; #else // Lower nibble interface DATA_PORT &= 0xf0; // Function set cmd(4-bit interface) DATA_PORT |= 0b00000010; #endif #endif E_PIN = 1; // Clock the cmd in __delay_us(1); E_PIN = 0; // Delay for at least 100us __delay_us(100); #if 1 #ifdef BIT8 DATA_PORT = 0b00110000; // Function set cmd(8-bit interface) #else #ifndef BIT8 #ifdef UPPER // Upper nibble interface DATA_PORT &= 0x0f; // Function set cmd(4-bit interface) DATA_PORT |= 0b00100000; #else // Lower nibble interface DATA_PORT &= 0xf0; // Function set cmd(4-bit interface) DATA_PORT |= 0b00000010; #endif E_PIN = 1; // Clock cmd in __delay_us(1); E_PIN = 0; #endif #endif #endif #ifdef BIT8 // 8-bit interface TRIS_DATA_PORT = 0xff; // Make data port input #else // 4-bit interface #ifdef UPPER // Upper nibble interface TRIS_DATA_PORT |= 0xf0; // Make data nibble input #else // Lower nibble interface TRIS_DATA_PORT |= 0x0f; // Make data nibble input #endif #endif // Set data interface width, # lines, font #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDCommand(XCLD_TYPE); // Function set cmd // Set DD Ram address to 0 #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDCommand(XCLD_TYPE); #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDCommand(DOFF&XLCD_DISPLAY_SETUP); #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDCommand(DON&XLCD_DISPLAY_SETUP); // Clear display #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDCommand(0x01); // Clear display // Set entry mode inc, no shift #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDCommand(SHIFT_CUR_LEFT); // Entry Mode // Set DD Ram address to 0 #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDCommand(0x80); return; } void XLCDCommand(unsigned char cmd) { #if defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif TRIS_RS = 0; #ifdef BIT8 // 8-bit interface TRIS_DATA_PORT = 0; // Data port output DATA_PORT = cmd; // Write command to data port RS_PIN = 0; // for sending a command __delay_us(1); E_PIN = 1; // Clock the command in __delay_us(1); E_PIN = 0; __delay_us(1); TRIS_DATA_PORT = 0xff; // Data port input #else // 4-bit interface #ifdef UPPER // Upper nibble interface TRIS_DATA_PORT &= 0x0f; DATA_PORT &= 0x0f; DATA_PORT |= cmd&0xf0; #else // Lower nibble interface TRIS_DATA_PORT &= 0xf0; DATA_PORT &= 0xf0; DATA_PORT |= (cmd>>4); #endif RS_PIN = 0; __delay_us(1); E_PIN = 1; // Clock command in __delay_us(1); E_PIN = 0; #ifdef UPPER // Upper nibble interface DATA_PORT &= 0x0f; DATA_PORT |= (cmd<<4)&0xf0; #else // Lower nibble interface DATA_PORT &= 0xf0; DATA_PORT |= cmd&0x0f; #endif __delay_us(1); E_PIN = 1; // Clock command in __delay_us(1); E_PIN = 0; #ifdef UPPER // Make data nibble input TRIS_DATA_PORT |= 0xf0; #else TRIS_DATA_PORT |= 0x0f; #endif #endif return; } char XLCDIsBusy(void) { #if !defined(XLCD_READ_BACK) int i = 0; for ( i = 0; i < 500; i++ ) ; return 0; #endif RS_PIN = 0; TRIS_RS = 0; __delay_us(1); E_PIN = 1; // Clock in the command __delay_us(1); #ifdef BIT8 // 8-bit interface if(DATA_PORT&0x80) // Read bit 7 (busy bit) { // If high E_PIN = 0; // Reset clock line return 1; // Return TRUE } else // Bit 7 low { E_PIN = 0; // Reset clock line return 0; // Return FALSE } #else // 4-bit interface #ifdef UPPER // Upper nibble interface if(DATA_PORT&0x80) #else // Lower nibble interface if(DATA_PORT&0x08) #endif { E_PIN = 0; // Reset clock line __delay_us(1); E_PIN = 1; // Clock out other nibble __delay_us(1); E_PIN = 0; return 1; // Return TRUE } else // Busy bit is low { E_PIN = 0; // Reset clock line __delay_us(1); E_PIN = 1; // Clock out other nibble __delay_us(1); E_PIN = 0; return 0; // Return FALSE } #endif } #if defined(XLCD_ENABLE_LCD_READS) unsigned char XLCDGetAddr(void) { char data; // Holds the data retrieved from the LCD TRIS_RS = 0; #if defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif #ifdef BIT8 // 8-bit interface RS_PIN = 0; __delay_us(1); E_PIN = 1; // Clock data out of the LCD controller __delay_us(1); data = DATA_PORT; // Save the data in the register E_PIN = 0; #else // 4-bit interface RS_PIN = 0; __delay_us(1); E_PIN = 1; // Clock data out of the LCD controller __delay_us(1); #ifdef UPPER // Upper nibble interface data = DATA_PORT&0xf0; // Read the nibble into the upper nibble of data #else // Lower nibble interface data = (DATA_PORT<<4)&0xf0; // Read the nibble into the upper nibble of data #endif E_PIN = 0; // Reset the clock __delay_us(1); E_PIN = 1; // Clock out the lower nibble __delay_us(1); #ifdef UPPER // Upper nibble interface data |= (DATA_PORT>>4)&0x0f; // Read the nibble into the lower nibble of data #else // Lower nibble interface data |= DATA_PORT&0x0f; // Read the nibble into the lower nibble of data #endif E_PIN = 0; #endif return (data&0x7f); // Return the address, Mask off the busy bit } #endif #if defined(XLCD_ENABLE_LCD_READS) char XLCDGet(void) { char data; TRIS_RS = 0; #if defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif #ifdef BIT8 // 8-bit interface RS_PIN = 1; // Set the control bits __delay_us(1); E_PIN = 1; // Clock the data out of the LCD __delay_us(1); data = DATA_PORT; // Read the data E_PIN = 0; RS_PIN = 0; // Reset the control bits #else // 4-bit interface RS_PIN = 1; __delay_us(1); E_PIN = 1; // Clock the data out of the LCD __delay_us(1); #ifdef UPPER // Upper nibble interface data = DATA_PORT&0xf0; // Read the upper nibble of data #else // Lower nibble interface data = (DATA_PORT<<4)&0xf0; // read the upper nibble of data #endif E_PIN = 0; // Reset the clock line __delay_us(1); E_PIN = 1; // Clock the next nibble out of the LCD __delay_us(1); #ifdef UPPER // Upper nibble interface data |= (DATA_PORT>>4)&0x0f; // Read the lower nibble of data #else // Lower nibble interface data |= DATA_PORT&0x0f; // Read the lower nibble of data #endif E_PIN = 0; RS_PIN = 0; // Reset the control bits #endif return(data); // Return the data byte } #endif void XLCDPutString(char *string) { char v; while( v = *string ) { #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDPut(v); string++; } } void XLCDPutROMString(const char *string) { char v; while( v = *string ) { #if !defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif XLCDPut(v); string++; } } void XLCDPut(char data) { #if defined(XLCD_IS_BLOCKING) while(XLCDIsBusy()); // Wait if LCD busy #endif TRIS_RS = 0; #ifdef BIT8 // 8-bit interface TRIS_DATA_PORT = 0; // Make port output DATA_PORT = data; // Write data to port RS_PIN = 1; // Set control bits __delay_us(1); E_PIN = 1; // Clock data into LCD __delay_us(1); E_PIN = 0; RS_PIN = 0; // Reset control bits TRIS_DATA_PORT = 0xff; // Make port input #else // 4-bit interface #ifdef UPPER // Upper nibble interface TRIS_DATA_PORT &= 0x0f; DATA_PORT &= 0x0f; DATA_PORT |= data&0xf0; #else // Lower nibble interface TRIS_DATA_PORT &= 0xf0; DATA_PORT &= 0xf0; DATA_PORT |= ((data>>4)&0x0f); #endif RS_PIN = 1; // Set control bits __delay_us(1); E_PIN = 1; // Clock nibble into LCD __delay_us(1); E_PIN = 0; #ifdef UPPER // Upper nibble interface DATA_PORT &= 0x0f; DATA_PORT |= ((data<<4)&0xf0); #else // Lower nibble interface DATA_PORT &= 0xf0; DATA_PORT |= (data&0x0f); #endif __delay_us(1); E_PIN = 1; // Clock nibble into LCD __delay_us(1); E_PIN = 0; #ifdef UPPER // Upper nibble interface TRIS_DATA_PORT |= 0xf0; #else // Lower nibble interface TRIS_DATA_PORT |= 0x0f; #endif #endif return; } void XLCDGoto(unsigned char row, unsigned char col) { switch(row) { case 0 : XLCDCommand(col | 0x80);break; case 1 : XLCDCommand((col + 0x40) | 0x80);break; case 2 : XLCDCommand((col + 0x14) | 0x80);break; case 3 : XLCDCommand((col + 0x54) | 0x80);break; default: break; } }