Manuel Caballero / PCF8574
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCF8574.h Source File

PCF8574.h

00001 /**
00002  * @brief       PCF8574.h
00003  * @details     Remote 8-bit I/O expander for I2C-bus with interrupt.
00004  *              Header file.
00005  *
00006  *
00007  * @return      NA
00008  *
00009  * @author      Manuel Caballero
00010  * @date        11/October/2017
00011  * @version     11/October/2017    The ORIGIN
00012  * @pre         NaN.
00013  * @warning     NaN
00014  * @pre         This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
00015  */
00016 #ifndef PCF8574_H
00017 #define PCF8574_H
00018 
00019 #include "mbed.h"
00020 
00021 
00022 /**
00023     Example:
00024 
00025 #include "mbed.h"
00026 #include "PCF8574.h"
00027 
00028 
00029 PCF8574     myDevice        ( I2C_SDA, I2C_SCL, PCF8574::PCF8574_ADDRESS_0, 400000 );
00030 
00031 Ticker      newReading;
00032 DigitalOut  myled1          ( LED1 );
00033 DigitalOut  myled2          ( LED2 );
00034 InterruptIn myPCF8574INT    ( p8 );
00035 
00036 
00037 PCF8574::PCF8574_status_t    aux;
00038 uint32_t                     mySTATE       =   0;
00039 
00040 
00041 void flip ( void )
00042 {
00043     PCF8574::PCF8574_vector_data_t   myData;
00044 
00045     // Read the port to check P7 status
00046     aux         =   myDevice.PCF8574_ReadPins ( &myData );
00047 
00048     if ( ( myData.data & PCF8574::PCF8574_P7_MASK ) == PCF8574::PCF8574_P7_MASK )
00049         myled2    =   1;                                                        // Turn the LED 2 on when P7 is HIGH
00050     else
00051         myled2    =   0;                                                        // Turn the LED 2 off when P7 is LOW
00052 }
00053 
00054 
00055 
00056 void changeDATA ( void )
00057 {
00058     PCF8574::PCF8574_vector_data_t   myData;
00059 
00060 
00061     myled1    =  1;
00062 
00063 
00064     // Read the port to mask P7
00065     aux         =   myDevice.PCF8574_ReadPins ( &myData );
00066     myData.data =   ( myData.data & PCF8574::PCF8574_P7_MASK );
00067 
00068     // Change the state of the PCF8574 pins: P[O-6]
00069     if ( mySTATE == 0 ) {
00070         myData.data  |=   ( PCF8574::PCF8574_P0_OUTPUT_LOW | PCF8574::PCF8574_P1_OUTPUT_HIGH | PCF8574::PCF8574_P2_OUTPUT_LOW | PCF8574::PCF8574_P3_OUTPUT_HIGH |
00071                             PCF8574::PCF8574_P4_OUTPUT_LOW | PCF8574::PCF8574_P5_OUTPUT_HIGH | PCF8574::PCF8574_P6_OUTPUT_LOW );
00072 
00073         aux           =   myDevice.PCF8574_SetPins  ( myData );
00074 
00075         mySTATE       =   1;
00076     } else {
00077         myData.data  |=   ( PCF8574::PCF8574_P0_OUTPUT_HIGH | PCF8574::PCF8574_P1_OUTPUT_LOW | PCF8574::PCF8574_P2_OUTPUT_HIGH | PCF8574::PCF8574_P3_OUTPUT_LOW |
00078                             PCF8574::PCF8574_P4_OUTPUT_HIGH | PCF8574::PCF8574_P5_OUTPUT_LOW | PCF8574::PCF8574_P6_OUTPUT_HIGH );
00079 
00080         aux           =   myDevice.PCF8574_SetPins  ( myData );
00081 
00082         mySTATE       =   0;
00083     }
00084 
00085     myled1    =  0;
00086 }
00087 
00088 
00089 int main()
00090 {
00091     PCF8574::PCF8574_vector_data_t   myData;
00092 
00093     // Configure PCF8574: P[0-6] OUTPUTs, P7 INPUT
00094     myData.data   =   ( PCF8574::PCF8574_P0_OUTPUT_LOW | PCF8574::PCF8574_P1_OUTPUT_LOW | PCF8574::PCF8574_P2_OUTPUT_LOW | PCF8574::PCF8574_P3_OUTPUT_LOW |
00095                         PCF8574::PCF8574_P4_OUTPUT_LOW | PCF8574::PCF8574_P5_OUTPUT_LOW | PCF8574::PCF8574_P6_OUTPUT_LOW | PCF8574::PCF8574_P7_INPUT      );
00096 
00097     aux           =    myDevice.PCF8574_SetPins ( myData );
00098 
00099 
00100     myPCF8574INT.mode( PullUp );
00101     myPCF8574INT.fall( &flip );                                                 // attach the address of the flip function to the falling edge
00102     newReading.attach( &changeDATA, 0.5 );                                      // the address of the function to be attached ( changeDATA ) and the interval ( 0.5s )
00103 
00104 
00105     // Let the callbacks take care of everything
00106     while(1) {
00107         sleep();
00108     }
00109 }
00110 */
00111 
00112 
00113 /*!
00114  Library for the PCF8574 Remote 8-bit I/O expander for I2C-bus with interrupt.
00115 */
00116 class PCF8574
00117 {
00118 public:
00119     /**
00120     * @brief   DEFAULT ADDRESSES. NOTE: There are two version: PCF8574 and PCF8574A with different address only,
00121     *                             its functionality remains the same.
00122     */
00123     typedef enum {
00124         PCF8574_ADDRESS_0      =   ( 0x20 << 1 ),                 /*!<   A2 A1 A0: 000                                            */
00125         PCF8574_ADDRESS_1      =   ( 0x21 << 1 ),                 /*!<   A2 A1 A0: 001                                            */
00126         PCF8574_ADDRESS_2      =   ( 0x22 << 1 ),                 /*!<   A2 A1 A0: 010                                            */
00127         PCF8574_ADDRESS_3      =   ( 0x23 << 1 ),                 /*!<   A2 A1 A0: 011                                            */
00128         PCF8574_ADDRESS_4      =   ( 0x24 << 1 ),                 /*!<   A2 A1 A0: 100                                            */
00129         PCF8574_ADDRESS_5      =   ( 0x25 << 1 ),                 /*!<   A2 A1 A0: 101                                            */
00130         PCF8574_ADDRESS_6      =   ( 0x26 << 1 ),                 /*!<   A2 A1 A0: 110                                            */
00131         PCF8574_ADDRESS_7      =   ( 0x27 << 1 ),                 /*!<   A2 A1 A0: 111                                            */
00132 
00133         PCF8574A_ADDRESS_0     =   ( 0x38 << 1 ),                 /*!<   A2 A1 A0: 000                                            */
00134         PCF8574A_ADDRESS_1     =   ( 0x39 << 1 ),                 /*!<   A2 A1 A0: 001                                            */
00135         PCF8574A_ADDRESS_2     =   ( 0x3A << 1 ),                 /*!<   A2 A1 A0: 010                                            */
00136         PCF8574A_ADDRESS_3     =   ( 0x3B << 1 ),                 /*!<   A2 A1 A0: 011                                            */
00137         PCF8574A_ADDRESS_4     =   ( 0x3C << 1 ),                 /*!<   A2 A1 A0: 100                                            */
00138         PCF8574A_ADDRESS_5     =   ( 0x3D << 1 ),                 /*!<   A2 A1 A0: 101                                            */
00139         PCF8574A_ADDRESS_6     =   ( 0x3E << 1 ),                 /*!<   A2 A1 A0: 110                                            */
00140         PCF8574A_ADDRESS_7     =   ( 0x3F << 1 )                  /*!<   A2 A1 A0: 111                                            */
00141     } PCF8574_address_t;
00142 
00143 
00144 // DATA BYTE
00145     /**
00146       * @brief   PIN NUMBER
00147       */
00148     typedef enum {
00149         PCF8574_P0               =   0,                            /*!<  PCF8574 P0 INPUT                                       */
00150         PCF8574_P1               =   1,                            /*!<  PCF8574 P1 INPUT                                       */
00151         PCF8574_P2               =   2,                            /*!<  PCF8574 P2 INPUT                                       */
00152         PCF8574_P3               =   3,                            /*!<  PCF8574 P3 INPUT                                       */
00153         PCF8574_P4               =   4,                            /*!<  PCF8574 P4 INPUT                                       */
00154         PCF8574_P5               =   5,                            /*!<  PCF8574 P5 INPUT                                       */
00155         PCF8574_P6               =   6,                            /*!<  PCF8574 P6 INPUT                                       */
00156         PCF8574_P7               =   7                             /*!<  PCF8574 P7 INPUT                                       */
00157     } PCF8574_pin_number_t;
00158 
00159 
00160     /**
00161       * @brief   PIN MASK
00162       */
00163     typedef enum {
00164         PCF8574_P0_MASK           =   0b00000001,                  /*!<  PCF8574 P0 INPUT                                       */
00165         PCF8574_P1_MASK           =   0b00000010,                  /*!<  PCF8574 P1 INPUT                                       */
00166         PCF8574_P2_MASK           =   0b00000100,                  /*!<  PCF8574 P2 INPUT                                       */
00167         PCF8574_P3_MASK           =   0b00001000,                  /*!<  PCF8574 P3 INPUT                                       */
00168         PCF8574_P4_MASK           =   0b00010000,                  /*!<  PCF8574 P4 INPUT                                       */
00169         PCF8574_P5_MASK           =   0b00100000,                  /*!<  PCF8574 P5 INPUT                                       */
00170         PCF8574_P6_MASK           =   0b01000000,                  /*!<  PCF8574 P6 INPUT                                       */
00171         PCF8574_P7_MASK           =   0b10000000                   /*!<  PCF8574 P7 INPUT                                       */
00172     } PCF8574_pin_mask_t;
00173 
00174 
00175 
00176     /**
00177       * @brief   PIN CONFIGURATION
00178       */
00179     typedef enum {
00180         PCF8574_P0_INPUT         =   ( 1 << PCF8574_P0  ),           /*!<  PCF8574 P0 INPUT                                       */
00181         PCF8574_P0_OUTPUT_HIGH   =   ( 1 << PCF8574_P0  ),           /*!<  PCF8574 P0 OUTPUT HIGH                                 */
00182         PCF8574_P0_OUTPUT_LOW    =   ( 0 << PCF8574_P0  ),           /*!<  PCF8574 P0 OUTPUT LOW                                  */
00183 
00184         PCF8574_P1_INPUT         =   ( 1 << PCF8574_P1  ),           /*!<  PCF8574 P1 INPUT                                       */
00185         PCF8574_P1_OUTPUT_HIGH   =   ( 1 << PCF8574_P1  ),           /*!<  PCF8574 P1 OUTPUT HIGH                                 */
00186         PCF8574_P1_OUTPUT_LOW    =   ( 0 << PCF8574_P1  ),           /*!<  PCF8574 P1 OUTPUT LOW                                  */
00187 
00188         PCF8574_P2_INPUT         =   ( 1 << PCF8574_P2  ),           /*!<  PCF8574 P2 INPUT                                       */
00189         PCF8574_P2_OUTPUT_HIGH   =   ( 1 << PCF8574_P2  ),           /*!<  PCF8574 P2 OUTPUT HIGH                                 */
00190         PCF8574_P2_OUTPUT_LOW    =   ( 0 << PCF8574_P2  ),           /*!<  PCF8574 P2 OUTPUT LOW                                  */
00191 
00192         PCF8574_P3_INPUT         =   ( 1 << PCF8574_P3  ),           /*!<  PCF8574 P3 INPUT                                       */
00193         PCF8574_P3_OUTPUT_HIGH   =   ( 1 << PCF8574_P3  ),           /*!<  PCF8574 P3 OUTPUT HIGH                                 */
00194         PCF8574_P3_OUTPUT_LOW    =   ( 0 << PCF8574_P3  ),           /*!<  PCF8574 P3 OUTPUT LOW                                  */
00195 
00196         PCF8574_P4_INPUT         =   ( 1 << PCF8574_P4  ),           /*!<  PCF8574 P4 INPUT                                       */
00197         PCF8574_P4_OUTPUT_HIGH   =   ( 1 << PCF8574_P4  ),           /*!<  PCF8574 P4 OUTPUT HIGH                                 */
00198         PCF8574_P4_OUTPUT_LOW    =   ( 0 << PCF8574_P4  ),           /*!<  PCF8574 P4 OUTPUT LOW                                  */
00199 
00200         PCF8574_P5_INPUT         =   ( 1 << PCF8574_P5  ),           /*!<  PCF8574 P5 INPUT                                       */
00201         PCF8574_P5_OUTPUT_HIGH   =   ( 1 << PCF8574_P5  ),           /*!<  PCF8574 P5 OUTPUT HIGH                                 */
00202         PCF8574_P5_OUTPUT_LOW    =   ( 0 << PCF8574_P5  ),           /*!<  PCF8574 P5 OUTPUT LOW                                  */
00203 
00204         PCF8574_P6_INPUT         =   ( 1 << PCF8574_P6  ),           /*!<  PCF8574 P6 INPUT                                       */
00205         PCF8574_P6_OUTPUT_HIGH   =   ( 1 << PCF8574_P6  ),           /*!<  PCF8574 P6 OUTPUT HIGH                                 */
00206         PCF8574_P6_OUTPUT_LOW    =   ( 0 << PCF8574_P6  ),           /*!<  PCF8574 P6 OUTPUT LOW                                  */
00207 
00208         PCF8574_P7_INPUT         =   ( 1 << PCF8574_P7  ),           /*!<  PCF8574 P7 INPUT                                       */
00209         PCF8574_P7_OUTPUT_HIGH   =   ( 1 << PCF8574_P7  ),           /*!<  PCF8574 P7 OUTPUT HIGH                                 */
00210         PCF8574_P7_OUTPUT_LOW    =   ( 0 << PCF8574_P7  )            /*!<  PCF8574 P7 OUTPUT LOW                                  */
00211     } PCF8574_pin_configuration_t;
00212 
00213 
00214 
00215     /**
00216       * @brief   PIN STATUS
00217       */
00218     typedef enum {
00219         PCF8574_P0_HIGH   =   ( 1 << PCF8574_P0  ),                  /*!<  PCF8574 P0 STATUS HIGH                                 */
00220         PCF8574_P0_LOW    =   ( 0 << PCF8574_P0  ),                  /*!<  PCF8574 P0 STATUS LOW                                  */
00221 
00222         PCF8574_P1_HIGH   =   ( 1 << PCF8574_P1  ),                  /*!<  PCF8574 P1 STATUS HIGH                                 */
00223         PCF8574_P1_LOW    =   ( 0 << PCF8574_P1  ),                  /*!<  PCF8574 P1 STATUS LOW                                  */
00224 
00225         PCF8574_P2_HIGH   =   ( 1 << PCF8574_P2  ),                  /*!<  PCF8574 P2 STATUS HIGH                                 */
00226         PCF8574_P2_LOW    =   ( 0 << PCF8574_P2  ),                  /*!<  PCF8574 P2 STATUS LOW                                  */
00227 
00228         PCF8574_P3_HIGH   =   ( 1 << PCF8574_P3  ),                  /*!<  PCF8574 P3 STATUS HIGH                                 */
00229         PCF8574_P3_LOW    =   ( 0 << PCF8574_P3  ),                  /*!<  PCF8574 P3 STATUS LOW                                  */
00230 
00231         PCF8574_P4_HIGH   =   ( 1 << PCF8574_P4  ),                  /*!<  PCF8574 P4 STATUS HIGH                                 */
00232         PCF8574_P4_LOW    =   ( 0 << PCF8574_P4  ),                  /*!<  PCF8574 P4 STATUS LOW                                  */
00233 
00234         PCF8574_P5_HIGH   =   ( 1 << PCF8574_P5  ),                  /*!<  PCF8574 P5 STATUS HIGH                                 */
00235         PCF8574_P5_LOW    =   ( 0 << PCF8574_P5  ),                  /*!<  PCF8574 P5 STATUS LOW                                  */
00236 
00237         PCF8574_P6_HIGH   =   ( 1 << PCF8574_P6  ),                  /*!<  PCF8574 P6 STATUS HIGH                                 */
00238         PCF8574_P6_LOW    =   ( 0 << PCF8574_P6  ),                  /*!<  PCF8574 P6 STATUS LOW                                  */
00239 
00240         PCF8574_P7_HIGH   =   ( 1 << PCF8574_P7  ),                  /*!<  PCF8574 P7 STATUS HIGH                                 */
00241         PCF8574_P7_LOW    =   ( 0 << PCF8574_P7  )                   /*!<  PCF8574 P7 STATUS LOW                                  */
00242     } PCF8574_pin_status_t;
00243 
00244 
00245 
00246 
00247 
00248 #ifndef PCF8574_VECTOR_STRUCT_H
00249 #define PCF8574_VECTOR_STRUCT_H
00250     typedef struct {
00251         char data;
00252     } PCF8574_vector_data_t;
00253 #endif
00254 
00255 
00256 
00257 
00258     /**
00259       * @brief   INTERNAL CONSTANTS
00260       */
00261     typedef enum {
00262         PCF8574_SUCCESS     =       0,
00263         PCF8574_FAILURE     =       1,
00264         I2C_SUCCESS          =       0                           /*!<   I2C communication was fine                               */
00265     } PCF8574_status_t;
00266 
00267 
00268 
00269 
00270     /** Create an PCF8574 object connected to the specified I2C pins.
00271       *
00272       * @param sda     I2C data pin
00273       * @param scl     I2C clock pin
00274       * @param addr    I2C slave address
00275       * @param freq    I2C frequency in Hz.
00276       */
00277     PCF8574 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq );
00278 
00279     /** Delete PCF8574 object.
00280      */
00281     ~PCF8574();
00282 
00283     /** It configures and sets the pins of the device.
00284      */
00285     PCF8574_status_t  PCF8574_SetPins   ( PCF8574_vector_data_t  myConfDATA );
00286 
00287     /** It reads the state of the pins of the device
00288      */
00289     PCF8574_status_t  PCF8574_ReadPins  ( PCF8574_vector_data_t* myReadDATA );
00290 
00291 
00292 
00293 private:
00294     I2C      i2c;
00295     uint32_t PCF8574_Addr;
00296 };
00297 
00298 #endif