HD44780 compatible 16x2 character LCD driver with HC595 shiftregister
Diff: TriPinLcd.cpp
- Revision:
- 0:9cf8e8a3a8d6
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TriPinLcd.cpp Fri Jun 20 01:07:06 2014 +0000 @@ -0,0 +1,269 @@ + +#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); + +}