HD44780 compatible 16x2 character LCD driver with HC595 shiftregister
TriPinLcd.cpp
- Committer:
- k4zuki
- Date:
- 2014-06-20
- Revision:
- 0:9cf8e8a3a8d6
File content as of revision 0:9cf8e8a3a8d6:
#include "mbed.h" #include "TriPinLcd.h" TriPinLcd::TriPinLcd(PinName data, PinName clock, PinName latch): _lcd(data,clock,latch,8) { _displayfunction = LCD_3WIERMODE | LCD_1LINE | LCD_5x8DOTS; begin(16, 1); setCursor(0,0); } /* TriPinLcd(PinName data, PinName clock, PinName latch); void init(); void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); void clear(); void home(); void noDisplay(); void display(); void noBlink(); void blink(); void noCursor(); void cursor(); void scrollDisplayLeft(); void scrollDisplayRight(); void leftToRight(); void rightToLeft(); void autoscroll(); void noAutoscroll(); void createChar(uint8_t, uint8_t[]); void setCursor(uint8_t, uint8_t); virtual int _putc(int value); virtual int _getc(); */ void TriPinLcd::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { if (lines > 1) { _displayfunction |= LCD_2LINE; } _numlines = lines; _currline = 0; // for some 1 line displays you can select a 10 pixel high font if ((dotsize != 0) && (lines == 1)) { _displayfunction |= LCD_5x10DOTS; } // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! // according to datasheet, we need at least 40ms after power rises above 2.7V // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 wait_us(40000); //put the LCD into 4 bit or 8 bit mode if (! (_displayfunction & LCD_8BITMODE)) { // this is according to the hitachi HD44780 datasheet // figure 24, pg 46 // we start in 8bit mode, try to set 4 bit mode _write4bits(0x03); wait_us(4500); // wait min 4.1ms // second try _write4bits(0x03); wait_us(4500); // wait min 4.1ms // third go! _write4bits(0x03); wait_us(150); // finally, set to 4-bit interface _write4bits(0x02); } _command(LCD_FUNCTIONSET | _displayfunction); // turn the display on with no cursor or blinking default _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; display(); // clear it off clear(); // Initialize to default text direction (for romance languages) _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; // set the entry mode _command(LCD_ENTRYMODESET | _displaymode); wait_us(150); } // ********** high level commands, for the user! void TriPinLcd::clear() { _command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero wait_ms(30); // this command takes a long time! } void TriPinLcd::home() { _command(LCD_RETURNHOME); // set cursor position to zero wait_ms(30); // this command takes a long time! } void TriPinLcd::setCursor(uint8_t col, uint8_t row) { int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; if ( row >= _numlines ) { row = _numlines-1; // we count rows starting w/0 } _command(LCD_SETDDRAMADDR | (col + row_offsets[row])); } // Turn the display on/off (quickly) void TriPinLcd::noDisplay() { _displaycontrol &= ~LCD_DISPLAYON; _command(LCD_DISPLAYCONTROL | _displaycontrol); } void TriPinLcd::display() { _displaycontrol |= LCD_DISPLAYON; _command(LCD_DISPLAYCONTROL | _displaycontrol); } // Turns the underline cursor on/off void TriPinLcd::noCursor() { _displaycontrol &= ~LCD_CURSORON; _command(LCD_DISPLAYCONTROL | _displaycontrol); } void TriPinLcd::cursor() { _displaycontrol |= LCD_CURSORON; _command(LCD_DISPLAYCONTROL | _displaycontrol); } // Turn on and off the blinking cursor void TriPinLcd::noBlink() { _displaycontrol &= ~LCD_BLINKON; _command(LCD_DISPLAYCONTROL | _displaycontrol); } void TriPinLcd::blink() { _displaycontrol |= LCD_BLINKON; _command(LCD_DISPLAYCONTROL | _displaycontrol); } // These commands scroll the display without changing the RAM void TriPinLcd::scrollDisplayLeft(void) { _command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); } void TriPinLcd::scrollDisplayRight(void) { _command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); } // This is for text that flows Left to Right void TriPinLcd::leftToRight(void) { _displaymode |= LCD_ENTRYLEFT; _command(LCD_ENTRYMODESET | _displaymode); } // This is for text that flows Right to Left void TriPinLcd::rightToLeft(void) { _displaymode &= ~LCD_ENTRYLEFT; _command(LCD_ENTRYMODESET | _displaymode); } // This will 'right justify' text from the cursor void TriPinLcd::autoscroll(void) { _displaymode |= LCD_ENTRYSHIFTINCREMENT; _command(LCD_ENTRYMODESET | _displaymode); } // This will 'left justify' text from the cursor void TriPinLcd::noAutoscroll(void) { _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; _command(LCD_ENTRYMODESET | _displaymode); } // Allows us to fill the first 8 CGRAM locations // with custom characters void TriPinLcd::createChar(uint8_t location, uint8_t charmap[]) { location &= 0x07; // we only have 8 locations 0-7 _command(LCD_SETCGRAMADDR | (location << 3)); for (int i=0; i<8; i++) { _write(charmap[i]); } } // *********** mid level commands, for sending data/cmds inline void TriPinLcd::_command(uint8_t value) { _send(value, CMND_BYTE); } inline void TriPinLcd::_write(uint8_t value) { _send(value, DATA_BYTE); } int TriPinLcd::_putc(int value) { _send(value, DATA_BYTE); wait_us(1000); return value; } int TriPinLcd::_getc() { return -1; } void TriPinLcd::_send(uint8_t value, uint8_t mode) { int data = value & 0xf0; //send the 4 MSbits (from 8) data |= (mode << SHIFT_RS); // set DI mode data &= ~SHIFT_EN; // set Enable LOW _lcd.write(data); data |= SHIFT_EN; // Set Enable HIGH _lcd.write(data); data &= ~SHIFT_EN; // set Enable LOW _lcd.write(data); data = value << 4; // send the 4 LSbits (from 8) data |= (mode << SHIFT_RS); // set DI mode data &= ~SHIFT_EN; // set Enable LOW _lcd.write(data); data |= SHIFT_EN; // Set Enable HIGH _lcd.write(data); data &= ~SHIFT_EN; // set Enable LOW _lcd.write(data); } void TriPinLcd::_write4bits(uint8_t value) { int data=0; //= value & 0x0f; data = value << 4; //send the first 4 databits (from 8) data &= ~SHIFT_EN; // set Enable LOW _lcd.write(data); data |= SHIFT_EN; // Set Enable HIGH _lcd.write(data); data &= ~SHIFT_EN; // set Enable LOW _lcd.write(data); }