![]() |
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 //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 routines 00044 // --------------------------------------------------------------------------- 00054 inline static void waitUsec ( uint16_t uSec ) 00055 { 00056 #ifndef FAST_MODE 00057 delayMicroseconds ( uSec ); 00058 #endif // FAST_MODE 00059 } 00060 00061 // CONSTRUCTORS 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 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 00066 { 00067 init(LCD_8BIT, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); 00068 } 00069 00070 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 00071 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 00072 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 00073 { 00074 init(LCD_8BIT, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); 00075 } 00076 00077 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 00078 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 00079 { 00080 init(LCD_4BIT, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); 00081 } 00082 00083 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 00084 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 00085 { 00086 init(LCD_4BIT, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); 00087 } 00088 00089 // PRIVATE METHODS 00090 // --------------------------------------------------------------------------- 00091 00092 // When the display powers up, it is configured as follows: 00093 // 00094 // 1. Display clear 00095 // 2. Function set: 00096 // DL = 1; 8-bit interface data 00097 // N = 0; 1-line display 00098 // F = 0; 5x8 dot character font 00099 // 3. Display on/off control: 00100 // D = 0; Display off 00101 // C = 0; Cursor off 00102 // B = 0; Blinking off 00103 // 4. Entry mode set: 00104 // I/D = 1; Increment by 1 00105 // S = 0; No shift 00106 // 00107 // Note, however, that resetting the Arduino doesn't reset the LCD, so we 00108 // can't assume that its in that state when a sketch starts (and the 00109 // LiquidCrystal constructor is called). 00110 // A call to begin() will reinitialize the LCD. 00111 // 00112 // init 00113 void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, 00114 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 00115 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 00116 { 00117 uint8_t i; 00118 00119 // Initialize the IO pins 00120 // ----------------------- 00121 00122 _rs_pin = rs; 00123 _rw_pin = rw; 00124 _enable_pin = enable; 00125 00126 _data_pins[0] = d0; 00127 _data_pins[1] = d1; 00128 _data_pins[2] = d2; 00129 _data_pins[3] = d3; 00130 _data_pins[4] = d4; 00131 _data_pins[5] = d5; 00132 _data_pins[6] = d6; 00133 _data_pins[7] = d7; 00134 00135 // Initialize the IO port direction to OUTPUT 00136 // ------------------------------------------ 00137 00138 for ( i = 0; i < 4; i++ ) 00139 { 00140 pinMode ( _data_pins[i], OUTPUT ); 00141 } 00142 00143 // Initialize the rest of the ports if it is an 8bit controlled LCD 00144 // ---------------------------------------------------------------- 00145 00146 if ( !fourbitmode ) 00147 { 00148 for ( i = 4; i < 8; i++ ) 00149 { 00150 pinMode ( _data_pins[i], OUTPUT ); 00151 } 00152 } 00153 pinMode(_rs_pin, OUTPUT); 00154 00155 // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# 00156 if (_rw_pin != 255) 00157 { 00158 pinMode(_rw_pin, OUTPUT); 00159 } 00160 00161 pinMode(_enable_pin, OUTPUT); 00162 00163 // Initialise displaymode functions to defaults: LCD_1LINE and LCD_5x8DOTS 00164 // ------------------------------------------------------------------------- 00165 if (fourbitmode) 00166 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; 00167 else 00168 _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; 00169 } 00170 00171 // PUBLIC METHODS 00172 // --------------------------------------------------------------------------- 00173 00174 // 00175 // begin 00176 void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) 00177 { 00178 if (lines > 1) 00179 { 00180 _displayfunction |= LCD_2LINE; 00181 } 00182 _numlines = lines; 00183 _cols = cols; 00184 00185 // for some 1 line displays you can select a 10 pixel high font 00186 // ------------------------------------------------------------ 00187 if ((dotsize != 0) && (lines == 1)) 00188 { 00189 _displayfunction |= LCD_5x10DOTS; 00190 } 00191 00192 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! 00193 // according to datasheet, we need at least 40ms after power rises above 2.7V 00194 // before sending commands. Arduino can turn on way before 4.5V so we'll wait 00195 // 50 00196 // --------------------------------------------------------------------------- 00197 delayMicroseconds(50000); 00198 00199 // Now we pull both RS and R/W low to begin commands 00200 digitalWrite(_rs_pin, LOW); 00201 digitalWrite(_enable_pin, LOW); 00202 00203 if (_rw_pin != 255) 00204 { 00205 digitalWrite(_rw_pin, LOW); 00206 } 00207 00208 //put the LCD into 4 bit or 8 bit mode 00209 // ------------------------------------- 00210 if (! (_displayfunction & LCD_8BITMODE)) 00211 { 00212 // this is according to the hitachi HD44780 datasheet 00213 // figure 24, pg 46 00214 00215 // we start in 8bit mode, try to set 4 bit mode 00216 write4bits(0x03); 00217 delayMicroseconds(4500); // wait min 4.1ms 00218 00219 // second try 00220 write4bits(0x03); 00221 delayMicroseconds(4500); // wait min 4.1ms 00222 00223 // third go! 00224 write4bits(0x03); 00225 delayMicroseconds(150); 00226 00227 // finally, set to 4-bit interface 00228 write4bits(0x02); 00229 } 00230 else 00231 { 00232 // this is according to the hitachi HD44780 datasheet 00233 // page 45 figure 23 00234 00235 // Send function set command sequence 00236 command(LCD_FUNCTIONSET | _displayfunction); 00237 delayMicroseconds(4500); // wait more than 4.1ms 00238 00239 // second try 00240 command(LCD_FUNCTIONSET | _displayfunction); 00241 delayMicroseconds(150); 00242 00243 // third go 00244 command(LCD_FUNCTIONSET | _displayfunction); 00245 } 00246 00247 // finally, set # lines, font size, etc. 00248 command(LCD_FUNCTIONSET | _displayfunction); 00249 00250 // turn the display on with no cursor or blinking default 00251 _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 00252 display(); 00253 00254 // clear the LCD 00255 clear(); 00256 00257 // Initialize to default text direction (for romance languages) 00258 _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 00259 // set the entry mode 00260 command(LCD_ENTRYMODESET | _displaymode); 00261 00262 } 00263 00264 /************ low level data pushing commands **********/ 00265 00266 // send 00267 void LiquidCrystal::send(uint8_t value, uint8_t mode) 00268 { 00269 digitalWrite( _rs_pin, mode ); 00270 00271 // if there is a RW pin indicated, set it low to Write 00272 // --------------------------------------------------- 00273 if (_rw_pin != 255) 00274 { 00275 digitalWrite(_rw_pin, LOW); 00276 } 00277 00278 if (_displayfunction & LCD_8BITMODE) 00279 { 00280 write8bits(value); 00281 } 00282 else 00283 { 00284 write4bits ( value >> 4 ); 00285 write4bits ( value ); 00286 } 00287 waitUsec ( EXEC_TIME ); // wait for the command to execute by the LCD 00288 } 00289 00290 // 00291 // pulseEnable 00292 void LiquidCrystal::pulseEnable(void) 00293 { 00294 // There is no need for the delays, since the digitalWrite operation 00295 // takes longer. 00296 digitalWrite(_enable_pin, HIGH); 00297 waitUsec(1); // enable pulse must be > 450ns 00298 digitalWrite(_enable_pin, LOW); 00299 } 00300 00301 // 00302 // write4bits 00303 void LiquidCrystal::write4bits(uint8_t value) 00304 { 00305 for (uint8_t i = 0; i < 4; i++) 00306 { 00307 digitalWrite(_data_pins[i], (value >> i) & 0x01); 00308 } 00309 pulseEnable(); 00310 } 00311 00312 // 00313 // write8bits 00314 void LiquidCrystal::write8bits(uint8_t value) 00315 { 00316 for (uint8_t i = 0; i < 8; i++) 00317 { 00318 digitalWrite(_data_pins[i], (value >> i) & 0x01); 00319 } 00320 pulseEnable(); 00321 }