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