PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : microsps_pcf8574p(TWI) senden funktioniert nicht



atan09
28.10.2009, 20:54
Hallo!

Zuerst mal die Hardware: microsps mit atmega32 und microsps 12/4 I/OModul mit 2 pcf5874p i2c expander

Problem:Meine Intention ist es den IC2 anzusprechen, da an diesem 4 Relais und 4 LEDs hängen. (pcf8574p)

Ich will alle LEDs zum leuchten bringen (fürs erste).
Leider funktioniert dies nicht so, wie ich es mir vorstelle.

Ich habe herausgefunden, dass der A0-Eingang an +5 V liegt, wie wirkt dies dann auf die Slaveadresse aus(IC2-Baustein)? Und A0 an 0 V (vom IC1). (und einen Schalter mit A1 und A2)

die Grundadresse ist ja bekanntlicherweise laut datasheet 0x40...


Hier mein Quellcode (zusammengeschnipselt aus diversen Büchern):




// ATmega32 TWI-Schnittstelle PCF8574P
//Ziel: alle LEDs an RE sollen leuchten
// Port C: PC1 = SDA -> Stift 15 PC0=SCL -> Stift 14 PCF8574P

#include <avr/io.h> // Deklarationen
#define TAKT 3686400UL // Systemtakt 3.6864 MHz
#define AUSAD 68 // Adresse Ausgabeeinheit PCF8574P(Grundadresse 0x40+A0)
#define FAKTOR 44 // Teilerfaktor für 10 kHz Bustakt
#define TEILER 1 // Vorteiler TWPS = 1
void init(unsigned char faktor, unsigned char teiler) // TWI initialisieren
{
TWBR = faktor; // Bitrate
TWSR = teiler; // Vorteiler
}
void send(unsigned char adres, unsigned char daten) // Zeichen senden
{
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Startbedingung
loop_until_bit_is_set(TWCR, TWINT); // warte bis fertig
TWDR = adres; // Adresse
TWCR = (1 << TWINT) | (1 << TWEN); // senden
loop_until_bit_is_set(TWCR, TWINT); // warte bis fertig
TWDR = daten; // Daten
TWCR = (1 << TWINT) | (1 << TWEN); // senden
loop_until_bit_is_set(TWCR, TWINT); // warte bis fertig
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // Stoppbedingung
}
unsigned char empf(unsigned char adres) // Zeichen empfangen
{
unsigned char daten; // Hilfsvariable
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Startbedingung
loop_until_bit_is_set(TWCR, TWINT); // warte bis fertig
TWDR = adres; // Adresse
TWCR = (1 << TWINT) | (1 << TWEN); // senden
loop_until_bit_is_set(TWCR, TWINT); // warte bis fertig
TWCR = (1 << TWINT) | (1 << TWEN); // Empfang starten
loop_until_bit_is_set(TWCR, TWINT); // warte bis fertig
daten = TWDR; // Daten abholen
TWCR = (1 << TWINT) | (1 << TWEA) | (1 << TWEN); // ACK-Impuls senden
loop_until_bit_is_set(TWCR, TWINT); // warte bis fertig
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // Stoppbedingung
return daten;
}
void main (void) // Hauptfunktion
{
unsigned char awert; // Zwischenwert für Test

init(FAKTOR, TEILER); // TWI Bustakt Initialisierung
while (1) // Arbeitsschleife
{

awert = 0xff;
send(AUSAD, ~awert); // Komplement senden da Buslogik invers ist
} // Ende while
} // Ende main



PS freu mich über jede Hilfe und bedanke mich im Voraus, da ich neu in dem Bereich bin....

Gruß
atan09

Marten83
02.11.2009, 12:33
Hallo atan09,

zuerst muss man mal wissen ob du wirlich den PCF5874 oder den PCF5874A hast.
Wenn das schonmal geklärt ist, musst du dir sicher sein welcher der Adresspins (A0 bis A2) auf welches Potential gezogen ist.
Du hast geschrieben, dass dein Baustein Pin A0 auf 5V und A1 und A2 an einem Schalter. Wie stehen denn die Schalter?
Dann sehen deine Routinen zum Senden und Empfangen ziemlich unübersichtlich aus.
Hast du schonmal eine lib von z.B. Peter Fleury versucht?

Falls du alles selber programmieren willst, verstehe ich das, aber zum Testen würde ich mal eine fertige nehmen.

Das ganze gibt es auch noch interruptgesteuert als Beispiel direkt von Atmel (AVR315).

Probiers mal.

MfG, Marten83