PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Twi, wie liest der Master vom Bus?



batti112
30.12.2004, 15:41
Hi!
Ich baue gerade einen I2C Bus auf, dank der vielen wirklich guten Tutorials scheint das sehr einfach zu sein. Allerdings habe ich noch nichts gefunden wo ein Master vom Bus liest.

Ich habe mal angefangen mir die wichtigsten Funktionen zu bauen,
aber gerade bei der lese-Funktion bin ich mir doch sehr sehr unsicher...

Würde mich sehr freuen wenn sich jemand das mal ansieht, und mich vll. berichtigt, oder mir vll. ne gute Seite empfielt...


Gruss
Bastian



#include <avr/twi.h>
#include <avr/io.h>

void i2cStart()
{
// TWINT = Enables the TWI Interrupt Flag
// TWSTA = Writes the TWI Start Condition Bit into the Bus (Master)
// TWEN = Enables the TWI Hardware
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))); //wait until the Bus is not ready
}

void i2cStop()
{
// TWINT = Enables the TWI Interrupt Flag
// TWSTO = Writes the TWI Stop Condition Bit into the Bus (nolonger Master)
// TWEN = Enables the TWI Hardware
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //Send Stop
}

void i2cSendData(unsigned char address,unsigned char data)
{
TWDR = address << 1; //load Slave Address + Write in TWDR
TWCR = (1<<TWINT)|(1<<TWEN); //clear Bits to start transmission
while (! (TWCR & (1<<TWINT))); //wait until the Bus is not ready
TWDR = data; //load data in TWDR
TWCR = (1<<TWINT)|(1<<TWEN); //clear Bits to start transmission
while (! (TWCR & (1<<TWINT))); //wait until the Bus is not ready
}

//????????????????????????????????????????????
unsigned char i2cReadData(unsigned char address)
{
TWDR = (address << 1) + 1; //load Slave Address + Read in TWDR
TWCR = (1<<TWINT)|(1<<TWEN); //clear Bits to start transmission
while (! (TWCR & (1<<TWINT))); //wait until the Bus is not ready
TWCR = (1<<TWINT)|(1<<TWEN); //clear Bits to start transmission
while (! (TWCR & (1<<TWINT))); //wait until the Bus is not ready
return TWDR; //return TWDR
}

30.12.2004, 16:15
Der Master erzeugt Lesezyklen, übernimmt die Daten und stellt sie dann im Datenregister der Anwendersoftware zur Verfügung.

Pascal
30.12.2004, 17:13
hast du schonmal ins Datenblatt des ATMEGA8/16 usw. geschaut, da steht das ganze sehr ausführlich und verständlich drin

batti112
31.12.2004, 00:07
Nun gut, werde das wohl so hinbekommen.
Scheitere jetzt nur an einem anderen Problem.

Sobald ich meine Funktion i2cStart() aufrufe
und TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); ausgeführt wurde
läuft das Programm in die Endlosschleife da das TWINT-Bit nicht gesetzt wurde.

Nach der schlauen Literatur bedeutet dies doch das kein "START" gesendet werden konnte, dass also der Bus nicht bereit war.
Dies deutet dann doch auf einen Hardware-Fehler, wenn mein Bus nur einen Master enthält (im "Bus" sind nur der Atmega32 und ein PCF8574).

Grundsetzlich müsste aber doch auch ein "Start" gesendet werden können, wenn gar keine Slaves im Bus existieren, oder?
Denn auch dieses funktioniert nicht.

Ich fürchte an dieser Stelle hilft mir kein Tutorial weiter...

Gruss

Bastian

31.12.2004, 08:48
Hast du Pull-UpWiderstände ordentlich an die Busleitungen geschalten?
Falls du Interrupts freigegeben hast (sei()), existiert für das TWI eine ISR?

Ansonsten schau mal hier: www.mc-project.de unter der Rubrik ICs&Co ist der von dir verwendete Baustein samt Code beschrieben.

batti112
31.12.2004, 10:00
ja, ich hab Interrupts freigegeben.
Aber diese sind doch unabhängig von den Interrupts des µC wenn ich bei diesem das Interrupt Enable Flag nicht gesetzt habe.

Als Pullups nutze ich zwei 10k Ohm Widerstände.
Danke für den Link!
Dort scheint es alles zu geben, was ich so brauchte.

MfG
Bastian

31.12.2004, 11:25
10K sollte ok sein (ich verwende meist 4,7K), welche Datenrate verwendest du?

batti112
31.12.2004, 11:42
Woran kann es liegen, das ich kein Start senden kann???
bekomme das TWINT-Bit nicht gesetzt.
Im Bus existieren nur ein PCF8574 und ein PCF8591.

batti112
31.12.2004, 11:45
setze den TWBR auf 15 ( TWBR = 0x10 )

batti112
31.12.2004, 11:46
ach ja, und der µC läuft mit 16Mhz

Kjion
31.12.2004, 12:10
Es gibt übrigens einen Edit Button ... ansonsten gibt das immer so endloslange Threads in denen eigentlich nix drinnsteht ... wollte nur mal so draufhinweisen ...

Pascal
31.12.2004, 12:39
wo ist denn der Code für das Initialisieren des TWI?
wenn da was falsch gemacht wird, geht nicht viel

schau mal in den Thread "Fragen zu TWI", darin hab ich Code für den Master sowie den Slave gepostet, der bei mir funktioniert

und so nebenbei...0x10 ist nicht 15, sondern 16...

batti112
31.12.2004, 13:57
Also ich habe mal Teile deines Master_Progs genommen, das Problem bleibt bestehen, kann es ein Hardware-Problem sein?
Wie sieht das mit dem START aus, wenn garkein Bus angeschlossen ist?
(denn das funktioniert ja auch nicht)

batti112
31.12.2004, 14:14
Bin gerade auf etwas interessantes gestoßen,
der µC scheint defekt zu sein.
Grundsätzlich kann ich PC0 nicht als Eingang oder Ausgang nutzen (unabhängig vom TWI). Habe den Port bis jetzt noch nicht genutzt, deswegen ist mir das nie aufgefallen. PC1-PC7 kann man normal auf log. High setzen, PC0 nicht.
Da scheint wohl mein Atmega32 kaputt zu sein.

Naja, ich wünsche allen einen guten Rutsch ins neue Jahr!!!!!

Bastian

Pascal
31.12.2004, 14:59
spontan fällt mir ein, dass das mit dem JTAG zu tun haben könnte, das ist ab dem ATMEGA16 vorhanden und standartmäßig aktiviert, wenn man es nicht deaktiviert, machen die Pins komische Sachen(das JTAG dürfte an PORT C liegen)

ich werd mir das in den nächsten Tagen nochmal anschauen, aber jetzt muss ich weg...

ich wünsch euch allen auch einen guten Rutsch
Pascal