HD44780 compatible 16x2 character LCD driver with HC595 shiftregister

Dependents:   mbed_3pinLCD

Revision:
0:9cf8e8a3a8d6
diff -r 000000000000 -r 9cf8e8a3a8d6 TriPinLcd.cpp
--- /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);
+
+}