//reset LCD to 8bit mode void HD44780_Reset(void){ //set initial pin states //we use open drain with pullup resistors to interface the LCD at 5volts //all I/O should be to ground, low to start //all to low for ground on TRIS clear PORTB &=(~0b1111); //clear B bits (B765) PORTD &=(~0b11); //clear D bits (RS/RW) PORTE &=(~0b111111); //clear the E bits (E01234) //all start output/low, 0 on HD44780 pins TRISB &=(~0b1111); //clear B bits (B765) TRISD &=(~0b11); //clear D bits (RS/RW) TRISE &=(~0b111111); //clear the E bits (E01234) //# Wait more than 15 msecs after power is applied. delayMS(15); //# Write 0x30 to LCD and wait 5 msecs for the instruction to complete HD44780_WriteByte(COMMAND, 0x30); delayMS(5); //# Write 0x30 to LCD and wait 160 usecs for instruction to complete HD44780_WriteByte(COMMAND, 0x30); delayUS(160); //# Write 0x30 AGAIN to LCD and wait 160 usecs (or poll the Busy Flag) HD44780_WriteByte(COMMAND, 0x30); delayUS(160); }
//write this byte value to LCD as ascii text //output an 8bit/byte decimal value to the LCD void LCD_WriteByteVal(unsigned char c){ unsigned char d,j,m,k=0; d=100; for(j=0; j<2; j++){ m=c/d; if(k || m){ HD44780_WriteByte(DATA, m + '0'); c = c - (m*d); k=1; } d/=10; } HD44780_WriteByte(DATA, c + '0'); }
//blink and underline share a command byte, //we need to remember them so we can keep the correct setting on one when we update the other void LCD_BlinkCursor(unsigned char blink){ LCDdisplayControl.blink=blink; //store the setting blink=CMD_DISPLAYCONTROL + DISPLAYON; //setup the command if(LCDdisplayControl.cursor) blink+=CURSORON; //set cursor bit if(LCDdisplayControl.blink) blink+=BLINKON; //set blink bit HD44780_WriteByte(COMMAND, blink); //send command delayUS(40);//delay }
//same as LCD_BlinkCursor(), different bit void LCD_UnderlineCursor(unsigned char cursor){ LCDdisplayControl.cursor=cursor; cursor=CMD_DISPLAYCONTROL + DISPLAYON; if(LCDdisplayControl.cursor) cursor+=CURSORON; if(LCDdisplayControl.blink) cursor+=BLINKON; HD44780_WriteByte(COMMAND, cursor); delayUS(40);//delay }
//initialize LCD with standard features void HD44780_Init(void){ //Function set HD44780_WriteByte(COMMAND, (CMD_FUNCTIONSET + DATAWIDTH8 + FONT5X7 + DISPLAYLINES2)); //0x28, 0b101000 delayMS(15);//delay 15ms //Turn display off HD44780_WriteByte(COMMAND, CMD_DISPLAYCONTROL + DISPLAYOFF + CURSOROFF + BLINKOFF);//0x08, 0b1000 delayMS(15);//delay 15ms //Clear LCD and return home HD44780_WriteByte(COMMAND, CMD_CLEARDISPLAY); delayMS(15);//delay 15ms //Turn on display, turn off cursor and blink HD44780_WriteByte(COMMAND, CMD_DISPLAYCONTROL + DISPLAYON + CURSOROFF + BLINKOFF); // 0x0f, 0b1111 delayMS(15);//delay 15ms LCDdisplayControl.cursor=CURSOROFF; LCDdisplayControl.blink=BLINKOFF; }
// //functions // //reset LCD to 8bit mode void HD44780_Reset(void){ //set initial pin states //we use open drain with pullup resistors to interface the LCD at 5volts //all I/O should be to ground, low to start //all to low for ground on TRIS clear LCD_PIN_SETUP(); //# Wait more than 15 msecs after power is applied. delayMS(15); //# Write 0x30 to LCD and wait 5 msecs for the instruction to complete HD44780_WriteByte(COMMAND, 0x30); delayMS(5); //# Write 0x30 to LCD and wait 160 usecs for instruction to complete HD44780_WriteByte(COMMAND, 0x30); delayUS(160); //# Write 0x30 AGAIN to LCD and wait 160 usecs (or poll the Busy Flag) HD44780_WriteByte(COMMAND, 0x30); delayUS(160); }
//set position, with compensation for actual LCD layout //this is used to align character 21 with line 2 postion 1, instead of the default line 3. void LCD_CursorPosition(unsigned char c){ cursorPosition=c; //calculate actual cursor position value if(c>=1 && c<=20){ c--; }else if (c>=21 && c<=40){ c+=43; }else if (c>=41 && c<=60){ c-=21; }else if (c>=61){ c+=23; } HD44780_WriteByte(COMMAND, CMD_SETDDRAMADDR | c); }
//this function sends text to the LCD, with compensation for non-linearity //write a character to the LCD with wrap to the next line void LCD_WriteChar(char c){ HD44780_WriteByte(DATA, c); //wrap the cursor at the end of the line //1-20, line 1, 0x00-0x13 //21-40, line 2, 0x40-0x53 //41-60, line 3, 0x14-0x27 (20) //61-80, line 4, 0x54-0x67 cursorPosition++; if (cursorPosition==21 || cursorPosition==41 || cursorPosition==61){ LCD_CursorPosition(cursorPosition); }else if (cursorPosition==81){ cursorPosition=0; LCD_CursorPosition(cursorPosition); } }
void LCD_WriteINT(u16 value) { unsigned int temp,dvd=10000; char i=0,k=0; temp = value; for (i=0;i<5;i++) { temp=value/dvd; if(temp)k++; if(k)HD44780_WriteByte(DATA, temp + '0'); value = value - (temp*dvd); dvd/=10; } }
void HD44780_WriteCommand(char dat) { HD44780_WriteByte(HD44780_REGISTER_COMMAND, dat); delay2MiliSecond(); }
//write a string to the LCD //curser position is not tracked.... void LCD_WriteString(char *s) //other processors { char c; while((c = *s++)) HD44780_WriteByte(DATA, c); }
//return cursor to home void LCD_Home(void){ HD44780_WriteByte(COMMAND,CMD_RETURNHOME); cursorPosition=1; //cursor is positioned at home delayMS(2);//delay 15ms }
//Clear LCD and return home void LCD_Clear(void){ HD44780_WriteByte(COMMAND, CMD_CLEARDISPLAY); cursorPosition=1; //cursor is positioned at home delayMS(15);//delay 15ms }
void HD44780_WriteData(char dat) { HD44780_WriteByte(HD44780_REGISTER_DATA, dat); delay50MicroSecond(); }
//no cursor compensation, for CGRAM void LCD_WriteRAM(char c){ HD44780_WriteByte(DATA, c); delayUS(46); }
//write to character generator RAM void LCD_WriteCGRAM(char c){ c*=8; HD44780_WriteByte(COMMAND, CMD_SETCGRAMADDR + c); delayUS(46); }
void LCD_WriteString(rom char *s) //for 18F { char c; while((c = *s++)) HD44780_WriteByte(DATA, c); }