Hallo allemaal ,

Ik ben voor de eerste keer aan het experimenteren met I2C communicatie.
Ik heb een atmega 32 over I2C gekoppeld aan een PCF8574AP Port Expander.

De bedoeling van de test is proberen 1 led aan te sturen.

De hardware is goed aangesloten , met de Led in "sink-configuratie" naar de port expander.
De led hangt aan PO van de expander.

Alleen krijg ik niets te zien , ik heb ook geen oscilloscoop , dus het is moeilijk te weten wat er werkt en wat niet.

Graag iemand die kan helpen.

De code :

#include <avr/io.h>


void port_expander_init(void)
{
	
	TWBR = 0x8E;	// snelheid instellen
	
}

void zend_start (void)
{
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // Start TWI , enable TWI , clear interupt
	
	while (!(TWCR & (1<<TWINT))); // wacht
}


void zend_stop (void)
{
	
	TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);	// Stop TWI , enable TWI , clear interrupt
}


unsigned char zend_byte (unsigned char byte)
{
	
	TWDR = byte;	// zet data in TWDR
	
	TWCR = (1<<TWINT) | (1<<TWEN);
	
	while (!(TWCR & (1<<TWINT)));	// wacht tot byte verzonden is
	return TWSR;
}


unsigned char zend_add_rw (unsigned char address , unsigned char rw)
{
	
	unsigned char addr_byte = 0; // adres 0..8
	
	addr_byte = address << 1; // adres 1 bit opschuiven
	
	
	addr_byte |= rw;	// read/write bit (1=read , 0= write)
	
	
	addr_byte |= 0b01000000; // 0b0100xxx0 --> adres van expander
	

	return zend_byte (addr_byte);
}



int main(void)
{
	port_expander_init();
	
	
	
	
	while(1)
	{
		zend_start();
		zend_add_rw(0b00000000, 0);
		zend_byte(0b00000000);
		zend_stop();
		
		for (int i=0; i<30000; i++);	
		
		
		
	}
}

Heb je het juiste doel adres opgegeven?
Heb je gezegt of het een schrijf of lees commando is?
Heb je een pull up weerstand (2K2) aan je SCL en SDA lijn hangen?
Heb je de A0, A1, en A2 goed aangesloten? Zie datasheet
http://www.nxp.com/documents/data_sheet/PCF8574.pdf

Dit zijn zomaar een paar dingen die heel belangrijk zijn, anders gaat het nooit werken.

Het doel-adres is 0 , want A0,A1 en A2 hangen op massa.
Het is een schrijf-commando ,want ik stuur 0 naar rw.

zend_add_rw(0b00000000, 0);

Pull-up weerstanden hanger er op.

Met de hardware is alles in orde

Nee dat bedoel ik niet, jou ic heeft zelf ook een adres.

In jou geval is dat adres 112 (BusOut %01110000)
Daar moet je mee beginnen, anders weet je ic niet of je het hem of met een ander wil communiceren.

Ik gebruik alleen picbasic, dus busout zal wel niet kloppen. :)

EDIT:
Voorbeeld is wel in basic.


BStart                         ; Start I2C bus
    BusOut %01110000           ; Zend doel adres [112]
    BusOut %11111111           ; Zend poort adres [alles uit]
    DelayMS tijd               ; Pauze
    BusOut %11111110           ; Zend poort adres [P0 is aan]
    DelayMS tijd               ; Pauze
    BusOut %11111111           ; Zend poort adres [alles uit]
    DelayMS tijd               ; Pauze
    BusOut %11111101           ; Zend poort adres [P1 is aan]
    DelayMS tijd               ; Pauze
    BusOut %11111111           ; Zend poort adres [alles uit]
    DelayMS tijd               ; Pauze
    BusOut %11111011           ; Zend poort adres [P2 is aan]
    DelayMS tijd               ; Pauze
    BusOut %11111111           ; Zend poort adres [alles uit]
    DelayMS tijd               ; Pauze
    BusOut %11110111           ; Zend poort adres [P3 is aan]
    DelayMS tijd               ; Pauze
    BusOut %11111111           ; Zend poort adres [alles uit]
    DelayMS tijd               ; Pauze
    BusOut %11101111           ; Zend poort adres [P4 is aan]
    DelayMS tijd               ; Pauze
    BusOut %11111111           ; Zend poort adres [alles uit]
    DelayMS tijd               ; Pauze
    BusOut %11011111           ; Zend poort adres [P5 is aan]
    DelayMS tijd               ; Pauze
    BusOut %11111111           ; Zend poort adres [alles uit]
    DelayMS tijd               ; Pauze
    BusOut %10111111           ; Zend poort adres [P6 is aan]
    DelayMS tijd               ; Pauze
    BusOut %11111111           ; Zend poort adres [alles uit]
    DelayMS tijd               ; Pauze
    BusOut %01111111           ; Zend poort adres [P7 is aan]
    DelayMS tijd               ; Pauze
    BusOut %11111111           ; Zend poort adres [alles uit]
    BStop                      ; Stop I2C bus

Inderdaad , bedankt.
De eerste digits van het IC-adres waren fout.

Nu werkt het perfect :)

Nou dat is mooi dat het werkt.

In het voorbeeld kan je alleen naar het ic schrijven, als je wil lezen komt er op bit_0 een 1 te staan.
Zo dus 01110001, nu kan je een lees actie doen uit je PCF8574AP.