154
|
1 // ---------------------------------------------------------------------------
|
|
2 // Created by Francisco Malpartida on 7.3.2012.
|
|
3 // Copyright 2011 - Under creative commons license 3.0:
|
|
4 // Attribution-ShareAlike CC BY-SA
|
|
5 //
|
|
6 // This software is furnished "as is", without technical support, and with no
|
|
7 // warranty, express or implied, as to its usefulness for any purpose.
|
|
8 //
|
|
9 // Thread Safe: No
|
|
10 // Extendable: Yes
|
|
11 //
|
|
12 // @file LiquidCrystal_SRG.h
|
|
13 // This file implements a basic liquid crystal library that comes as standard
|
|
14 // in the Arduino SDK but using a generic SHIFT REGISTER extension board.
|
|
15 //
|
|
16 // @brief
|
|
17 // This is a basic implementation of the LiquidCrystal library of the
|
|
18 // Arduino SDK. The original library has been reworked in such a way that
|
|
19 // this class implements the all methods to command an LCD based
|
|
20 // on the Hitachi HD44780 and compatible chipsets using a 3 wire latching
|
|
21 // shift register. While it has been tested with a 74HC595N shift register
|
|
22 // it should also work with other latching shift registers such as the MC14094
|
|
23 // and the HEF4094
|
|
24 //
|
|
25 // This particular driver has been created as generic as possible to enable
|
|
26 // users to configure and connect their LCDs using just 3 digital IOs from the
|
|
27 // AVR or Arduino, and connect the LCD to the outputs of the shiftregister
|
|
28 // in any configuration. The library is configured by passing the IO pins
|
|
29 // that control the strobe, data and clock of the shift register and a map
|
|
30 // of how the shiftregister is connected to the LCD.
|
|
31 //
|
|
32 //
|
|
33 // +--------------------------------------------+
|
|
34 // | MCU |
|
|
35 // | IO1 IO2 IO3 |
|
|
36 // +----+-------------+-------------+-----------+
|
|
37 // | | |
|
|
38 // | | |
|
|
39 // +----+-------------+-------------+-----------+
|
|
40 // | Strobe Data Clock |
|
|
41 // | 8-bit shift/latch register | 74HC595N
|
|
42 // | Qa0 Qb1 Qc2 Qd3 Qe4 Qf5 Qg6 Qh7 |
|
|
43 // +----+----+----+----+----+----+----+----+----+
|
|
44 // | | | | | | |
|
|
45 // |11 |12 |13 |14 |6 |5 |4 (LCD pins)
|
|
46 // +----+----+----+----+----+----+----+----+----+
|
|
47 // | DB4 DB5 DB6 DB7 E Rw RS |
|
|
48 // | LCD Module |
|
|
49 //
|
|
50 // NOTE: Rw is not used by the driver so it can be connected to GND.
|
|
51 //
|
|
52 // The functionality provided by this class and its base class is identical
|
|
53 // to the original functionality of the Arduino LiquidCrystal library.
|
|
54 //
|
|
55 //
|
|
56 // History
|
|
57 // 2012.03.29 bperrybap - fixed constructors not properly using Rs
|
|
58 // Fixed incorrect use of 5x10 for default font
|
|
59 // - now matches original LQ library.
|
|
60 // moved delay to send() so it is per cmd/write vs shiftout()
|
|
61 // NOTE: delay is on hairy edge of working when FAST_MODE is on.
|
|
62 // because of waitUsec().
|
|
63 // There is margin at 16Mhz AVR but might fail on 20Mhz AVRs.
|
|
64 //
|
|
65 // @author F. Malpartida - fmalpartida@gmail.com
|
|
66 // ---------------------------------------------------------------------------
|
|
67 // flags for backlight control
|
|
68 #include <stdio.h>
|
|
69 #include <string.h>
|
|
70 #include <inttypes.h>
|
|
71
|
|
72 #if (ARDUINO < 100)
|
|
73 #include <WProgram.h>
|
|
74 #else
|
|
75 #include <Arduino.h>
|
|
76 #endif
|
|
77 #include "LiquidCrystal_SR3W.h"
|
|
78
|
|
79 #include "FastIO.h"
|
|
80
|
|
81 /*!
|
|
82 @defined
|
|
83 @abstract LCD_NOBACKLIGHT
|
|
84 @discussion No BACKLIGHT MASK
|
|
85 */
|
|
86 #define LCD_NOBACKLIGHT 0x00
|
|
87
|
|
88 /*!
|
|
89 @defined
|
|
90 @abstract LCD_BACKLIGHT
|
|
91 @discussion BACKLIGHT MASK used when backlight is on
|
|
92 */
|
|
93 #define LCD_BACKLIGHT 0xFF
|
|
94
|
|
95
|
|
96 // Default library configuration parameters used by class constructor with
|
|
97 // only the I2C address field.
|
|
98 // ---------------------------------------------------------------------------
|
|
99 /*!
|
|
100 @defined
|
|
101 @abstract Enable bit of the LCD
|
|
102 @discussion Defines the IO of the expander connected to the LCD's Enable
|
|
103 */
|
|
104 #define EN 4 // Enable bit
|
|
105
|
|
106 /*!
|
|
107 @defined
|
|
108 @abstract Read/Write bit of the LCD
|
|
109 @discussion Defines the IO of the expander connected to the LCD's Rw pin
|
|
110 */
|
|
111 #define RW 5 // Read/Write bit
|
|
112
|
|
113 /*!
|
|
114 @defined
|
|
115 @abstract Register bit of the LCD
|
|
116 @discussion Defines the IO of the expander connected to the LCD's Register select pin
|
|
117 */
|
|
118 #define RS 6 // Register select bit
|
|
119
|
|
120 /*!
|
|
121 @defined
|
|
122 @abstract LCD dataline allocation this library only supports 4 bit LCD control
|
|
123 mode.
|
|
124 @discussion D4, D5, D6, D7 LCD data lines pin mapping of the extender module
|
|
125 */
|
|
126 #define D4 0
|
|
127 #define D5 1
|
|
128 #define D6 2
|
|
129 #define D7 3
|
|
130
|
|
131
|
|
132
|
|
133 LiquidCrystal_SR3W::LiquidCrystal_SR3W(uint8_t data, uint8_t clk, uint8_t strobe)
|
|
134 {
|
|
135 init( data, clk, strobe, RS, RW, EN, D4, D5, D6, D7 );
|
|
136 }
|
|
137
|
|
138 LiquidCrystal_SR3W::LiquidCrystal_SR3W(uint8_t data, uint8_t clk, uint8_t strobe,
|
|
139 uint8_t backlighPin, t_backlighPol pol)
|
|
140 {
|
|
141 init( data, clk, strobe, RS, RW, EN, D4, D5, D6, D7 );
|
|
142 setBacklightPin(backlighPin, pol);
|
|
143 }
|
|
144
|
|
145 LiquidCrystal_SR3W::LiquidCrystal_SR3W(uint8_t data, uint8_t clk, uint8_t strobe,
|
|
146 uint8_t En, uint8_t Rw, uint8_t Rs,
|
|
147 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 )
|
|
148 {
|
|
149 init( data, clk, strobe, Rs, Rw, En, d4, d5, d6, d7 );
|
|
150 }
|
|
151
|
|
152 LiquidCrystal_SR3W::LiquidCrystal_SR3W(uint8_t data, uint8_t clk, uint8_t strobe,
|
|
153 uint8_t En, uint8_t Rw, uint8_t Rs,
|
|
154 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
|
|
155 uint8_t backlighPin, t_backlighPol pol)
|
|
156 {
|
|
157 init( data, clk, strobe, Rs, Rw, En, d4, d5, d6, d7 );
|
|
158 setBacklightPin(backlighPin, pol);
|
|
159 }
|
|
160
|
|
161
|
|
162 void LiquidCrystal_SR3W::send(uint8_t value, uint8_t mode)
|
|
163 {
|
|
164
|
|
165 if ( mode != FOUR_BITS )
|
|
166 {
|
|
167 write4bits( (value >> 4), mode ); // upper nibble
|
|
168 }
|
|
169 write4bits( (value & 0x0F), mode); // lower nibble
|
|
170
|
|
171
|
|
172 #if (F_CPU <= 16000000)
|
|
173 // No need to use the delay routines on AVR since the time taken to write
|
|
174 // on AVR with SR pin mapping even with fio is longer than LCD command execution.
|
|
175 waitUsec(37); //goes away on AVRs
|
|
176 #else
|
|
177 delayMicroseconds ( 37 ); // commands & data writes need > 37us to complete
|
|
178 #endif
|
|
179
|
|
180 }
|
|
181
|
|
182
|
|
183 void LiquidCrystal_SR3W::setBacklightPin ( uint8_t value, t_backlighPol pol = POSITIVE )
|
|
184 {
|
|
185 _backlightPinMask = ( 1 << value );
|
|
186 _backlightStsMask = LCD_NOBACKLIGHT;
|
|
187 _polarity = pol;
|
|
188 setBacklight (BACKLIGHT_OFF); // Set backlight to off as initial setup
|
|
189 }
|
|
190
|
|
191 void LiquidCrystal_SR3W::setBacklight ( uint8_t value )
|
|
192 {
|
|
193 // Check if backlight is available
|
|
194 // ----------------------------------------------------
|
|
195 if ( _backlightPinMask != 0x0 )
|
|
196 {
|
|
197 // Check for polarity to configure mask accordingly
|
|
198 // ----------------------------------------------------------
|
|
199 if (((_polarity == POSITIVE) && (value > 0)) ||
|
|
200 ((_polarity == NEGATIVE ) && ( value == 0 )))
|
|
201 {
|
|
202 _backlightStsMask = _backlightPinMask & LCD_BACKLIGHT;
|
|
203 }
|
|
204 else
|
|
205 {
|
|
206 _backlightStsMask = _backlightPinMask & LCD_NOBACKLIGHT;
|
|
207 }
|
|
208 loadSR( _backlightStsMask );
|
|
209 }
|
|
210 }
|
|
211
|
|
212
|
|
213 // PRIVATE METHODS
|
|
214 // -----------------------------------------------------------------------------
|
|
215
|
|
216 int LiquidCrystal_SR3W::init(uint8_t data, uint8_t clk, uint8_t strobe,
|
|
217 uint8_t Rs, uint8_t Rw, uint8_t En,
|
|
218 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
|
|
219 {
|
|
220 _data = fio_pinToBit(data);
|
|
221 _clk = fio_pinToBit(clk);
|
|
222 _strobe = fio_pinToBit(strobe);
|
|
223 _data_reg = fio_pinToOutputRegister(data);
|
|
224 _clk_reg = fio_pinToOutputRegister(clk);
|
|
225 _strobe_reg = fio_pinToOutputRegister(strobe);
|
|
226
|
|
227 // LCD pin mapping
|
|
228 _backlightPinMask = 0;
|
|
229 _backlightStsMask = LCD_NOBACKLIGHT;
|
|
230 _polarity = POSITIVE;
|
|
231
|
|
232 _En = ( 1 << En );
|
|
233 _Rw = ( 1 << Rw );
|
|
234 _Rs = ( 1 << Rs );
|
|
235
|
|
236 // Initialise pin mapping
|
|
237 _data_pins[0] = ( 1 << d4 );
|
|
238 _data_pins[1] = ( 1 << d5 );
|
|
239 _data_pins[2] = ( 1 << d6 );
|
|
240 _data_pins[3] = ( 1 << d7 );
|
|
241
|
|
242 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
|
243
|
|
244 return (1);
|
|
245 }
|
|
246
|
|
247 void LiquidCrystal_SR3W::write4bits(uint8_t value, uint8_t mode)
|
|
248 {
|
|
249 uint8_t pinMapValue = 0;
|
|
250
|
|
251 // Map the value to LCD pin mapping
|
|
252 // --------------------------------
|
|
253 for ( uint8_t i = 0; i < 4; i++ )
|
|
254 {
|
|
255 if ( ( value & 0x1 ) == 1 )
|
|
256 {
|
|
257 pinMapValue |= _data_pins[i];
|
|
258 }
|
|
259 value = ( value >> 1 );
|
|
260 }
|
|
261
|
|
262 // Is it a command or data
|
|
263 // -----------------------
|
|
264 mode = ( mode == DATA ) ? _Rs : 0;
|
|
265
|
|
266 pinMapValue |= mode | _backlightStsMask;
|
|
267 loadSR ( pinMapValue | _En ); // Send with enable high
|
|
268 loadSR ( pinMapValue); // Send with enable low
|
|
269 }
|
|
270
|
|
271
|
|
272 void LiquidCrystal_SR3W::loadSR(uint8_t value)
|
|
273 {
|
|
274 // Load the shift register with information
|
|
275 fio_shiftOut(_data_reg, _data, _clk_reg, _clk, value, MSBFIRST);
|
|
276
|
|
277 // Strobe the data into the latch
|
|
278 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
|
279 {
|
|
280 fio_digitalWrite_HIGH(_strobe_reg, _strobe);
|
|
281 fio_digitalWrite_SWITCHTO(_strobe_reg, _strobe, LOW);
|
|
282 }
|
|
283 }
|