![]() |
LCD Library 1.1.7
LCD Library - LCD control class hierarchy library. Drop in replacement for the LiquidCrystal Library.
|
00001 // --------------------------------------------------------------------------- 00002 // Created by Francisco Malpartida on 20/08/11. 00003 // Copyright 2011 - Under creative commons license 3.0: 00004 // Attribution-ShareAlike CC BY-SA 00005 //LiquidCrystal 00006 // This software is furnished "as is", without technical support, and with no 00007 // warranty, express or implied, as to its usefulness for any purpose. 00008 // 00009 // Thread Safe: No 00010 // Extendable: Yes 00011 // 00012 // @file LiquidCrystal.cpp 00013 // This file implements a basic liquid crystal library that comes as standard 00014 // in the Arduino SDK. 00015 // 00016 // @brief 00017 // This is a basic implementation of the LiquidCrystal library of the 00018 // Arduino SDK. The original library has been reworked in such a way that 00019 // this class implements the all methods to command an LCD based 00020 // on the Hitachi HD44780 and compatible chipsets using the parallel port of 00021 // the LCD (4 bit and 8 bit). 00022 // 00023 // The functionality provided by this class and its base class is identical 00024 // to the original functionality of the Arduino LiquidCrystal library. 00025 // 00026 // 00027 // This library is only compatible with Arduino's SDK version 1.0 00028 // 00029 // 00030 // @author F. Malpartida - fmalpartida@gmail.com 00031 // --------------------------------------------------------------------------- 00032 #include <stdio.h> 00033 #include <string.h> 00034 #include <inttypes.h> 00035 00036 #if (ARDUINO < 100) 00037 #include <WProgram.h> 00038 #else 00039 #include <Arduino.h> 00040 #endif 00041 #include <LiquidCrystal.h> 00042 00043 // STATIC helper functions 00044 // --------------------------------------------------------------------------- 00045 00046 00047 // CONSTRUCTORS 00048 // --------------------------------------------------------------------------- 00049 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 00050 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 00051 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 00052 { 00053 init(LCD_8BIT, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); 00054 } 00055 00056 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 00057 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 00058 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 00059 { 00060 init(LCD_8BIT, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); 00061 } 00062 00063 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 00064 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 00065 { 00066 init(LCD_4BIT, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); 00067 } 00068 00069 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 00070 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 00071 { 00072 init(LCD_4BIT, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); 00073 } 00074 00075 // PRIVATE METHODS 00076 // --------------------------------------------------------------------------- 00077 00078 // When the display powers up, it is configured as follows: 00079 // 00080 // 1. Display clear 00081 // 2. Function set: 00082 // DL = 1; 8-bit interface data 00083 // N = 0; 1-line display 00084 // F = 0; 5x8 dot character font 00085 // 3. Display on/off control: 00086 // D = 0; Display off 00087 // C = 0; Cursor off 00088 // B = 0; Blinking off 00089 // 4. Entry mode set: 00090 // I/D = 1; Increment by 1 00091 // S = 0; No shift 00092 // 00093 // Note, however, that resetting the Arduino doesn't reset the LCD, so we 00094 // can't assume that its in that state when a sketch starts (and the 00095 // LiquidCrystal constructor is called). 00096 // A call to begin() will reinitialize the LCD. 00097 // 00098 // init 00099 void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, 00100 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 00101 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 00102 { 00103 uint8_t i; 00104 00105 // Initialize the IO pins 00106 // ----------------------- 00107 00108 _rs_pin = rs; 00109 _rw_pin = rw; 00110 _enable_pin = enable; 00111 00112 _data_pins[0] = d0; 00113 _data_pins[1] = d1; 00114 _data_pins[2] = d2; 00115 _data_pins[3] = d3; 00116 _data_pins[4] = d4; 00117 _data_pins[5] = d5; 00118 _data_pins[6] = d6; 00119 _data_pins[7] = d7; 00120 00121 // Initialize the IO port direction to OUTPUT 00122 // ------------------------------------------ 00123 00124 for ( i = 0; i < 4; i++ ) 00125 { 00126 pinMode ( _data_pins[i], OUTPUT ); 00127 } 00128 00129 // Initialize the rest of the ports if it is an 8bit controlled LCD 00130 // ---------------------------------------------------------------- 00131 00132 if ( !fourbitmode ) 00133 { 00134 for ( i = 4; i < 8; i++ ) 00135 { 00136 pinMode ( _data_pins[i], OUTPUT ); 00137 } 00138 } 00139 pinMode(_rs_pin, OUTPUT); 00140 00141 // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# 00142 if (_rw_pin != 255) 00143 { 00144 pinMode(_rw_pin, OUTPUT); 00145 } 00146 00147 pinMode(_enable_pin, OUTPUT); 00148 00149 // Initialise displaymode functions to defaults: LCD_1LINE and LCD_5x8DOTS 00150 // ------------------------------------------------------------------------- 00151 if (fourbitmode) 00152 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; 00153 else 00154 _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; 00155 } 00156 00157 // PUBLIC METHODS 00158 // --------------------------------------------------------------------------- 00159 00160 // 00161 // begin 00162 void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) 00163 { 00164 if (lines > 1) 00165 { 00166 _displayfunction |= LCD_2LINE; 00167 } 00168 _numlines = lines; 00169 _cols = cols; 00170 00171 // for some 1 line displays you can select a 10 pixel high font 00172 // ------------------------------------------------------------ 00173 if ((dotsize != 0) && (lines == 1)) 00174 { 00175 _displayfunction |= LCD_5x10DOTS; 00176 } 00177 00178 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! 00179 // according to datasheet, we need at least 40ms after power rises above 2.7V 00180 // before sending commands. Arduino can turn on way before 4.5V so we'll wait 00181 // 50 00182 // --------------------------------------------------------------------------- 00183 delayMicroseconds(50000); 00184 00185 // Now we pull both RS and R/W low to begin commands 00186 digitalWrite(_rs_pin, LOW); 00187 digitalWrite(_enable_pin, LOW); 00188 00189 if (_rw_pin != 255) 00190 { 00191 digitalWrite(_rw_pin, LOW); 00192 } 00193 00194 //put the LCD into 4 bit or 8 bit mode 00195 // ------------------------------------- 00196 if (! (_displayfunction & LCD_8BITMODE)) 00197 { 00198 // this is according to the hitachi HD44780 datasheet 00199 // figure 24, pg 46 00200 00201 // we start in 8bit mode, try to set 4 bit mode 00202 writeNbits(0x03, 4); 00203 delayMicroseconds(4500); // wait min 4.1ms 00204 00205 // second try 00206 writeNbits(0x03, 4); 00207 delayMicroseconds(4500); // wait min 4.1ms 00208 00209 // third go! 00210 writeNbits(0x03, 4); 00211 delayMicroseconds(150); 00212 00213 // finally, set to 4-bit interface 00214 writeNbits(0x02, 4); 00215 } 00216 else 00217 { 00218 // this is according to the hitachi HD44780 datasheet 00219 // page 45 figure 23 00220 00221 // Send function set command sequence 00222 command(LCD_FUNCTIONSET | _displayfunction); 00223 delayMicroseconds(4500); // wait more than 4.1ms 00224 00225 // second try 00226 command(LCD_FUNCTIONSET | _displayfunction); 00227 delayMicroseconds(150); 00228 00229 // third go 00230 command(LCD_FUNCTIONSET | _displayfunction); 00231 } 00232 00233 // finally, set # lines, font size, etc. 00234 command(LCD_FUNCTIONSET | _displayfunction); 00235 00236 // turn the display on with no cursor or blinking default 00237 _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 00238 display(); 00239 00240 // clear the LCD 00241 clear(); 00242 00243 // Initialize to default text direction (for romance languages) 00244 _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 00245 // set the entry mode 00246 command(LCD_ENTRYMODESET | _displaymode); 00247 00248 } 00249 00250 /************ low level data pushing commands **********/ 00251 00252 // send 00253 void LiquidCrystal::send(uint8_t value, uint8_t mode) 00254 { 00255 digitalWrite( _rs_pin, mode ); 00256 00257 // if there is a RW pin indicated, set it low to Write 00258 // --------------------------------------------------- 00259 if (_rw_pin != 255) 00260 { 00261 digitalWrite(_rw_pin, LOW); 00262 } 00263 00264 if (_displayfunction & LCD_8BITMODE) 00265 { 00266 writeNbits(value, 8); 00267 } 00268 else 00269 { 00270 writeNbits ( value >> 4, 4 ); 00271 writeNbits ( value, 4 ); 00272 } 00273 waitUsec ( EXEC_TIME ); // wait for the command to execute by the LCD 00274 } 00275 00276 // 00277 // pulseEnable 00278 void LiquidCrystal::pulseEnable(void) 00279 { 00280 // There is no need for the delays, since the digitalWrite operation 00281 // takes longer. 00282 digitalWrite(_enable_pin, HIGH); 00283 waitUsec(1); // enable pulse must be > 450ns 00284 digitalWrite(_enable_pin, LOW); 00285 waitUsec(20); 00286 } 00287 00288 // 00289 // write4bits 00290 void LiquidCrystal::writeNbits(uint8_t value, uint8_t numBits) 00291 { 00292 for (uint8_t i = 0; i < numBits; i++) 00293 { 00294 digitalWrite(_data_pins[i], (value >> i) & 0x01); 00295 } 00296 pulseEnable(); 00297 }