Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
03/18/05 17:04
Read: times


 
#89959 - The code...
Responding to: ???'s previous message
LS,

Below, you can find the code I'm using to test one simple input of the IO expander:

- Declaration of the variable m_keyscanData (ptr to structure)
- Creation of a PCF8574 'instance', used in the keyscan module

{start snippet}
.
.
static xdata Pcf8574 *m_keyscanData;
.
.
PUBLIC void keyscan_pow_TurnOn( void )
{
    m_keyscanData = pcf8574_obj_New( div_PCF8574_KEYDETECT_ADDRESS
                                   , 0x01
                                   );
.
.
}
{end snippet}

First parameter is the device address, second parameter the 'destination' of the pins. Here: one pin defined as input (pin0), rest defined as output.

Structure:

{start snippet}
structdef( Pcf8574 )
{
    Nat8 I2cAddress;
    Nat8 Buffer;
};
{end snippet}

There's a macro that 'expands' the structdef( Pcf8574 ).

Implementation of pcf8574_obj_New() code:

{start code}
PUBLIC Pcf8574 xdata *pcf8574_obj_New( Nat8 I2cAddress, Nat8 DefaultMask )
{
    Pcf8574 *p;

    ASSERT( m_Index < div_MaxIoExpanders );

    p = &( m_MyPcf8574Array[ m_Index++ ] );
    p->I2cAddress = I2cAddress;
    p->Buffer     = DefaultMask;
    WriteI2c( p );

    return ( p );
}
{end code}

Here, I get an 'instance', being one struct out of an array of Pcf8574 structs. This way, I'm preventing multiple c files for the different IO expanders I'm using.
That's my way of OO programming in plain C... :-)

So, after the TurnOn, the parameter 'Buffer' contains the default mask 0x01.

Later on, I want to read the complete content of the IO expander, to see if something has changed (if the status of pin0 has changed, in other words: did I release the switch or do I still press the switch?).
This read action is done every 50ms, via a 'pump' in the OS (own OS, not the one of Keil). The handler called is given below.

{start code}
PUBLIC void keyscan_pmp_KeyboardScan( Nat8 Param1, Nat16 Param2 )
{
    Nat8 TempVal;

    UNUSED( Param1 );
    UNUSED( Param2 );

    TempVal = m_DataIo1;
    m_DataIo1 = pcf8574_get_Byte( m_keyscanData );

    pcf8574_set_Bit( m_keyscanData
                   , 6
                   , ( ( m_DataIo1 & KEY1 ) ? 0 : 1 ) 
                   );
        
    brucos_krn_PmpSendAfter( KEYBOARD_SCAN
                           , 0
                           , 0
                           , PMP_AFTER_MS( 50 )
                           );
}
{end code}

First, you see that I read the content of the IO expander, referred to by the pointer m_keyscanData (points to one of the struct elements in the array which is located in the Pcf8574 'driver': see above). The result of that read action is stored in the variable m_DataIo1 (of type Nat8).

This is the code for the function pcf8574_get_Byte():

{start code}
PUBLIC Nat8 pcf8574_get_Byte( Pcf8574 const xdata *Object )
{
    ASSERT( Object != NULL);

    i2c_swi2c_Read( Object->I2cAddress
                  , &( Object->Buffer )
                  , 1 
                  );

    return ( Object->Buffer );
}
{end code}

Here, you can see I'm giving a pointer to the function. The intention is to fill the parameter 'Buffer' of the structure given, after the I2C read action has been done.

Back to the function keyscan_pmp_KeyboardScan now...
Next to reading the content of the IO expander, I'm setting another pin (pin6, configured as output) of the Pcf8574, reflecting the status of the INPUT pin.
The 3rd parameter of function pcf8574_set_Bit() depends on the content of the byte just read. If bit0 of that byte is set, it means a '1' is detected at the input pin0 (means: switch is not pressed). Otherwise, bit0 will have the value '0', meaning the switch is pressed.
Since activating the LED means writing a '0' to pin6 (LED is via +5Vdc and resistor of 390 ohm connected to pin6), the logic is the following: when I press the switch, the LED should be activated. So, reading '0' for bit0 (meaning switch is pressed, so input is connected to ground) will result in writing '0' for bit6 (and so pin6, so LED is activated) and vice versa.
To know the value of bit0, I bitwise "OR" the content of the IO expander (in the variable m_DataIo1) with KEY1 (defined as 0x01).
The code for the function pcf8574_set_Bit() is given below:

{start code}
PUBLIC void pcf8574_set_Bit( Pcf8574 xdata *Object, Nat8 Pin, Bool Active )
{
    ASSERT( ( 0 <= Pin )
          &&( Pin <= 7 )
          );

    ASSERT( ( Active == TRUE )
          ||( Active == FALSE )
          );

    if ( Active )
    {
        Object->Buffer |= _crol_( 0x01, Pin );
    }
    else
    {
        Object->Buffer &= ~_crol_( 0x01, Pin );
    }

    WriteI2c( Object );
}
{end code}

First, I'm checking if a '1' or a '0' must be written to the object given as input to this function (here, again my m_keyscanData object).
To set or clear the correct bit, the variable Pin will shift the '1' in the value 0x01 x locations to the left. So, if I want to change the status of pin6 (= my example), then 6 shift operations will be done to create the value 0x40 out of 0x01.
If a '1' has to be written, then I bitwise "OR" the content of the buffer (which still contains 0x01) with the shifted value, here 0x40. So, the result is 0x40 | 0x01 = 0x41.
You can clearly see that I don't write a '0' on location 1 in the byte, thanks to the bitwise "OR" action!
If a '0' has to be written, then again the same shift action is done (maybe it can be done a bit more efficient, but that's not the issue here). However, now there's a bitwise "AND"-ing with the inverse of the result.
If I take again my example, then we have:
. 0x01 << 6 = 0x40
. inverse the number => 0xBF
. bitwise "AND" the content of the buffer (which can have the value 0x40): 0xBF & 0x40 = 0x01.
So, again I don't change the configuration of pin0!!!

Voila, that's my code I'm using to control a Pcf8574. Hope there's enough information...

If you see any mistakes, I will be more than happy to carefully listen!

Andy, I hope the formatting is OK? ;-) ;-) ;-)

Best rgds,

--Geert



List of 77 messages in thread
TopicAuthorDate
Problems with PCF8574 input            01/01/70 00:00      
   best guess            01/01/70 00:00      
      To Erik            01/01/70 00:00      
         So....            01/01/70 00:00      
            To Jez Smith            01/01/70 00:00      
         show the code            01/01/70 00:00      
            To Oleg            01/01/70 00:00      
               How to post code            01/01/70 00:00      
                  To Andy            01/01/70 00:00      
   hmmmmmm            01/01/70 00:00      
      To Jez            01/01/70 00:00      
   RTFDS - using 8574 IO as inputs            01/01/70 00:00      
      To J. Guy            01/01/70 00:00      
         When is pin written ?            01/01/70 00:00      
            My datasheet tells something different..            01/01/70 00:00      
               To Kai            01/01/70 00:00      
                  cutting through the fog            01/01/70 00:00      
            To J. Guy            01/01/70 00:00      
   Where is the difference between...            01/01/70 00:00      
      To Kai            01/01/70 00:00      
         Re:Problems with PCF8574 input            01/01/70 00:00      
         Test it without having any communication            01/01/70 00:00      
            To Kai            01/01/70 00:00      
   Maybe good guess!            01/01/70 00:00      
      To Medhi            01/01/70 00:00      
      Switch terminology            01/01/70 00:00      
         Thanks!            01/01/70 00:00      
            Coonfoosed yeeet            01/01/70 00:00      
               Contact arrangement - nothing else            01/01/70 00:00      
   PCF8574            01/01/70 00:00      
      To Ben            01/01/70 00:00      
   I have used the bugger often            01/01/70 00:00      
      To Erik            01/01/70 00:00      
         helloooooooooo !!            01/01/70 00:00      
            To Erik            01/01/70 00:00      
         Wager...            01/01/70 00:00      
            To Grant            01/01/70 00:00      
      The code...            01/01/70 00:00      
         Thats told 'em :-)            01/01/70 00:00      
            Frightend... ;-)            01/01/70 00:00      
         Formatting            01/01/70 00:00      
            Format flavours.            01/01/70 00:00      
   Insanity            01/01/70 00:00      
      Malaysian Grand Prix...            01/01/70 00:00      
   Some update!!!            01/01/70 00:00      
      Let me comment....            01/01/70 00:00      
         "fancy" code            01/01/70 00:00      
            I'll Suggest...            01/01/70 00:00      
               Pointers and structures            01/01/70 00:00      
         C assumes int            01/01/70 00:00      
            Followed the advice of Michael Karas...            01/01/70 00:00      
               Why not assembly using?            01/01/70 00:00      
                  Assembler code            01/01/70 00:00      
            Well...            01/01/70 00:00      
               int            01/01/70 00:00      
                  Check Maxint ?            01/01/70 00:00      
                     Maxint            01/01/70 00:00      
                  Murdered quote            01/01/70 00:00      
   I2C code            01/01/70 00:00      
      Keil webpage            01/01/70 00:00      
         i2c simulator            01/01/70 00:00      
            Me to blame?            01/01/70 00:00      
               not blaming you!            01/01/70 00:00      
                  Michael B. made a very usefull tool!            01/01/70 00:00      
         hello            01/01/70 00:00      
            Not aware?            01/01/70 00:00      
               thank u            01/01/70 00:00      
                  Name confusion...            01/01/70 00:00      
               hi            01/01/70 00:00      
   Damned, damned, damned...            01/01/70 00:00      
      Ha, ha, ha, ha, ha ....            01/01/70 00:00      
      Calico            01/01/70 00:00      
         Pls. do so!            01/01/70 00:00      
      Keyboard Calico            01/01/70 00:00      
         Christmas            01/01/70 00:00      
            Maybe it was ....            01/01/70 00:00      
            Christmas Presents            01/01/70 00:00      

Back to Subject List