/* * LcdInit * Description: This initializes the LCD. This must be called before the LCD can * be used. * Thus this function has to be called before calling any other * LCD-interface functions. * The LCD is set to the following specifications: * 8-bit mode, 4-line display, 5x8 font * cursor INCs, display doesn't shift * cursor visible, cursor blinking * * Argument: None * Return: None * * Input: None * Output: LCD * * Operation: * Really just follows standard initialization sequence. See sketch below * * POWER ON * | * | Wait time >40ms * \|/ * FUNCTION SET (RS = 0, RW=0, DB = 0b0011NFXX) [BF cannot be checked b4 this] * | * | Wait time >37us * \|/ * FUNCTION SET (RS = 0, RW=0, DB = 0b0011NFXX) [BF cannot be checked b4 this] * | * | Wait time >37us * \|/ * DISPLAY ON/OFF control (RS = 0, RW=0, DB = 0b00001DCB) * | * | Wait time >37us * \|/ * DISPLAY Clear (RS=0, RW=0, DB=0b00000001) * | * | Wait time >1.52ms * \|/ * Entry Mode Set (RS=0, RW=0, DB=0b0000001{I/D}S) * | * | Wait time >37us * \|/ * Initialization End * * Revision History: * Dec. 16, 2012 Nnoduka Eruchalu Initial Revision */ void LcdInit(void) { LCD_DATA_TRIS = 0x00; /* setup LCD IO ports as outputs */ LCD_E_TRIS = 0; LCD_RW_TRIS = 0; LCD_RS_TRIS = 0; LCD_DATA_LAT = 0; /* clear IO lines*/ CLEAR_RS(); CLEAR_RW(); CLEAR_E(); __delay_ms(40); LCD_DATA_LAT = LCD_FUNC_SET; /* FUNCTION SET, done manually to prevent a */ LCD_STROBE(); /* BF check before next command */ __delay_us(40); LcdCommand(LCD_FUNC_SET); /* FUNCTION SET, again done manually */ LCD_STROBE(); __delay_us(40); LcdCommand(LCD_ON); /* DISPLAY ON/OFF control: Turn display on */ __delay_us(40); LcdCommand(LCD_CLEAR); /* DISPLAY Clear */ __delay_ms(2); LcdCommand(LCD_ENTRY_MD); /* ENTRY mode set */ GenSpecChars(); /* Now create some special characters */ }
/* * LcdWaitBF * Description: This procedure simply loops until the LCD is not busy. * This clears the RS bit. * * Argument: None * Return: None * * Input: LCD's Busy Flag * Output: None * * Operation: Keep on looping and reading the LCD busy flag. Exit when it * indicates the LCD is not busy. * * Revision History: * Dec. 16, 2012 Nnoduka Eruchalu Initial Revision */ void LcdWaitBF(void) { unsigned char busy, status=0x00; LCD_DATA_TRIS = 0xFF; /* when reading a port change it to an input */ CLEAR_RS(); /* prepare to read BF and Address Counter */ SET_RW(); /* and put the LCD in read mode */ do { SET_E(); /* during reads the E has to be active */ __delay_us(0.5); /* wait tPW for data to become available */ status = LCD_DATA_PORT; /* read in value on data lines */ busy = status & 0x80; /* busy flag is highest status bit */ __delay_us(0.5); CLEAR_E(); /* pull E low for at least tC-tPW */ __delay_us(1); } while(busy); /* put the LCD in write mode */ CLEAR_RW(); /* in write mode when R/W\ is cleared */ LCD_DATA_TRIS = 0x00; /* and the I/O pins are set as outputs */ }
/* * LcdCommand * Description: This procedure simply writes a command byte to the LCD. * It does not return until the LCD's busy flag is cleared. * * Argument: c: command byte * Return: None * * Input: None * Output: LCD * * Operation: Send the byte, then wait for the BF to be cleared. * * Revision History: * Dec. 16, 2012 Nnoduka Eruchalu Initial Revision */ void LcdCommand(unsigned char c) { LCD_DATA_LAT = c; /* put data on output port */ CLEAR_RS(); /* RS = 0: Command */ CLEAR_RW(); /* R/W = 0: Write */ LCD_STROBE(); LcdWaitBF(); /* dont exit until the LCD is no longer busy */ }
void LCDInit(uint8_t style) { /***************************************************************** This function Initializes the lcd module must be called before calling lcd related functions Arguments: style = LS_BLINK,LS_ULINE(can be "OR"ed for combination) LS_BLINK : The cursor is blinking type LS_ULINE : Cursor is "underline" type else "block" type LS_NONE : No visible cursor *****************************************************************/ //After power on Wait for LCD to Initialize __delay_ms(30); //Set IO Ports LCD_DATA_TRIS&=(~(0x0F<<LCD_DATA_POS)); //Output LCD_E_TRIS=0; //Output LCD_RS_TRIS=0; //Output LCD_RW_TRIS=0; //Output LCD_DATA_PORT&=(~(0x0F<<LCD_DATA_POS));//Clear data port CLEAR_E(); CLEAR_RW(); CLEAR_RS(); //Set 4-bit mode __delay_us(0.5); //tAS SET_E(); LCD_DATA_PORT|=((0b00000010)<<LCD_DATA_POS); //[B] To transfer 0b00100000 i was using LCD_DATA_PORT|=0b00100000 __delay_us(1); CLEAR_E(); __delay_us(1); //Wait for LCD to execute the Functionset Command LCDBusyLoop(); //[B] Forgot this delay //Now the LCD is in 4-bit mode LCDCmd(0b00101000); //function set 4-bit,2 line 5x7 dot format LCDCmd(0b00001100|style); //Display On /* Custom Char */ LCDCmd(0b01000000); uint8_t __i; for(__i=0;__i<sizeof(__cgram);__i++) LCDData(__cgram[__i]); }
void LCDBusyLoop() { //This function waits till lcd is BUSY uint8_t busy,status=0x00,temp; //Change Port to input type because we are reading data LCD_DATA_TRIS|=(0x0f<<LCD_DATA_POS); //change LCD mode SET_RW(); //Read mode CLEAR_RS(); //Read status //Let the RW/RS lines stabilize __delay_us(0.5); //tAS do { SET_E(); //Wait tDA for data to become available __delay_us(0.5); status=(LCD_DATA_PORT>>LCD_DATA_POS); status=status<<4; __delay_us(0.5); //Pull E low CLEAR_E(); __delay_us(1); //tEL SET_E(); __delay_us(0.5); temp=(LCD_DATA_PORT>>LCD_DATA_POS); temp&=0x0F; status=status|temp; busy=status & 0b10000000; __delay_us(0.5); CLEAR_E(); __delay_us(1); //tEL }while(busy); CLEAR_RW(); //write mode //Change Port to output LCD_DATA_TRIS&=(~(0x0F<<LCD_DATA_POS)); }
void LCDByte(uint8_t c,uint8_t isdata) { //Sends a byte to the LCD in 4bit mode //cmd=0 for data //cmd=1 for command //NOTE: THIS FUNCTION RETURS ONLY WHEN LCD HAS PROCESSED THE COMMAND uint8_t hn,ln; //Nibbles uint8_t temp; hn=c>>4; ln=(c & 0x0F); if(isdata==0) CLEAR_RS(); else SET_RS(); _delay_us(0.500); //tAS SET_E(); //Send high nibble temp=(LCD_DATA_PORT & (~(0X0F<<LCD_DATA_POS)))|((hn<<LCD_DATA_POS)); LCD_DATA_PORT=temp; _delay_us(1); //tEH //Now data lines are stable pull E low for transmission CLEAR_E(); _delay_us(1); //Send the lower nibble SET_E(); temp=(LCD_DATA_PORT & (~(0X0F<<LCD_DATA_POS)))|((ln<<LCD_DATA_POS)); LCD_DATA_PORT=temp; _delay_us(1); //tEH //SEND CLEAR_E(); _delay_us(1); //tEL LCDBusyLoop(); }
void LCDBusyLoop() { //This function waits till lcd is BUSY uint8_t busy,status=0x00,temp; //Change Port to input type because we are reading data LCD_DATA_DDR&=0xF0; //change LCD mode SET_RW(); //Read mode CLEAR_RS(); //Read status //Let the RW/RS lines stabilize _delay_us(HALF); //tAS do { SET_E(); //Wait tDA for data to become available _delay_us(HALF); status=LCD_DATA_PIN; status=status<<4; _delay_us(HALF); //Pull E low CLEAR_E(); _delay_us(ONE); //tEL SET_E(); _delay_us(HALF); temp=LCD_DATA_PIN; temp&=0x0F; status=status|temp; busy=status & 0b10000000; _delay_us(HALF); CLEAR_E(); _delay_us(ONE); //tEL } while(busy); CLEAR_RW(); //write mode //Change Port to output LCD_DATA_DDR|=0x0F; }
void LCDInit(uint8_t style) { /***************************************************************** This function Initializes the lcd module must be called before calling lcd related functions Arguments: style = LS_BLINK,LS_ULINE(can be "OR"ed for combination) LS_BLINK :The cursor is blinking type LS_ULINE :Cursor is "underline" type else "block" type *****************************************************************/ //After power on Wait for LCD to Initialize _delay_ms(30); //Set IO Ports LCD_DATA_DDR|=(0x0F<<LCD_DATA_POS); LCD_E_DDR|=(1<<LCD_E_POS); LCD_RS_DDR|=(1<<LCD_RS_POS); LCD_RW_DDR|=(1<<LCD_RW_POS); LCD_DATA_PORT&=(~(0x0F<<LCD_DATA_POS)); CLEAR_E(); CLEAR_RW(); CLEAR_RS(); //Set 4-bit mode _delay_us(0.3); //tAS SET_E(); LCD_DATA_PORT|=((0b00000010)<<LCD_DATA_POS); //[B] To transfer 0b00100000 i was using LCD_DATA_PORT|=0b00100000 _delay_us(1); CLEAR_E(); _delay_us(1); //Wait for LCD to execute the Functionset Command LCDBusyLoop(); //[B] Forgot this delay //Now the LCD is in 4-bit mode LCDCmd(0b00101000); //function set 4-bit,2 line 5x7 dot format LCDCmd(0b00001100|style); //Display On }
void LCDInit(uint8_t style) { __delay_ms(30); //Set IO Ports LCD_DATA_TRIS&=(~(0x0F<<LCD_DATA_POS)); //Output LCD_E_TRIS=0; //Output LCD_RS_TRIS=0; //Output LCD_RW_TRIS=0; //Output LCD_DATA_PORT&=(~(0x0F<<LCD_DATA_POS));//Clear data port CLEAR_E(); CLEAR_RW(); CLEAR_RS(); //Set 4-bit mode __delay_us(0.5); //tAS SET_E(); LCD_DATA_PORT|=((0b00000010)<<LCD_DATA_POS); //[B] To transfer 0b00100000 i was using LCD_DATA_PORT|=0b00100000 __delay_us(1); CLEAR_E(); __delay_us(1); //Wait for LCD to execute the Functionset Command LCDBusyLoop(); //[B] Forgot this delay //Now the LCD is in 4-bit mode LCDCmd(0b00101000); //function set 4-bit,2 line 5x7 dot format LCDCmd(0b00001100|style); //Display On /* Custom Char */ LCDCmd(0b01000000); uint8_t __i; for(__i=0;__i<sizeof(__cgram);__i++) LCDData(__cgram[__i]); }