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