View previous topic :: View next topic |
Author |
Message |
The Puma
Joined: 23 Apr 2004 Posts: 227 Location: The Netherlands
|
Help with reading ports from pcf8574 |
Posted: Sun Mar 19, 2006 7:06 am |
|
|
I need some help with reading state of the IO ports of the Pcf8574
Code: | #ifndef PCF8574A_SDA
#define PCF8574A_SDA PIN_C4
#define PCF8574A_SCL PIN_C3
#endif
#use i2c(master,sda=PCF8574A_SDA,scl=PCF8574A_SCL,FORCE_HW)
#define PCF8574A_WRITE_ADDR 0x70
#define PCF8574A_READ_ADDR 0x71
void pcf8574_get_io() {
int io_field;
i2c_start();
i2c_write(PCF8574A_READ_ADDR);
io_field=i2c_read();
i2c_stop();
} |
The value of the var io_field give only the hex value 0x80 if the port P0 = 5v
Other pins give no value |
|
|
Ttelmah Guest
|
|
Posted: Sun Mar 19, 2006 9:08 am |
|
|
Have you been doing any other I/O to the chip?.
The response suggests that the pins are programmed low. To work as inputs, the pins must be programmed high. This should be the default on power on, but if you have done any other I/O, should be set before trying to read. Note that you should NACK the last byte you read from the chip. Note that the chip also returns the 'last' value, and you should read a second time, if you want the 'current' value on the pins.
Best Wishes |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sun Mar 19, 2006 9:38 am |
|
|
Quote: |
#define PCF8574A_WRITE_ADDR 0x70
#define PCF8574A_READ_ADDR 0x71
|
PCF8574A have Slave Addresses in the range 0x38-0x3F ONLY.
Humberto |
|
|
Ttelmah Guest
|
|
Posted: Sun Mar 19, 2006 9:51 am |
|
|
The _A_ versions, have alternate slave addresses. The standard chips (non A), have slave addresses, 0x40 to 0x4E. The 'A', has slave addresses 0x70 to 0x7E. Look at figure 10 in the data sheet.
Best Wishes |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
|
The Puma
Joined: 23 Apr 2004 Posts: 227 Location: The Netherlands
|
|
Posted: Sun Mar 19, 2006 10:21 am |
|
|
I have found it.
The i2c address has the same then the SAA1064 i2c address
I have changed the i2c adress to 0x76 and it works
Thx all |
|
|
The Puma
Joined: 23 Apr 2004 Posts: 227 Location: The Netherlands
|
|
Posted: Sun Mar 19, 2006 11:32 am |
|
|
Last question
How to implement "per bit" port control???
Code: | // note: in order to implement "per bit" port control, it will be necessary
// to first read all bits, and then OR that value with the bit you are
// trying to toggle. otherwise, you'll just end up overwriting adjacent
// io bits and thus inadvertently changing other io lines.
int i2c_pcf8574_set_io(int device_type, int device_addr, int io_field) {
int addr_mask;
addr_mask=i2c_addr_mask(device_addr);
i2c_start();
i2c_write(device_type | addr_mask | I2CWRITE);
i2c_write(io_field);
i2c_write(io_field);
i2c_stop();
return(io_field);
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Sun Mar 19, 2006 11:47 am |
|
|
Humberto. Look at the actual wiring illustration under the TI address table. It shows the same addresses as the Philips sheet, and I know that the Philips addresses do work!.
It turns out the problem was an 'address clash'.
The [spam].
You don't implement 'per bit' control. The comment in the code section makes this clear. You read the byte, change the bit you require, and write the whole byte back. Gives the 'effect' of per bit control. Alternatively, to give 'per bit' output only, use the same trick as is regularly used on the PIC. Have a 'shadow' register, and keep a copy of what you are writing in this, then to do 'per bit' control, just change the required bit here, and write this.
Best Wishes |
|
|
|