??? 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 |
Topic | Author | Date |
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 |