![]() |
LCD Library 1.1.1
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 // 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_SR.h 00013 // Connects an LCD using 2 or 3 pins from the Arduino, via an 8-bit 00014 // ShiftRegister (SR from now on). 00015 // 00016 // @brief 00017 // This is a port of the ShiftRegLCD library from raron and ported to the 00018 // LCD library. 00019 // 00020 // The functionality provided by this class and its base class is identical 00021 // to the original functionality of the Arduino LiquidCrystal library and can 00022 // be used as such. 00023 // 00024 // Modified to work serially with the shiftOut() function, an 8-bit shiftregister 00025 // (SR) and an LCD in 4-bit mode. 00026 // 00027 // Shiftregister connection description (NEW as of 2009.07.27) 00028 // 00029 // Bit #0 - N/C - not connected, used to hold a zero 00030 // Bits #1 - N/C 00031 // Bit #2 - connects to RS (Register Select) on the LCD 00032 // Bits #3 - #6 from SR connects to LCD data inputs D4 - D7. 00033 // Bit #7 - is used to enabling the enable-puls (via a diode-resistor AND "gate") 00034 // 00035 // 2 or 3 Pins required from the Arduino for Data, Clock, and Enable (optional). 00036 // If not using Enable, the Data pin is used for the enable signal by defining 00037 // the same pin for Enable as for Data. Data and Clock outputs/pins goes to the 00038 // shiftregister. 00039 // LCD RW-pin hardwired to LOW (only writing to LCD). Busy Flag (BF, data bit D7) 00040 // is not read. 00041 // 00042 // Any shift register should do. I used 74LS164, for the reason that's what I 00043 // had at hand. 00044 // 00045 // Original project homepage: http://code.google.com/p/arduinoshiftreglcd/ 00046 // 00047 // History 00048 // 2011.10.29 fmalpartida - adaption of the library to the LCD class hierarchy. 00049 // 2009.05.23 raron - but; based mostly (as in almost verbatim) on the 00050 // "official" LiquidCrystal library. 00051 // 2009.07.23 Incorporated some proper initialization routines 00052 // inspired (lets say copy-paste-tweaked) from LiquidCrystal library 00053 // improvements from LadyAda 00054 // 2009.07.25 raron - Fixed comments. I really messed up the comments before 00055 // posting this, so I had to fix it. 00056 // Also renamed a function, but no improvements or functional changes. 00057 // 2009.07.27 Thanks to an excellent suggestion from mircho at the Arduiono 00058 // playgrond forum, the number of wires now required is only two! 00059 // 2009.07.28 Mircho / raron - a new modification to the schematics, and a more 00060 // streamlined interface 00061 // 2009.07.30 raron - minor corrections to the comments. Fixed keyword highlights. 00062 // Fixed timing to datasheet safe. 00063 // 2011.07.02 Fixed a minor flaw in setCursor function. No functional change, 00064 // just a bit more memory efficient. 00065 // Thanks to CapnBry (from google code and github) who noticed it. 00066 // URL to his version of shiftregLCD: 00067 //https://github.com/CapnBry/HeaterMeter/commit/c6beba1b46b092ab0b33bcbd0a30a201fd1f28c1 00068 // 00069 // 00070 // This library is only compatible with Arduino's SDK version 1.0 00071 // 00072 // 00073 // @author F. Malpartida - fmalpartida@gmail.com 00074 // --------------------------------------------------------------------------- 00075 #include <stdio.h> 00076 #include <string.h> 00077 #include <inttypes.h> 00078 00079 #if (ARDUINO < 100) 00080 #include <WProgram.h> 00081 #else 00082 #include <Arduino.h> 00083 #endif 00084 #include <LiquidCrystal_SR.h> 00085 00086 // When the display powers up, it is configured as follows: 00087 // 00088 // 1. Display clear 00089 // 2. Function set: 00090 // DL = 1; 8-bit interface data 00091 // N = 0; 1-line display 00092 // F = 0; 5x8 dot character font 00093 // 3. Display on/off control: 00094 // D = 0; Display off 00095 // C = 0; Cursor off 00096 // B = 0; Blinking off 00097 // 4. Entry mode set: 00098 // I/D = 1; Increment by 1 00099 // S = 0; No shift 00100 // 00101 // Note, however, that resetting the Arduino doesn't reset the LCD, so we 00102 // can't assume that its in that state when a sketch starts (and the 00103 // LiquidCrystal constructor is called). 00104 // A call to begin() will reinitialize the LCD. 00105 00106 // STATIC helper routines 00107 // --------------------------------------------------------------------------- 00117 inline static void waitUsec ( uint16_t uSec ) 00118 { 00119 #ifndef FAST_MODE 00120 delayMicroseconds ( uSec ); 00121 #endif // FAST_MODE 00122 00123 // CONSTRUCTORS 00124 // --------------------------------------------------------------------------- 00125 // Assuming 1 line 8 pixel high font 00126 LiquidCrystal_SR::LiquidCrystal_SR ( uint8_t srdata, uint8_t srclock, 00127 uint8_t enable ) 00128 { 00129 init ( srdata, srclock, enable, 1, 0 ); 00130 } 00131 // Set nr. of lines, assume 8 pixel high font 00132 LiquidCrystal_SR::LiquidCrystal_SR ( uint8_t srdata, uint8_t srclock, 00133 uint8_t enable, uint8_t lines ) 00134 { 00135 init ( srdata, srclock, enable, lines, 0 ); 00136 } 00137 00138 // Set nr. of lines and font 00139 LiquidCrystal_SR::LiquidCrystal_SR ( uint8_t srdata, uint8_t srclock, 00140 uint8_t enable, uint8_t lines, 00141 uint8_t font ) 00142 { 00143 init ( srdata, srclock, enable, lines, font ); 00144 } 00145 00146 00147 // PRIVATE METHODS 00148 // --------------------------------------------------------------------------- 00149 00150 // 00151 // init 00152 void LiquidCrystal_SR::init( uint8_t srdata, uint8_t srclock, uint8_t enable, 00153 uint8_t lines, uint8_t font ) 00154 { 00155 // Initialise private variables 00156 _two_wire = 0; 00157 _srdata_pin = srdata; 00158 _srclock_pin = srclock; 00159 _enable_pin = enable; 00160 00161 if (enable == TWO_WIRE) 00162 { 00163 _enable_pin = _srdata_pin; 00164 _two_wire = 1; 00165 } 00166 00167 // Configure control pins as outputs 00168 // ------------------------------------------------------------------------ 00169 pinMode(_srclock_pin, OUTPUT); 00170 pinMode(_srdata_pin, OUTPUT); 00171 pinMode(_enable_pin, OUTPUT); 00172 00173 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x10DOTS; 00174 } 00175 00176 // PUBLIC METHODS 00177 // --------------------------------------------------------------------------- 00178 00179 // 00180 // begin 00181 void LiquidCrystal_SR::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) 00182 { 00183 00184 if (lines > 1) 00185 { 00186 _displayfunction |= LCD_2LINE; 00187 } 00188 00189 _numlines = lines; 00190 _cols = cols; 00191 00192 // for some 1 line displays you can select a 10 pixel high font 00193 // ------------------------------------------------------------ 00194 if ((dotsize != 0) && (lines == 1)) 00195 { 00196 _displayfunction |= LCD_5x10DOTS; 00197 } 00198 00199 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! 00200 // according to datasheet, we need at least 40ms after power rises above 2.7V 00201 // before sending commands. Arduino can turn on way before 4.5V so we'll wait 00202 // 50 00203 // --------------------------------------------------------------------------- 00204 delayMicroseconds(50000); 00205 init4bits(LCD_FUNCTIONSET | LCD_8BITMODE); 00206 delayMicroseconds(4500); // wait more than 4.1ms 00207 00208 // Second try 00209 init4bits(LCD_FUNCTIONSET | LCD_8BITMODE); 00210 delayMicroseconds(150); 00211 // Third go 00212 init4bits(LCD_FUNCTIONSET | LCD_8BITMODE); 00213 00214 // And finally, set to 4-bit interface 00215 init4bits(LCD_FUNCTIONSET | LCD_4BITMODE); 00216 00217 // Set # lines, font size, etc. 00218 command(LCD_FUNCTIONSET | _displayfunction); 00219 // Turn the display on with no cursor or blinking default 00220 _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 00221 display(); 00222 // Clear it off 00223 clear(); 00224 // Initialize to default text direction (for romance languages) 00225 _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 00226 // set the entry mode 00227 command(LCD_ENTRYMODESET | _displaymode); 00228 home(); 00229 00230 } 00231 00232 /************ low level data pushing commands **********/ 00233 00234 // send 00235 void LiquidCrystal_SR::send(uint8_t value, uint8_t mode) 00236 { 00237 uint8_t val1, val2; 00238 00239 // If _two_wire - clear the shiftregister first. 00240 // ---------------------------------------------- 00241 if ( _two_wire ) 00242 { 00243 shiftOut ( _srdata_pin, _srclock_pin, MSBFIRST, 0x00 ); 00244 } 00245 digitalWrite( _enable_pin, LOW ); 00246 00247 mode = mode ? SR_RS_BIT : 0; // RS bit; LOW: command. HIGH: character. 00248 val1 = mode | SR_EN_BIT | ((value >> 1) & 0x78); // upper nibble 00249 val2 = mode | SR_EN_BIT | ((value << 3) & 0x78); // lower nibble 00250 00251 shiftOut ( _srdata_pin, _srclock_pin, MSBFIRST, val1 ); 00252 00253 digitalWrite( _enable_pin, HIGH ); 00254 waitUsec( 1 ); // enable pulse must be >450ns 00255 digitalWrite( _enable_pin, LOW ); 00256 00257 // clear shiftregister 00258 // --------------------------- 00259 if ( _two_wire ) 00260 { 00261 shiftOut ( _srdata_pin, _srclock_pin, MSBFIRST, 0x00 ); 00262 } 00263 shiftOut ( _srdata_pin, _srclock_pin, MSBFIRST, val2 ); 00264 00265 digitalWrite( _enable_pin, HIGH ); 00266 waitUsec( 1 ); // enable pulse must be >450ns 00267 digitalWrite( _enable_pin, LOW ); 00268 waitUsec( 40 ); // commands need > 37us to settle 00269 } 00270 00271 // 00272 // init4bits 00273 void LiquidCrystal_SR::init4bits(uint8_t value) 00274 { 00275 uint8_t val1; 00276 00277 // clear shiftregister 00278 // -------------------------- 00279 if ( _two_wire ) 00280 { 00281 shiftOut ( _srdata_pin, _srclock_pin, MSBFIRST, 0x00 ); 00282 } 00283 digitalWrite( _enable_pin, LOW ); 00284 00285 val1 = SR_EN_BIT | ((value >> 1) & 0x78); 00286 shiftOut ( _srdata_pin, _srclock_pin, MSBFIRST, val1 ); 00287 00288 digitalWrite( _enable_pin, HIGH ); 00289 waitUsec( 1 ); // enable pulse must be >450ns 00290 digitalWrite( _enable_pin, LOW ); 00291 00292 waitUsec( 40 ); // commands need > 37us to settle 00293 } 00294 00295 00296