Added generic I2C board control to define pin mapping to IO extender so that it is a generic library for the PCF8574.

This commit is contained in:
FMC
2011-11-06 22:31:54 +01:00
parent d3f8077769
commit 9b07db2bee
8 changed files with 195 additions and 86 deletions
+14 -8
View File
@@ -57,6 +57,7 @@ public:
This method is the first method that should be call prior to calling any
other method form this class. On initialization all pins are configured
as INPUT on the device.
@param i2cAddr: I2C Address where the device is located.
@result 1 if the device was initialized correctly, 0 otherwise
*/
@@ -67,18 +68,19 @@ public:
@abstract Sets the mode of a particular pin.
@discussion Sets the mode of a particular pin to INPUT, OUTPUT. digitalWrite
has no effect on pins which are not declared as output.
@param pin: Pin from the I2C IO expander to be configured. Range 0..7
@param dir: Pin direction (INPUT, OUTPUT).
@param pin[in] Pin from the I2C IO expander to be configured. Range 0..7
@param dir[in] Pin direction (INPUT, OUTPUT).
*/
void pinMode ( uint8_t pin, uint8_t dir );
/*!
@method
@abstract Sets all the pins of the device in a particular direction.
@discussion This method sets all the pins of the device in a particular
direction. This method is useful to set all the pins of the device to be
either inputs or outputs.
@param dir: Direction of all the pins of the device (INPUT, OUTPUT).
@param dir[in] Direction of all the pins of the device (INPUT, OUTPUT).
*/
void portMode ( uint8_t dir );
@@ -88,6 +90,7 @@ public:
@discussion Reads from the device the status of the pins that are configured
as INPUT. During initialization all pins are configured as INPUTs by default.
Please refer to pinMode or portMode.
@param none
*/
uint8_t read ( void );
@@ -98,7 +101,8 @@ public:
@discussion Reads a particular pin from the device. To read a particular
pin it has to be configured as INPUT. During initialization all pins are
configured as INPUTs by default. Please refer to pinMode or portMode.
@param pin: Pin from the port to read its status. Range (0..7)
@param pin[in] Pin from the port to read its status. Range (0..7)
@result Returns the pin status (HIGH, LOW) if the pin is configured
as an output, reading its value will always return LOW regardless of its
real state.
@@ -114,7 +118,8 @@ public:
a particular pin with this method, such pin has to be configured as OUTPUT
using the portMode or pinMode methods. If no pins have been configured as
OUTPUTs this method will have no effect.
@param value: value to be written to the device.
@param value[in] value to be written to the device.
@result 1 on success, 0 otherwise
*/
int write ( uint8_t value );
@@ -125,8 +130,9 @@ public:
@discussion Write a level to the indicated pin of the device. For this
method to have effect, the pin has to be configured as OUTPUT using the
pinMode or portMode methods.
@param pin: device pin to change level. Range (0..7).
@para level: logic level to set the pin at (HIGH, LOW).
@param pin[in] device pin to change level. Range (0..7).
@para level[in] logic level to set the pin at (HIGH, LOW).
@result 1 on success, 0 otherwise.
*/
int digitalWrite ( uint8_t pin, uint8_t level );
+7 -8
View File
@@ -61,13 +61,13 @@ LCD::LCD ()
void LCD::clear()
{
command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
delayMicroseconds(2000); // this command is time consuming
delayMicroseconds(1500); // this command is time consuming
}
void LCD::home()
{
command(LCD_RETURNHOME); // set cursor position to zero
delayMicroseconds(2000); // This command is time consuming
delayMicroseconds(1500); // This command is time consuming
}
void LCD::setCursor(uint8_t col, uint8_t row)
@@ -164,6 +164,7 @@ void LCD::createChar(uint8_t location, uint8_t charmap[])
location &= 0x7; // we only have 8 locations 0-7
command(LCD_SETCGRAMADDR | (location << 3));
for (int i=0; i<8; i++)
{
write(charmap[i]); // call the virtual write method
@@ -174,21 +175,19 @@ void LCD::createChar(uint8_t location, uint8_t charmap[])
// ---------------------------------------------------------------------------
void LCD::command(uint8_t value)
{
send(value, LOW);
send(value, COMMAND);
}
#if (ARDUINO < 100)
void LCD::write(uint8_t value)
{
send(value, HIGH);
send(value, DATA);
}
#else
size_t LCD::write(uint8_t value)
{
send(value, HIGH);
send(value, DATA);
return 1; // assume OK
}
#endif
//void LCD::send(uint8_t value, uint8_t mode) { }
#endif
+21 -12
View File
@@ -90,6 +90,15 @@
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
#define LCD_4BIT 1
#define LCD_8BIT 0
// Define COMMAND and DATA LCD Rs
// ---------------------------------------------------------------------------
#define COMMAND 0
#define DATA 1
class LCD : public Print
{
public:
@@ -113,8 +122,8 @@ public:
this base class to implement the internals of how the LCD is initialized
and configured.
@param cols the number of columns that the display has
@param rows the number of rows that the display has
@param cols[in] the number of columns that the display has
@param rows[in] the number of rows that the display has
*/
#if (ARDUINO < 100)
virtual void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS) { };
@@ -285,9 +294,9 @@ public:
determine the pixels in that row. To display a custom character on screen,
write()/print() its number, i.e. lcd.print (char(x)); // Where x is 0..7.
@param location: LCD memory location of the character to create
@param location[in] LCD memory location of the character to create
(0 to 7)
@param charmap: the bitmap array representing each row of the character.
@param charmap[in] the bitmap array representing each row of the character.
*/
void createChar(uint8_t location, uint8_t charmap[]);
@@ -297,8 +306,8 @@ public:
@discussion Sets the position of the LCD cursor. Set the location at which
subsequent text written to the LCD will be displayed.
@param col LCD column
@param row LCD row - line.
@param col[in] LCD column
@param row[in] LCD row - line.
*/
void setCursor(uint8_t col, uint8_t row);
@@ -312,7 +321,7 @@ public:
This command shouldn't be used to drive the LCD, only to implement any other
feature that is not available on this library.
@param value Command value to send to the LCD.
@param value[in] Command value to send to the LCD.
*/
void command(uint8_t value);
@@ -325,14 +334,14 @@ public:
This is the virtual write method, implemented in the Print class, therefore
all Print class methods will end up calling this method.
@param value Value to write to the LCD.
@param value[in] Value to write to the LCD.
*/
#if (ARDUINO < 100)
virtual void write(uint8_t value);
#else
virtual size_t write(uint8_t value);
#endif
/*!
@function
@@ -343,7 +352,7 @@ public:
Users should never call this method.
@param value Value to send to the LCD.
@param value[in] Value to send to the LCD.
@result mode LOW - write to the LCD CGRAM, HIGH - write a command to
the LCD.
*/
@@ -363,9 +372,9 @@ protected:
// Internal LCD variables to control the LCD shared between all derived
// classes.
uint8_t _displayfunction; // LCD_5x10DOTS or LCD_5x8DOTS, LCD_4BITMODE or
// LCD_8BITMODE, LCD_1LINE or LCD_2LINE
// LCD_8BITMODE, LCD_1LINE or LCD_2LINE
uint8_t _displaycontrol; // LCD base control command LCD on/off, blink, cursor
// all commands are "ored" to its contents.
// all commands are "ored" to its contents.
uint8_t _displaymode; // Text entry mode to the LCD
uint8_t _numlines; // Number of lines of the LCD, initialized with begin()
+7 -7
View File
@@ -67,26 +67,26 @@ LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
init(LCD_8BIT, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
init(LCD_8BIT, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
{
init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
init(LCD_4BIT, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
}
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
{
init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
init(LCD_4BIT, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
}
// PRIVATE METHODS
@@ -249,7 +249,7 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
// send
void LiquidCrystal::send(uint8_t value, uint8_t mode)
{
digitalWrite(_rs_pin, mode);
digitalWrite( _rs_pin, mode );
// if there is a RW pin indicated, set it low to Write
// ---------------------------------------------------
@@ -264,8 +264,8 @@ void LiquidCrystal::send(uint8_t value, uint8_t mode)
}
else
{
write4bits(value>>4);
write4bits(value);
write4bits ( value >> 4 );
write4bits ( value );
}
}
+2 -3
View File
@@ -63,7 +63,6 @@ public:
LiquidCrystal(uint8_t rs, uint8_t enable,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
/*!
@function
@abstract LCD initialization.
@@ -71,8 +70,8 @@ public:
initializes the LCD, therefore, it MUST be called prior to using any other
method from this class or parent class.
@param cols: the number of columns that the display has
@param rows: the number of rows that the display has
@param cols[in] the number of columns that the display has
@param rows[in] the number of rows that the display has
@param charsize: size of the characters of the LCD: LCD_5x8DOTS or
LCD_5x10DOTS.
*/
+75 -21
View File
@@ -67,8 +67,51 @@ LiquidCrystal_I2C::LiquidCrystal_I2C( uint8_t lcd_Addr )
_Addr = lcd_Addr;
_backlightval = LCD_NOBACKLIGHT;
_En = EN;
_Rw = RW;
_Rs = RS;
// Initialise default values data[0] pin 0, data[1] pin 1, ...
for ( uint8_t i = 0; i < 4; i++ )
{
_data_pins[i] = ( 1 << i );
}
}
LiquidCrystal_I2C::LiquidCrystal_I2C( uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
uint8_t Rs)
{
_Addr = lcd_Addr;
_backlightval = LCD_NOBACKLIGHT;
_En = ( 1 << En );
_Rw = ( 1 << Rw );
_Rs = ( 1 << Rs );
// Initialise default values data[0] pin 0, data[1] pin 1, ...
for ( uint8_t i = 0; i < 4; i++ )
{
_data_pins[i] = ( 1 << i );
}
}
LiquidCrystal_I2C::LiquidCrystal_I2C( uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
uint8_t Rs, uint8_t d0, uint8_t d1,
uint8_t d2, uint8_t d3 )
{
_Addr = lcd_Addr;
_backlightval = LCD_NOBACKLIGHT;
_En = ( 1 << En );
_Rw = ( 1 << Rw );
_Rs = ( 1 << Rs );
// Initialise pin mapping
_data_pins[0] = ( 1 << d0 );
_data_pins[1] = ( 1 << d1 );
_data_pins[2] = ( 1 << d2 );
_data_pins[3] = ( 1 << d3 );
}
// PRIVATE METHODS
// ---------------------------------------------------------------------------
@@ -121,7 +164,7 @@ void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
delayMicroseconds(50000);
// Now we pull both RS and R/W low to begin commands
expanderWrite(_backlightval); // reset expander and turn backlight off (Bit 8 =1)
expanderWrite ( _backlightval ); // reset expander and turn backlight off (Bit 8 =1)
delay(1000);
//put the LCD into 4 bit mode
@@ -129,19 +172,19 @@ void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
// figure 24, pg 46
// we start in 8bit mode, try to set 4 bit mode
write4bits(0x03);
write4bits ( 0x03, LOW );
delayMicroseconds(4500); // wait min 4.1ms
// second try
write4bits(0x03);
write4bits ( 0x03, LOW );
delayMicroseconds(4500); // wait min 4.1ms
// third go!
write4bits(0x03);
write4bits ( 0x03, LOW );
delayMicroseconds(150);
// finally, set to 4-bit interface
write4bits(0x02);
write4bits ( 0x02, LOW );
// set # lines, font size, etc.
@@ -191,26 +234,37 @@ void LiquidCrystal_I2C::backlight(void)
// send - write either command or data
void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode)
{
// Is it a command or data
// -----------------------
if ( mode == HIGH )
{
mode = Rs;
}
uint8_t highnib=value>>4;
uint8_t lownib=value & 0x0F;
write4bits((highnib)|mode);
write4bits((lownib)|mode);
write4bits( (value >> 4), mode );
write4bits( (value & 0x0F), mode);
}
//
// write4bits
void LiquidCrystal_I2C::write4bits(uint8_t value)
void LiquidCrystal_I2C::write4bits ( uint8_t value, uint8_t mode )
{
expanderWrite(value);
pulseEnable(value);
uint8_t pinMapValue = 0;
// Map the value to LCD pin mapping
// --------------------------------
for ( uint8_t i = 0; i < 4; i++ )
{
if ( ( value & 0x1 ) == 1 )
{
pinMapValue |= _data_pins[i];
}
value = ( value >> 1 );
}
// Is it a command or data
// -----------------------
if ( mode == DATA )
{
mode = _Rs;
}
expanderWrite ( pinMapValue | mode );
pulseEnable ( pinMapValue | mode );
}
//
@@ -219,10 +273,10 @@ void LiquidCrystal_I2C::pulseEnable (uint8_t _data)
{
// No need to use the delay routines since the time taken to write takes
// longer that what is needed.
expanderWrite (_data | En); // En HIGH
expanderWrite (_data | _En); // En HIGH
//delayMicroseconds(1); // enable pulse must be >450ns
expanderWrite(_data & ~En); // En low
expanderWrite(_data & ~_En); // En low
//delayMicroseconds(50); // commands need > 37us to settle
}
+53 -11
View File
@@ -50,21 +50,21 @@
@abstract Enable bit of the LCD
@discussion Defines the IO of the expander connected to the LCD Enable
*/
#define En B01000000 // Enable bit
#define EN B01000000 // Enable bit
/*!
@defined
@abstract Read/Write bit of the LCD
@discussion Defines the IO of the expander connected to the LCD Rw pin
*/
#define Rw B00100000 // Read/Write bit
#define RW B00100000 // Read/Write bit
/*!
@defined
@abstract Register bit of the LCD
@discussion Defines the IO of the expander connected to the LCD Register select pin
*/
#define Rs B00010000 // Register select bit
#define RS B00010000 // Register select bit
class LiquidCrystal_I2C : public LCD
@@ -77,11 +77,45 @@ public:
@discussion Initializes class variables and defines the I2C address of the
LCD. The constructor does not initialize the LCD.
@param lcd_Addr: I2C address of the IO expansion module. For I2CLCDextraIO,
@param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
the address can be configured using the on board jumpers.
*/
LiquidCrystal_I2C (uint8_t lcd_Addr);
/*!
@method
@abstract Class constructor.
@discussion Initializes class variables and defines the I2C address of the
LCD. The constructor does not initialize the LCD.
@param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
the address can be configured using the on board jumpers.
@param En[in] LCD En (Enable) pin connected to the IO extender module
@param Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
@para Rs[in] LCD Rs (Reset) pin connected to the IO extender module
*/
LiquidCrystal_I2C( uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs);
/*!
@method
@abstract Class constructor.
@discussion Initializes class variables and defines the I2C address of the
LCD. The constructor does not initialize the LCD.
@param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
the address can be configured using the on board jumpers.
@param En[in] LCD En (Enable) pin connected to the IO extender module
@param Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
@param Rs[in] LCD Rs (Reset) pin connected to the IO extender module
@param d0[in] LCD data 0 pin map on IO extender module
@param d1[in] LCD data 1 pin map on IO extender module
@param d2[in] LCD data 2 pin map on IO extender module
@param d3[in] LCD data 3 pin map on IO extender module
*/
LiquidCrystal_I2C( uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3 );
/*!
@function
@abstract LCD initialization.
@@ -89,9 +123,9 @@ public:
initializes the LCD, therefore, it MUST be called prior to using any other
method from this class or parent class.
@param cols: the number of columns that the display has
@param rows: the number of rows that the display has
@param charsize: size of the characters of the LCD: LCD_5x8DOTS or
@param cols[in] the number of columns that the display has
@param rows[in] the number of rows that the display has
@param charsize[in] size of the characters of the LCD: LCD_5x8DOTS or
LCD_5x10DOTS.
*/
virtual void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
@@ -104,9 +138,9 @@ public:
Users should never call this method.
@param value: Value to send to the LCD.
@result mode: LOW - write to the LCD CGRAM, HIGH - write a command to
the LCD.
@param value[in] Value to send to the LCD.
@param mode[in] DATA - write to the LCD CGRAM, COMMAND - write a
command to the LCD.
*/
virtual void send(uint8_t value, uint8_t mode);
@@ -144,8 +178,11 @@ private:
@method
@abstract Writes an 4 bit value to the LCD.
@discussion Writes 4 bits (the least significant) to the LCD control data lines.
@param value[in] Value to write to the LCD
@param more[in] Value to distinguish between command and data.
COMMAND == command, DATA == data.
*/
void write4bits(uint8_t);
void write4bits(uint8_t value, uint8_t mode);
/*!
@method
@@ -168,6 +205,11 @@ private:
uint8_t _rows; // Number of rows of the LCD
uint8_t _backlightval; // Backlight shadow value
I2CIO _i2cio; // I2CIO PCF8574* expansion module driver I2CLCDextraIO
uint8_t _En; // LCD expander word for enable pin
uint8_t _Rw; // LCD expander word for R/W pin
uint8_t _Rs; // LCD expander word for Register Select pin
uint8_t _data_pins[4]; // LCD data lines
};
#endif
+16 -16
View File
@@ -81,7 +81,7 @@
// two-wire indicator constant
// ---------------------------------------------------------------------------
#define TWO_WIRE 204
#define TWO_WIRE 204
#define SR_RS_BIT 0x04
#define SR_EN_BIT 0x80
@@ -95,22 +95,22 @@ public:
The constructor does not initialize the LCD. Assuming 1 line 8 pixel high
font.
@param srdata pin for shiftregister data line.
@param srclock pin for shiftregister clock line.
@param enable enable pin for the shiftregister.
@param srdata[in] pin for shiftregister data line.
@param srclock[in] pin for shiftregister clock line.
@param enable[in] enable pin for the shiftregister.
*/
LiquidCrystal_SR ( uint8_t srdata, uint8_t srclock, uint8_t enable );
// Set nr. of lines, assume 8 pixel high font
LiquidCrystal_SR ( uint8_t srdata, uint8_t srclock, uint8_t enable,
uint8_t lines );
uint8_t lines );
// Set nr. of lines and font
LiquidCrystal_SR( uint8_t srdata, uint8_t srclock, uint8_t enable,
uint8_t lines, uint8_t font );
uint8_t lines, uint8_t font );
/*!
@function
@abstract LCD initialization.
@@ -118,9 +118,9 @@ public:
initializes the LCD, therefore, it MUST be called prior to using any other
method from this class or parent class.
@param cols: the number of columns that the display has
@param rows: the number of rows that the display has
@param charsize: size of the characters of the LCD: LCD_5x8DOTS or
@param cols[in] the number of columns that the display has
@param rows[in] the number of rows that the display has
@param charsize[in] size of the characters of the LCD: LCD_5x8DOTS or
LCD_5x10DOTS.
*/
virtual void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
@@ -133,7 +133,7 @@ public:
Users should never call this method.
@param value Value to send to the LCD.
@param value[in] Value to send to the LCD.
@result mode LOW - write to the LCD CGRAM, HIGH - write a command to
the LCD.
*/
@@ -148,14 +148,14 @@ private:
@discussion Initializes the LCD pin allocation and configuration.
*/
void init ( uint8_t srdata, uint8_t srclock, uint8_t enable, uint8_t lines,
uint8_t font );
uint8_t font );
/*!
@method
@abstract For sending data when initializing the display to 4-bit
@discussion Initializes the LCD pin allocation and configuration.
*/
void init4bits ( uint8_t );
uint8_t _srdata_pin; // Serial Data pin
uint8_t _srclock_pin; // Clock Pin
uint8_t _enable_pin; // Enable Pin