HD44780 compatible 16x2 character LCD driver with HC595 shiftregister

Dependents:   mbed_3pinLCD

Committer:
k4zuki
Date:
Fri Jun 20 01:07:06 2014 +0000
Revision:
0:9cf8e8a3a8d6
porting from arduino library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
k4zuki 0:9cf8e8a3a8d6 1
k4zuki 0:9cf8e8a3a8d6 2 #include "mbed.h"
k4zuki 0:9cf8e8a3a8d6 3 #include "TriPinLcd.h"
k4zuki 0:9cf8e8a3a8d6 4
k4zuki 0:9cf8e8a3a8d6 5 TriPinLcd::TriPinLcd(PinName data, PinName clock, PinName latch): _lcd(data,clock,latch,8)
k4zuki 0:9cf8e8a3a8d6 6 {
k4zuki 0:9cf8e8a3a8d6 7
k4zuki 0:9cf8e8a3a8d6 8 _displayfunction = LCD_3WIERMODE | LCD_1LINE | LCD_5x8DOTS;
k4zuki 0:9cf8e8a3a8d6 9
k4zuki 0:9cf8e8a3a8d6 10 begin(16, 1);
k4zuki 0:9cf8e8a3a8d6 11 setCursor(0,0);
k4zuki 0:9cf8e8a3a8d6 12
k4zuki 0:9cf8e8a3a8d6 13 }
k4zuki 0:9cf8e8a3a8d6 14 /*
k4zuki 0:9cf8e8a3a8d6 15 TriPinLcd(PinName data, PinName clock, PinName latch);
k4zuki 0:9cf8e8a3a8d6 16
k4zuki 0:9cf8e8a3a8d6 17 void init();
k4zuki 0:9cf8e8a3a8d6 18
k4zuki 0:9cf8e8a3a8d6 19 void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
k4zuki 0:9cf8e8a3a8d6 20 void clear();
k4zuki 0:9cf8e8a3a8d6 21 void home();
k4zuki 0:9cf8e8a3a8d6 22
k4zuki 0:9cf8e8a3a8d6 23 void noDisplay();
k4zuki 0:9cf8e8a3a8d6 24 void display();
k4zuki 0:9cf8e8a3a8d6 25 void noBlink();
k4zuki 0:9cf8e8a3a8d6 26 void blink();
k4zuki 0:9cf8e8a3a8d6 27 void noCursor();
k4zuki 0:9cf8e8a3a8d6 28 void cursor();
k4zuki 0:9cf8e8a3a8d6 29 void scrollDisplayLeft();
k4zuki 0:9cf8e8a3a8d6 30 void scrollDisplayRight();
k4zuki 0:9cf8e8a3a8d6 31 void leftToRight();
k4zuki 0:9cf8e8a3a8d6 32 void rightToLeft();
k4zuki 0:9cf8e8a3a8d6 33 void autoscroll();
k4zuki 0:9cf8e8a3a8d6 34 void noAutoscroll();
k4zuki 0:9cf8e8a3a8d6 35
k4zuki 0:9cf8e8a3a8d6 36 void createChar(uint8_t, uint8_t[]);
k4zuki 0:9cf8e8a3a8d6 37 void setCursor(uint8_t, uint8_t);
k4zuki 0:9cf8e8a3a8d6 38
k4zuki 0:9cf8e8a3a8d6 39 virtual int _putc(int value);
k4zuki 0:9cf8e8a3a8d6 40 virtual int _getc();
k4zuki 0:9cf8e8a3a8d6 41
k4zuki 0:9cf8e8a3a8d6 42 */
k4zuki 0:9cf8e8a3a8d6 43
k4zuki 0:9cf8e8a3a8d6 44 void TriPinLcd::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
k4zuki 0:9cf8e8a3a8d6 45 {
k4zuki 0:9cf8e8a3a8d6 46 if (lines > 1) {
k4zuki 0:9cf8e8a3a8d6 47 _displayfunction |= LCD_2LINE;
k4zuki 0:9cf8e8a3a8d6 48 }
k4zuki 0:9cf8e8a3a8d6 49 _numlines = lines;
k4zuki 0:9cf8e8a3a8d6 50 _currline = 0;
k4zuki 0:9cf8e8a3a8d6 51
k4zuki 0:9cf8e8a3a8d6 52 // for some 1 line displays you can select a 10 pixel high font
k4zuki 0:9cf8e8a3a8d6 53 if ((dotsize != 0) && (lines == 1)) {
k4zuki 0:9cf8e8a3a8d6 54 _displayfunction |= LCD_5x10DOTS;
k4zuki 0:9cf8e8a3a8d6 55 }
k4zuki 0:9cf8e8a3a8d6 56
k4zuki 0:9cf8e8a3a8d6 57 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
k4zuki 0:9cf8e8a3a8d6 58 // according to datasheet, we need at least 40ms after power rises above 2.7V
k4zuki 0:9cf8e8a3a8d6 59 // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
k4zuki 0:9cf8e8a3a8d6 60 wait_us(40000);
k4zuki 0:9cf8e8a3a8d6 61
k4zuki 0:9cf8e8a3a8d6 62 //put the LCD into 4 bit or 8 bit mode
k4zuki 0:9cf8e8a3a8d6 63 if (! (_displayfunction & LCD_8BITMODE)) {
k4zuki 0:9cf8e8a3a8d6 64 // this is according to the hitachi HD44780 datasheet
k4zuki 0:9cf8e8a3a8d6 65 // figure 24, pg 46
k4zuki 0:9cf8e8a3a8d6 66
k4zuki 0:9cf8e8a3a8d6 67 // we start in 8bit mode, try to set 4 bit mode
k4zuki 0:9cf8e8a3a8d6 68 _write4bits(0x03);
k4zuki 0:9cf8e8a3a8d6 69 wait_us(4500); // wait min 4.1ms
k4zuki 0:9cf8e8a3a8d6 70
k4zuki 0:9cf8e8a3a8d6 71 // second try
k4zuki 0:9cf8e8a3a8d6 72 _write4bits(0x03);
k4zuki 0:9cf8e8a3a8d6 73 wait_us(4500); // wait min 4.1ms
k4zuki 0:9cf8e8a3a8d6 74
k4zuki 0:9cf8e8a3a8d6 75 // third go!
k4zuki 0:9cf8e8a3a8d6 76 _write4bits(0x03);
k4zuki 0:9cf8e8a3a8d6 77 wait_us(150);
k4zuki 0:9cf8e8a3a8d6 78
k4zuki 0:9cf8e8a3a8d6 79 // finally, set to 4-bit interface
k4zuki 0:9cf8e8a3a8d6 80 _write4bits(0x02);
k4zuki 0:9cf8e8a3a8d6 81 }
k4zuki 0:9cf8e8a3a8d6 82 _command(LCD_FUNCTIONSET | _displayfunction);
k4zuki 0:9cf8e8a3a8d6 83
k4zuki 0:9cf8e8a3a8d6 84 // turn the display on with no cursor or blinking default
k4zuki 0:9cf8e8a3a8d6 85 _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
k4zuki 0:9cf8e8a3a8d6 86 display();
k4zuki 0:9cf8e8a3a8d6 87
k4zuki 0:9cf8e8a3a8d6 88 // clear it off
k4zuki 0:9cf8e8a3a8d6 89 clear();
k4zuki 0:9cf8e8a3a8d6 90
k4zuki 0:9cf8e8a3a8d6 91 // Initialize to default text direction (for romance languages)
k4zuki 0:9cf8e8a3a8d6 92 _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
k4zuki 0:9cf8e8a3a8d6 93 // set the entry mode
k4zuki 0:9cf8e8a3a8d6 94 _command(LCD_ENTRYMODESET | _displaymode);
k4zuki 0:9cf8e8a3a8d6 95 wait_us(150);
k4zuki 0:9cf8e8a3a8d6 96 }
k4zuki 0:9cf8e8a3a8d6 97
k4zuki 0:9cf8e8a3a8d6 98 // ********** high level commands, for the user!
k4zuki 0:9cf8e8a3a8d6 99 void TriPinLcd::clear()
k4zuki 0:9cf8e8a3a8d6 100 {
k4zuki 0:9cf8e8a3a8d6 101 _command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
k4zuki 0:9cf8e8a3a8d6 102 wait_ms(30); // this command takes a long time!
k4zuki 0:9cf8e8a3a8d6 103 }
k4zuki 0:9cf8e8a3a8d6 104
k4zuki 0:9cf8e8a3a8d6 105 void TriPinLcd::home()
k4zuki 0:9cf8e8a3a8d6 106 {
k4zuki 0:9cf8e8a3a8d6 107 _command(LCD_RETURNHOME); // set cursor position to zero
k4zuki 0:9cf8e8a3a8d6 108 wait_ms(30); // this command takes a long time!
k4zuki 0:9cf8e8a3a8d6 109 }
k4zuki 0:9cf8e8a3a8d6 110
k4zuki 0:9cf8e8a3a8d6 111 void TriPinLcd::setCursor(uint8_t col, uint8_t row)
k4zuki 0:9cf8e8a3a8d6 112 {
k4zuki 0:9cf8e8a3a8d6 113 int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
k4zuki 0:9cf8e8a3a8d6 114 if ( row >= _numlines ) {
k4zuki 0:9cf8e8a3a8d6 115 row = _numlines-1; // we count rows starting w/0
k4zuki 0:9cf8e8a3a8d6 116 }
k4zuki 0:9cf8e8a3a8d6 117
k4zuki 0:9cf8e8a3a8d6 118 _command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
k4zuki 0:9cf8e8a3a8d6 119 }
k4zuki 0:9cf8e8a3a8d6 120
k4zuki 0:9cf8e8a3a8d6 121 // Turn the display on/off (quickly)
k4zuki 0:9cf8e8a3a8d6 122 void TriPinLcd::noDisplay()
k4zuki 0:9cf8e8a3a8d6 123 {
k4zuki 0:9cf8e8a3a8d6 124 _displaycontrol &= ~LCD_DISPLAYON;
k4zuki 0:9cf8e8a3a8d6 125 _command(LCD_DISPLAYCONTROL | _displaycontrol);
k4zuki 0:9cf8e8a3a8d6 126 }
k4zuki 0:9cf8e8a3a8d6 127 void TriPinLcd::display()
k4zuki 0:9cf8e8a3a8d6 128 {
k4zuki 0:9cf8e8a3a8d6 129 _displaycontrol |= LCD_DISPLAYON;
k4zuki 0:9cf8e8a3a8d6 130 _command(LCD_DISPLAYCONTROL | _displaycontrol);
k4zuki 0:9cf8e8a3a8d6 131 }
k4zuki 0:9cf8e8a3a8d6 132
k4zuki 0:9cf8e8a3a8d6 133 // Turns the underline cursor on/off
k4zuki 0:9cf8e8a3a8d6 134 void TriPinLcd::noCursor()
k4zuki 0:9cf8e8a3a8d6 135 {
k4zuki 0:9cf8e8a3a8d6 136 _displaycontrol &= ~LCD_CURSORON;
k4zuki 0:9cf8e8a3a8d6 137 _command(LCD_DISPLAYCONTROL | _displaycontrol);
k4zuki 0:9cf8e8a3a8d6 138 }
k4zuki 0:9cf8e8a3a8d6 139 void TriPinLcd::cursor()
k4zuki 0:9cf8e8a3a8d6 140 {
k4zuki 0:9cf8e8a3a8d6 141 _displaycontrol |= LCD_CURSORON;
k4zuki 0:9cf8e8a3a8d6 142 _command(LCD_DISPLAYCONTROL | _displaycontrol);
k4zuki 0:9cf8e8a3a8d6 143 }
k4zuki 0:9cf8e8a3a8d6 144
k4zuki 0:9cf8e8a3a8d6 145 // Turn on and off the blinking cursor
k4zuki 0:9cf8e8a3a8d6 146 void TriPinLcd::noBlink()
k4zuki 0:9cf8e8a3a8d6 147 {
k4zuki 0:9cf8e8a3a8d6 148 _displaycontrol &= ~LCD_BLINKON;
k4zuki 0:9cf8e8a3a8d6 149 _command(LCD_DISPLAYCONTROL | _displaycontrol);
k4zuki 0:9cf8e8a3a8d6 150 }
k4zuki 0:9cf8e8a3a8d6 151 void TriPinLcd::blink()
k4zuki 0:9cf8e8a3a8d6 152 {
k4zuki 0:9cf8e8a3a8d6 153 _displaycontrol |= LCD_BLINKON;
k4zuki 0:9cf8e8a3a8d6 154 _command(LCD_DISPLAYCONTROL | _displaycontrol);
k4zuki 0:9cf8e8a3a8d6 155 }
k4zuki 0:9cf8e8a3a8d6 156
k4zuki 0:9cf8e8a3a8d6 157 // These commands scroll the display without changing the RAM
k4zuki 0:9cf8e8a3a8d6 158 void TriPinLcd::scrollDisplayLeft(void)
k4zuki 0:9cf8e8a3a8d6 159 {
k4zuki 0:9cf8e8a3a8d6 160 _command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
k4zuki 0:9cf8e8a3a8d6 161 }
k4zuki 0:9cf8e8a3a8d6 162 void TriPinLcd::scrollDisplayRight(void)
k4zuki 0:9cf8e8a3a8d6 163 {
k4zuki 0:9cf8e8a3a8d6 164 _command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
k4zuki 0:9cf8e8a3a8d6 165 }
k4zuki 0:9cf8e8a3a8d6 166
k4zuki 0:9cf8e8a3a8d6 167 // This is for text that flows Left to Right
k4zuki 0:9cf8e8a3a8d6 168 void TriPinLcd::leftToRight(void)
k4zuki 0:9cf8e8a3a8d6 169 {
k4zuki 0:9cf8e8a3a8d6 170 _displaymode |= LCD_ENTRYLEFT;
k4zuki 0:9cf8e8a3a8d6 171 _command(LCD_ENTRYMODESET | _displaymode);
k4zuki 0:9cf8e8a3a8d6 172 }
k4zuki 0:9cf8e8a3a8d6 173
k4zuki 0:9cf8e8a3a8d6 174 // This is for text that flows Right to Left
k4zuki 0:9cf8e8a3a8d6 175 void TriPinLcd::rightToLeft(void)
k4zuki 0:9cf8e8a3a8d6 176 {
k4zuki 0:9cf8e8a3a8d6 177 _displaymode &= ~LCD_ENTRYLEFT;
k4zuki 0:9cf8e8a3a8d6 178 _command(LCD_ENTRYMODESET | _displaymode);
k4zuki 0:9cf8e8a3a8d6 179 }
k4zuki 0:9cf8e8a3a8d6 180
k4zuki 0:9cf8e8a3a8d6 181 // This will 'right justify' text from the cursor
k4zuki 0:9cf8e8a3a8d6 182 void TriPinLcd::autoscroll(void)
k4zuki 0:9cf8e8a3a8d6 183 {
k4zuki 0:9cf8e8a3a8d6 184 _displaymode |= LCD_ENTRYSHIFTINCREMENT;
k4zuki 0:9cf8e8a3a8d6 185 _command(LCD_ENTRYMODESET | _displaymode);
k4zuki 0:9cf8e8a3a8d6 186 }
k4zuki 0:9cf8e8a3a8d6 187
k4zuki 0:9cf8e8a3a8d6 188 // This will 'left justify' text from the cursor
k4zuki 0:9cf8e8a3a8d6 189 void TriPinLcd::noAutoscroll(void)
k4zuki 0:9cf8e8a3a8d6 190 {
k4zuki 0:9cf8e8a3a8d6 191 _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
k4zuki 0:9cf8e8a3a8d6 192 _command(LCD_ENTRYMODESET | _displaymode);
k4zuki 0:9cf8e8a3a8d6 193 }
k4zuki 0:9cf8e8a3a8d6 194
k4zuki 0:9cf8e8a3a8d6 195 // Allows us to fill the first 8 CGRAM locations
k4zuki 0:9cf8e8a3a8d6 196 // with custom characters
k4zuki 0:9cf8e8a3a8d6 197 void TriPinLcd::createChar(uint8_t location, uint8_t charmap[])
k4zuki 0:9cf8e8a3a8d6 198 {
k4zuki 0:9cf8e8a3a8d6 199 location &= 0x07; // we only have 8 locations 0-7
k4zuki 0:9cf8e8a3a8d6 200 _command(LCD_SETCGRAMADDR | (location << 3));
k4zuki 0:9cf8e8a3a8d6 201 for (int i=0; i<8; i++) {
k4zuki 0:9cf8e8a3a8d6 202 _write(charmap[i]);
k4zuki 0:9cf8e8a3a8d6 203 }
k4zuki 0:9cf8e8a3a8d6 204 }
k4zuki 0:9cf8e8a3a8d6 205
k4zuki 0:9cf8e8a3a8d6 206 // *********** mid level commands, for sending data/cmds
k4zuki 0:9cf8e8a3a8d6 207
k4zuki 0:9cf8e8a3a8d6 208 inline void TriPinLcd::_command(uint8_t value)
k4zuki 0:9cf8e8a3a8d6 209 {
k4zuki 0:9cf8e8a3a8d6 210 _send(value, CMND_BYTE);
k4zuki 0:9cf8e8a3a8d6 211 }
k4zuki 0:9cf8e8a3a8d6 212
k4zuki 0:9cf8e8a3a8d6 213 inline void TriPinLcd::_write(uint8_t value)
k4zuki 0:9cf8e8a3a8d6 214 {
k4zuki 0:9cf8e8a3a8d6 215 _send(value, DATA_BYTE);
k4zuki 0:9cf8e8a3a8d6 216 }
k4zuki 0:9cf8e8a3a8d6 217
k4zuki 0:9cf8e8a3a8d6 218 int TriPinLcd::_putc(int value)
k4zuki 0:9cf8e8a3a8d6 219 {
k4zuki 0:9cf8e8a3a8d6 220 _send(value, DATA_BYTE);
k4zuki 0:9cf8e8a3a8d6 221 wait_us(1000);
k4zuki 0:9cf8e8a3a8d6 222 return value;
k4zuki 0:9cf8e8a3a8d6 223 }
k4zuki 0:9cf8e8a3a8d6 224
k4zuki 0:9cf8e8a3a8d6 225 int TriPinLcd::_getc()
k4zuki 0:9cf8e8a3a8d6 226 {
k4zuki 0:9cf8e8a3a8d6 227 return -1;
k4zuki 0:9cf8e8a3a8d6 228 }
k4zuki 0:9cf8e8a3a8d6 229
k4zuki 0:9cf8e8a3a8d6 230
k4zuki 0:9cf8e8a3a8d6 231 void TriPinLcd::_send(uint8_t value, uint8_t mode)
k4zuki 0:9cf8e8a3a8d6 232 {
k4zuki 0:9cf8e8a3a8d6 233
k4zuki 0:9cf8e8a3a8d6 234 int data = value & 0xf0; //send the 4 MSbits (from 8)
k4zuki 0:9cf8e8a3a8d6 235
k4zuki 0:9cf8e8a3a8d6 236 data |= (mode << SHIFT_RS); // set DI mode
k4zuki 0:9cf8e8a3a8d6 237 data &= ~SHIFT_EN; // set Enable LOW
k4zuki 0:9cf8e8a3a8d6 238 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 239 data |= SHIFT_EN; // Set Enable HIGH
k4zuki 0:9cf8e8a3a8d6 240 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 241 data &= ~SHIFT_EN; // set Enable LOW
k4zuki 0:9cf8e8a3a8d6 242 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 243
k4zuki 0:9cf8e8a3a8d6 244 data = value << 4; // send the 4 LSbits (from 8)
k4zuki 0:9cf8e8a3a8d6 245
k4zuki 0:9cf8e8a3a8d6 246 data |= (mode << SHIFT_RS); // set DI mode
k4zuki 0:9cf8e8a3a8d6 247 data &= ~SHIFT_EN; // set Enable LOW
k4zuki 0:9cf8e8a3a8d6 248 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 249 data |= SHIFT_EN; // Set Enable HIGH
k4zuki 0:9cf8e8a3a8d6 250 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 251 data &= ~SHIFT_EN; // set Enable LOW
k4zuki 0:9cf8e8a3a8d6 252 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 253
k4zuki 0:9cf8e8a3a8d6 254 }
k4zuki 0:9cf8e8a3a8d6 255
k4zuki 0:9cf8e8a3a8d6 256 void TriPinLcd::_write4bits(uint8_t value)
k4zuki 0:9cf8e8a3a8d6 257 {
k4zuki 0:9cf8e8a3a8d6 258 int data=0; //= value & 0x0f;
k4zuki 0:9cf8e8a3a8d6 259
k4zuki 0:9cf8e8a3a8d6 260 data = value << 4; //send the first 4 databits (from 8)
k4zuki 0:9cf8e8a3a8d6 261
k4zuki 0:9cf8e8a3a8d6 262 data &= ~SHIFT_EN; // set Enable LOW
k4zuki 0:9cf8e8a3a8d6 263 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 264 data |= SHIFT_EN; // Set Enable HIGH
k4zuki 0:9cf8e8a3a8d6 265 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 266 data &= ~SHIFT_EN; // set Enable LOW
k4zuki 0:9cf8e8a3a8d6 267 _lcd.write(data);
k4zuki 0:9cf8e8a3a8d6 268
k4zuki 0:9cf8e8a3a8d6 269 }