-         

Ergebnis 1 bis 4 von 4

Thema: TWI - Slave Receiver Mode

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.01.2005
    Beiträge
    18

    TWI - Slave Receiver Mode

    Anzeige

    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.

    Code:
    #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();
    	}
    	}

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    23.01.2005
    Beiträge
    18
    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
    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;
    	}
    }

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    23.01.2005
    Beiträge
    18
    Kann mir wirklich keiner helfen? Ist die Frage zu allgemein gestellt?

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von darwin.nuernberg
    Registriert seit
    08.08.2004
    Ort
    A, A
    Alter
    53
    Beiträge
    1.305
    Blog-Einträge
    1
    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.
    Gruss
    Darwin (meine Projekte sind auf meiner Pinnwand zu finden)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •