![]() |
LCD Library 1.3.0
LCD Library - LCD control class hierarchy library. Drop in replacement for the LiquidCrystal Library.
|
00001 00002 // --------------------------------------------------------------------------- 00003 // Created/Adapted by Stephen Erisman 2013-07-06 00004 // Copyright 2013 - Under creative commons license 3.0: 00005 // Attribution-ShareAlike CC BY-SA 00006 // 00007 // This software is furnished "as is", without technical support, and with no 00008 // warranty, express or implied, as to its usefulness for any purpose. 00009 // 00010 // @file LiquidCrystal_SR1W.h 00011 // Connects a hd44780 LCD using 1 pin from the Arduino, via an 8-bit Latching 00012 // ShiftRegister (SR1W from now on). 00013 // 00014 // @brief 00015 // This is the 1 wire shift register interface class for the LCD library 00016 // 00017 // The functionality provided by this class and its base class is a superset of 00018 // the original functionality of the Arduino LiquidCrystal library and can 00019 // be used as such. 00020 // See the LCD class for a full description of the API functions available. 00021 // 00022 // It works with a 8-bit latched, no-tristate, unidirectional SIPO (Serial-In-Parallel-Out) 00023 // shift register, and an hd44780 LCD in 4-bit mode. 00024 // The 74HC595 shift register has been tested. 00025 // 00026 // 00027 // 1 Pin required from the Arduino: 00028 // - Serial PIN: 00029 // The Serial PIN is wired directly to the shift register's Clock PIN and its 00030 // unaltered signal directly triggers the Clock on every LOW to HIGH transition. 00031 // 00032 // Additionally, the Serial PIN is wired through a resistor capacitor (RC) filter to 00033 // the shift register's Data PIN. During a quick transition of the Serial PIN the 00034 // RC filter will maintain the Data PIN's previous value because the capacitor isn't 00035 // given enough time to charge (or discharge) to the alternate state. If the transition 00036 // is held for enough time, however, the RC capacitor will charge (or discharge) and the 00037 // value seen by the Data PIN will have changed state. 00038 // 00039 // There are two circuit versions that behave differently for Latch, Enable, and Clear: 00040 // 00041 // HW_CLEAR version: 00042 // In this version the shift register's Latch and LCD's Enable PINs are wired directly to 00043 // the shift register's Q'H output. The shift register's /Clear PIN is then wired up 00044 // through two logic "gates": first QH and Q'H are AND'd together with a diode-resistor 00045 // "gate" the output of which is NAND'd with VCC using a resistor-NPN-resistor "gate". 00046 // So, /CLR = ((QH AND Q'H) NAND VCC). We also put a capacitor on the NPN base to GND 00047 // to delay the signal a bit and allow the Latch and EN signals some extra time to trigger. 00048 // 00049 // This all fits together as follows: 00050 // 1. We shift in a '1'. 00051 // 2. Ws shift in the other 7 bits. 00052 // 3. At this point the first '1' has been shifted into Q'H causing it to go HIGH. 00053 // 4. When Q'H is HIGH it causes Latch and EN to also go HIGH. 00054 // 5. When Latch transitions to HIGH it changes the shift register outputs to the bits 00055 // that were shifted in. 00056 // 6. This causes QH to go HIGH (if it wasn't already). 00057 // 7. Now that QH AND Q'H are both HIGH they causes the base capacitor to start charging. 00058 // 8. When the capacitor has charged enough the transistor brings /CLR LOW. 00059 // 8. This will cause /CLR to trigger and the shift register will be cleared 00060 // (NOTE: This doesn't change the latched outputs) 00061 // 9. The clearing of the shift register causes Q'H to go LOW. 00062 // 9. When Q'H is LOW it causes Latch and EN to also go LOW. 00063 // 10. When EN transitions to LOW the LCD reads in the bits on the shift register pins 00064 // and does it's thing. 00065 // 11. Now that Q'H is LOW the base capacitor starts discharging. 00066 // 12. When the capacitor has discharged enough the transistor will stop sinking /CLR. 00067 // 13. This will cause /CLR to be pulled back up to HIGH by the VCC pullup resistor 00068 // (it will stay that way until our next nibble/byte has been shifted in) 00069 // 14. We are now ready for our next nibble/byte. 00070 // 00071 // 00072 // SW_CLEAR version: 00073 // In this version the Serial PIN is wired to the shift register's Latch and LCD's Enable 00074 // PINs through another RC filter. These PINs are also wired through a diode (AND "gate") 00075 // tied to the shift register's Q'H output. This combination means that the Latch and 00076 // Enable PINs will be held LOW as long as EITHER the Q'H or RC output is LOW. 00077 // 00078 // This all fits together as follows: 00079 // 1. We shift in a '1'. 00080 // 2. We shift in the other 7 bits. (NOTE: We leave Serial PIN HIGH at the end of this) 00081 // 3. At this point the first '1' has been shifted into Q'H causing it to go HIGH. 00082 // (NOTE: Up until this time Q'H has been LOW so the attached diode has been keeping 00083 // the Latch/EN pins LOW.) 00084 // 4. Now that Q'H is HIGH it causes the attached diode to stop discharging the Latch/EN 00085 // capacitor. We delay here for a while to make sure it is fully charged. 00086 // 5. When the capacitor has charged enough Latch/EN will be HIGH 00087 // 5. When Latch transitions to HIGH it changes the shift register outputs to what was 00088 // shifted in. 00089 // 6. We now bring the Serial PIN LOW and wait for the Latch/EN capacitor to discharge. 00090 // 7. When the capacitor has discharged enough Latch/EN will be LOW 00091 // 8. When EN transitions to LOW the LCD reads in the bits on the shift register pins 00092 // and does it's thing. 00093 // 9. We now shift in '0' 8 times (as quickly as possible). 00094 // 10. If we keep the LOW to HIGH to LOW pulses short enough while shifting in the '0's 00095 // the Latch/EN capacitor won't have time to charge to a point where it will re-trigger 00096 // the Latch/EN pins. 00097 // 11. Now Q'H will be LOW and the shift register has been cleared (NOTE: This doesn't 00098 // change the latched outputs.) 00099 // 12. We now bring the Serial PIN HIGH again and wait for the Data capacitor to recharge. 00100 // 13. When the Data capacitor has fully charged we are ready for our next nibble/byte. 00101 // 00102 // 00103 // These designs incorporate (and merge) ideas originally found here (1-wire concept): 00104 // http://www.romanblack.com/shift1.htm 00105 // and here (diode-resistor AND "gate" EN control): 00106 // http://www.rentron.com/Myke1.htm 00107 // as well as introducing some new and original ideas (particularly how HW_CLEAR works). 00108 // 00109 // Because of its use of the diode AND "gate", the SW_CLEAR design allows for faster sending 00110 // of data to the LCD compared to Roman's original design. With the proposed 5uS delay (see 00111 // notes below), a byte can be sent to the LCD in as little as 30 uS (plus overhead) when 00112 // sending all 1's. This increases to as much as 190 uS (plus overhead) when sending all 0's. 00113 // This is in comparison to Roman's estimate of around 3-4 mS to send a byte. So this 00114 // implementation is 15-133 times faster for the cost of a single (1N4148 or similar) diode. 00115 // 00116 // The HW_CLEAR version is even faster as it can completely eliminate the clearSR() call as 00117 // well as the delays that are needed to latch the data in the SW_CLEAR version. 00118 // 00119 // 00120 // Default Shift Register Bits - Shifted MSB first: 00121 // Bit #0 (QA) - not used 00122 // Bit #1 (QB) - connects to LCD data input D7 00123 // Bit #2 (QC) - connects to LCD data input D6 00124 // Bit #3 (QD) - connects to LCD data input D5 00125 // Bit #4 (QE) - connects to LCD data input D4 00126 // Bit #5 (QF) - optional backlight control 00127 // Bit #6 (QG) - connects to RS (Register Select) on the LCD 00128 // Bit #7 (QH) - used for /CLR on the HW_CLEAR version (cannot be changed) 00129 // (Q'H) - used for Latch/EN (via the diode AND "gate") (cannot be changed) 00130 // 00131 // NOTE: Any of these can be changed around as needed EXCEPT Bit #7 (QH and Q'H). 00132 // 00133 // 00134 // Circuit Types (for the 74HC595) 00135 // ------------------------------- 00136 // The 74HC595 is a latching shift register. See the explanations above for how these circuits 00137 // work. 00138 // 00139 // 00140 // HW_CLEAR version: (Faster but higher part count) 00141 // ------------------------------------------------ 00142 // 00143 // 74HC595 (VCC) 00144 // +----u----+ | 2.2nF 00145 // (LCD D7)------------1-|QB VCC|-16--+ +----||----(GND) 00146 // (LCD D6)------------2-|QC QA|-15 | 00147 // (LCD D5)------------3-|QD SER|-14-------+--[ Resistor ]--+ 00148 // (LCD D4)------------4-|QE /OE|-13--(GND) 1.5k | 00149 // (BL Circuit)--------5-|QF RCK|-12-----+ | 00150 // | | \ | 00151 // (LCD RS)------------6-|QG SCK|-11-------)----------------+--(Serial PIN) 00152 // | | | 00153 // +-------7-|QH /CLR|-10-------)--+--[ Resistor ]--(VCC) 00154 // | | | / | 1k 00155 // | +--8-|GND Q'H|--9-----+ | 00156 // | | +---------+ | | (GND)--(LCD RW) 00157 // | | 0.1uF | \ 00158 // | (GND)-----||----(VCC) +------)--------------(LCD EN) 00159 // | | / 00160 // |----|<|----+--[ Resistor ]--| | 00161 // diode | 1k C 00162 // | | 00163 // +-------------+---B-|> (NPN) 00164 // | | 00165 // (2.2nF) = E 00166 // | | 00167 // (GND) (GND) 00168 // 00169 // 00170 // SW_CLEAR version: (Lower part count but slower) 00171 // ----------------------------------------------- 00172 // 00173 // 74HC595 (VCC) 00174 // +----u----+ | 2.2nF 00175 // (LCD D7)------------1-|QB VCC|-16--+ +----||----(GND) 00176 // (LCD D6)------------2-|QC QA|-15 | 00177 // (LCD D5)------------3-|QD SER|-14---------+--[ Resistor ]--+ 00178 // (LCD D4)------------4-|QE /OE|-13--(GND) 1.5k | 00179 // (BL Circuit)--------5-|QF RCK|-12---------+ | 00180 // | | \ | 00181 // (LCD RS)------------6-|QG SCK|-11-----------)--------------+--(Serial PIN) 00182 // 7-|QH /CLR|-10--(VCC) / | 00183 // +--8-|GND Q'H|--9---|<|---+--[ Resistor ]--+ 00184 // | +---------+ diode | 1.5k 00185 // | | 00186 // | 0.1uF | 00187 // (GND)-----||----(VCC) +----||----(GND) 00188 // | 2.2nF 00189 // (LCD EN)-------------------------------------+ 00190 // (LCD RW)--(GND) 00191 // 00192 // 00193 // In either case the LCD RW pin is hardwired to GND meaning we will only be able to write 00194 // to the LCD. 00195 // Therefore, the Busy Flag (BF, data bit D7) is not able to be read and we have to make use 00196 // of the minimum delay time constraints. This isn't really a problem because it usually 00197 // takes us longer to shift and latch the data than the minimum delay anyway. For now, we 00198 // simply keep track of our delays and add more delay at the end to get to at least 37 uS. 00199 // 00200 // 00201 // Backlight Control Circuit 00202 // ------------------------- 00203 // Since we are using the latching nature of the shift resiter we don't need the extra 00204 // backlight circuitry that SR2W uses. Keeping it around, however, would still work because 00205 // the circuit just slows down the transitions to the mosfet a bit. 00206 // 00207 // Here are two more optimized versions that can be used. 00208 // 00209 // 00210 // NPN Transistor version: (Cheaper but more power draw and higher part count) 00211 // --------------------------------------------------------------------------- 00212 // 00213 // (value depends on LCD, 100ohm is usually safe) 00214 // (LCD BL anode)---[ resistor ]---(VCC) 00215 // 00216 // (LCD BL cathode)---------------+ 00217 // | 00218 // C 00219 // | 00220 // (BL input)--[ Resistor ]---B-|> (NPN) 00221 // 1k | 00222 // E 00223 // | 00224 // (GND) 00225 // 00226 // NOTE: The Bate resistor is needed because the NPN is current fed. For lower 00227 // power draw, try a 10k resistor. 00228 // 00229 // 00230 // N-CH Mosfet version: (More costly but less power draw and lower part count) 00231 // --------------------------------------------------------------------------- 00232 // 00233 // (value depends on LCD, 100ohm is usually safe) 00234 // (LCD BL anode)---[ resistor ]---(VCC) 00235 // 00236 // (LCD BL cathode)---------------+ 00237 // | 00238 // D 00239 // | 00240 // (BL input)----------------G-|-< (2N7000 FET) 00241 // | 00242 // S 00243 // | 00244 // (GND) 00245 // 00246 // NOTE: Gate resistor not needed because the mosfet is voltage fed and only really 00247 // pulls current while switching. 00248 // 00249 // In either case, when the BL input is HIGH the LCD backlight will turn on. 00250 // 00251 // 00252 // History 00253 // 2013.07.31 serisman - fixed potential interrupt bug and made more performance optimizations 00254 // 2013.07.10 serisman - more performance optimizations and modified the HW_CLEAR circuit a bit 00255 // 2013.07.09 serisman - added an even faster version that performs the clear in hardware 00256 // 2013.07.08 serisman - changed code to shift data MSB first to match SR2W 00257 // 2013.07.07 serisman - major speed optimization 00258 // 2013.07.06 serisman - created/modified from SR2W source to create SR1W 00259 // @author S. Erisman - arduino@serisman.com 00260 // -------------------------------------------------------------------------------- 00261 00262 #ifndef _LIQUIDCRYSTAL_SR1W_ 00263 #define _LIQUIDCRYSTAL_SR1W_ 00264 00265 #include <inttypes.h> 00266 #include "LCD.h" 00267 #include "FastIO.h" 00268 00269 // 1-wire SR timing constants 00270 // --------------------------------------------------------------------------- 00271 00272 // NOTE: 00273 // The 1.5k resistor (1.2k - 1.8k with a 20% tolerance) 00274 // takes between 2.376uS and 4.36uS to fully charge or discharge 00275 // the 2.2n capacitor (1.98n - 2.42n with a 10% tolerance). 00276 // We round this up to a 5uS delay to provide an additional safety margin. 00277 00278 #define SR1W_DELAY_US 5 00279 #define SR1W_DELAY() { delayMicroseconds(SR1W_DELAY_US); numDelays++; } 00280 00281 // 1-wire SR output bit constants 00282 // --------------------------------------------------------------------------- 00283 00284 #define SR1W_UNUSED_MASK 0x01 // Set unused bit(s) to '1' as they are slightly faster to clock in. 00285 #define SR1W_D7_MASK 0x02 00286 #define SR1W_D6_MASK 0x04 00287 #define SR1W_D5_MASK 0x08 00288 #define SR1W_D4_MASK 0x10 00289 #define SR1W_BL_MASK 0x20 00290 #define SR1W_RS_MASK 0x40 00291 #define SR1W_EN_MASK 0x80 // This cannot be changed. It has to be the first thing shifted in. 00292 00293 #define SR1W_ATOMIC_WRITE_LOW(reg, mask) ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *reg &= ~mask; } 00294 #define SR1W_ATOMIC_WRITE_HIGH(reg, mask) ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *reg |= mask; } 00295 00296 00297 typedef enum { SW_CLEAR, HW_CLEAR } t_sr1w_circuitType; 00298 00299 class LiquidCrystal_SR1W : public LCD 00300 { 00301 public: 00313 LiquidCrystal_SR1W (uint8_t srdata, t_sr1w_circuitType circuitType, 00314 t_backlighPol blpol = POSITIVE); 00315 00328 virtual void send(uint8_t value, uint8_t mode); 00329 00330 00340 void setBacklight ( uint8_t mode ); 00341 00342 private: 00343 00349 void init ( uint8_t srdata, t_sr1w_circuitType circuitType, t_backlighPol blpol, 00350 uint8_t lines, uint8_t font ); 00351 00357 uint8_t clearSR (); 00358 00363 uint8_t loadSR (uint8_t val); 00364 00365 fio_register _srRegister; // Serial PIN 00366 fio_bit _srMask; 00367 00368 t_sr1w_circuitType _circuitType; 00369 00370 uint8_t _blPolarity; 00371 uint8_t _blMask; 00372 }; 00373 #endif