PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : TWI - Slave Receiver Mode



Fro
16.07.2005, 18:21
Hallo!

Ich arbeite mich gerade in TWI ein. Ich habe folgendes Ziel: Per TWI von einem Atmega8 (master) einen zahlenwert zu einem anderen Atmega 8 (slave) zu senden.

Zum Master gibt es ja genügend tutorials hier und ich glaube dass der bisher steht. Nur beim Slave bin ich mir nicht sicher, da sind auch die Hilfen relativ dünn gesät und dass Datenblatt hilft mir nicht wirklich weiter.

Folgendes habe ich bisher (ein Teil des Codes ist aus einem Post hier im Forum entnommen - sollte ich damit jemand auf den Schlipps treten bitte ich um Verzeihung). Es wäre nett, wenn ihr mal drübergehen könntet und mich auf Probleme oder Fehler hinweisen würdet.


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

volatile uint8_t adresse = 2;

void twi_init(void){
TWAR = (1<<TWA0); //Das Slave-Adressenregister des Atmega 8 kriegt hier den Wert 2 zugewiesen - Slave hat den Wert 2
TWCR = (1<<TWEA)|(1<<TWEN); //TWEN enables TWI, TWCR aknowledges the slave adress
}

uint8_t receive_i2c(void){
TWDR = (adresse << 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
}



void main(void){
twi_init();
uint8_t minuten;
minuten = 0;
for(;;){
minuten = receive_i2c();
}
}

Fro
22.07.2005, 14:28
So mittlerweile hat sich das mit dem Slave erübrigt.

Jetzt stehe ich vor einem neuen Problem. Nachdem ich das Start-Signal und danach die Adresse gesendet habe, hängt er an der Überprüfung der Übertragung nach dem Daten-Byte, sprich an dem

while (!(TWCR & (1<<TWINT)));

Weiß jemand woran das liegen kann?

Hier noch der Slave-Code

/*Zeitanzeigetafel - hierrein soll nur der Code der den per TWI übergebenen TWI-Minuten und Sekundenwert angezeigt werden */

#include <avr/io.h>

#include <avr/interrupt.h>
#include <avr/signal.h>

volatile uint8_t sekunden;


//Interruptroutine des TWI
SIGNAL (SIG_2WIRE_SERIAL){
PORTD = (1<<PD7);
//hier wird das TWSR darauf geprüft, ob 0x80 darin steht, dieser Wert bedeutet, dass Daten
//empfangen wurden, 0x60 würde zB bedeuten, dass er addressiert wurde und dies bestätigt hat
if((TWSR & 0b11111000) == 0x80){
//hier Code einfügen, der bearbeitet werden soll, die empfangenen Daten kann man aus
//TWDR auslesen
sekunden = TWDR;

}

//wenn der Interrupt ausgelöst wird, wird der TWI des µC blockiert, damit man die Daten
//verarbeiten kann
//um ihn wieder zu aktivieren, muss man eben folgenden Befehl ausführen
TWCR |= 0b10000000;
}

int main(void){

DDRD = 0xFF;

//diese 6 Zeilen Code sind für das Initialisieren des TWI-Moduls zuständig, also kommt das Stück
//Code am besten irgendwo in die Mainmethode vor die Endlosschleife

//hier wird die Addresse des µC festgelegt(in den oberen 7 Bit, das LSB(niederwertigstes Bit) steht dafür, ob der µC auf einen general call //reagiert
TWAR = 0x02;
//TWI Control Register, hier wird der TWI aktiviert, der Interrupt aktiviert und solche Sachen
TWCR = 0b01000101;
//TWI Bitrate Register, für die Frequenz des TWI wichtig
//TWBR = 0xC;
//TWI Status Register, die 2 niederwertigsten sind für den Prescaler zur Taktberechnung, aus den
//anderen kann man auslesen, was genau passiert, wenn ein Interrupt ausgelöst wird, es gibt nämlich
//für den TWI nur einen
TWSR = 0b11111100;
//hier werden Interrupts global aktiviert
sei();
//hier wird das TWI-Modul aktiv geschalten, ab hier man den µC per TWI ansteuern, den Befehl aber
//auf jeden Fall hinter das "sei();", da es sonst nicht geht
TWCR |= 0b10000000;

PORTD = (1<<PD6);
for (;;){

PORTD |= sekunden;
}
}

Fro
23.07.2005, 09:09
Kann mir wirklich keiner helfen? Ist die Frage zu allgemein gestellt?

darwin.nuernberg
23.07.2005, 10:22
selbst ausprobiert habe ich es (noch) nicht,

Aber es gibt für TWI (I²C) Slave eine spezielle LIB.
Die musst Du anstelle der Master - Lib verwenden.
(Master-Lib durch Slave-Lib ersetzten)

Schau Dir mal die MCS Electronics TWI-slave demo an (TWI-slave.bas)
die ist in den Samples.