HD44780 compatible 16x2 character LCD driver with HC595 shiftregister
Revision 0:9cf8e8a3a8d6, committed 2014-06-20
- Comitter:
- k4zuki
- Date:
- Fri Jun 20 01:07:06 2014 +0000
- Commit message:
- porting from arduino library
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ShiftOut.h Fri Jun 20 01:07:06 2014 +0000 @@ -0,0 +1,43 @@ +#ifndef SHIFTOUT_H +#define SHIFTOUT_H + +#include <mbed.h> + +class ShiftOut +{ + +public : + + ShiftOut(PinName data, PinName clk, PinName latch, int8_t registerCount = 8) { + dataout = new DigitalOut(data); + clkout = new DigitalOut(clk); + latchout = new DigitalOut(latch); + this->registerCount = registerCount; + } + + ~ShiftOut() { + delete clkout; + delete dataout; + delete latchout; + } + + void write(int8_t data) { + *latchout = 0; + for(int i = registerCount - 1; i >= 0; i--) { + *clkout = 0; + wait_us(0.01); + *dataout = (data & (1 << i)) != 0; // 1 or 0 + *clkout = 1; + wait_us(0.01); + } + *latchout = 1; + } + +private : + DigitalOut *clkout; + DigitalOut *dataout; + DigitalOut *latchout; + int8_t registerCount; +}; + +#endif \ No newline at end of file
--- /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); + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TriPinLcd.h Fri Jun 20 01:07:06 2014 +0000 @@ -0,0 +1,190 @@ +/** this is for HD44780 compatible 16x2 charachter LCD with HC595 by bitbanging +* by Kazuki Yamamoto, or _K4ZUKI_ +*/ + +#ifndef __TRIPINLCD_H__ +#define __TRIPINLCD_H__ + +#include <inttypes.h> +#include "mbed.h" +#include "ShiftOut.h" + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_3WIERMODE 0x20 +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +//#define SHIFT_RS (0x02) //B00000010 +#define SHIFT_RS (0x01) //B00000010 +#define SHIFT_EN (0x08) //B00001000 + +#define DATA_BYTE (1) +#define CMND_BYTE (0) + +/** tripinLcd + * mbed library for HD44780 compatible charachter LCD with HC595 by bitbanging + * + * Example: + * @code +#include "mbed.h" +#include "TriPinLcd.h" + +Timer t; +TriPinLcd lcd(p5,p7,p6);//clk = p7, data = p5, latch = p6 + +int main() +{ + + lcd.begin(16, 2); + lcd.noBlink(); + + lcd.printf("LCD3WIRE mbed"); + t.start(); + while(1) { + lcd.setCursor(0, 1); +// lcd.printf("%.0f", t.read()); + lcd.printf("%d", t.read_us()); + } +} + + * @endcode + */ + +class TriPinLcd : public Stream +{ + +public: + /** Constructor + * @param data data input + * @param clock clock input + * @param latch latches HC595 and sends data to LCD + */ + TriPinLcd(PinName data, PinName clock, PinName latch); + + void begin(uint8_t cols, uint8_t rows, uint8_t dotsize = LCD_5x8DOTS); + + /** + clears display, set cursor position to zero + */ + void clear(); + + /** + set cursor position to zero + */ + void home(); + /** + Turn the display off + */ + void noDisplay(); + /** + Turn the display on + */ + void display(); + /** + Turns off the blinking cursor + */ + void noBlink(); + /** + Turns on the blinking cursor + */ + void blink(); + /** + Turns the underline cursor off + */ + void noCursor(); + /** + Turns the underline cursor on + */ + void cursor(); + /** + scroll the display to left without changing the RAM + */ + void scrollDisplayLeft(); + /** + scroll the display to right without changing the RAM + */ + void scrollDisplayRight(); + /** + This is for text that flows Left to Right + */ + void leftToRight(); + /** + This is for text that flows Right to Left + */ + void rightToLeft(); + /** + This will 'right justify' text from the cursor + */ + void autoscroll(); + /** + This will 'left justify' text from the cursor + */ + void noAutoscroll(); + + /** + Allows us to fill the first 8 CGRAM locations + with custom characters + */ + void createChar(uint8_t, uint8_t[]); + /** + set cursor position to (x=col,y=row); (0,0) is left-top + @param col X position + @param row Y position + */ + void setCursor(uint8_t, uint8_t); + + +private: + ShiftOut::ShiftOut _lcd; + void _write(uint8_t); + void _command(uint8_t); + + virtual int _putc(int value); + virtual int _getc(); + + void _send(uint8_t, uint8_t); + void _write4bits(uint8_t); + + uint8_t _displayfunction; + uint8_t _displaycontrol; + uint8_t _displaymode; + + uint8_t _numlines,_currline; + +}; + +#endif \ No newline at end of file