- Labornetzteil AliExpress         
Ergebnis 1 bis 5 von 5

Thema: Twi Problem! Helft mir!

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706

    Twi Problem! Helft mir!

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hi Leutz,
    ich hab da ein Problem mit der TWI Kommunikation!
    Meine 2 Atmega32 sind über 2 Kabel verbunden(SDA - SDA / SCL -SCL)
    diese jeweils über nen 10KOhm zu VCC. Desweiteren hängt an jedem der µC an PortB 0 eine LED + Widerstand gegen GND.
    Hier der Mastercode:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    unsigned volatile char slave_adresse, daten, error;
    
    int twi_start(void);
    int twi_adresse(void);
    int twi_daten(void);
    void twi_stop(void);
    
    int main(void)
    	{
    	DDRB = 0x00;
    	TWAR = 0x01;
    	TWBR = 0xC;
    	slave_adresse = 0x02;
    	daten = 0x03;
    	for(;;)
    		{
    		error = twi_start();
    		error = twi_adresse();
    		error = twi_daten();
    		if(error == 1)
    			{
    			PORTB = (1<<PB0);
    			}
    		else
    			{
    			PORTB &= ~(1<<PB0);
    			}
    		}
    	}
    	
    	
    int twi_start(void)
    	{
    	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    	while (!(TWCR & (1<<TWINT)));
    	if ((TWSR & 0xF8) == 0x08)
    		{
    		return 0;
    		}
    	else
    		{
    		return 1;
    		}
    	}
    	
    int twi_adresse(void)
    	{
    	TWDR = slave_adresse;
    	TWCR = (1<<TWINT)|(1<<TWEN);
    	while(!(TWCR & (1<<TWINT)));
    	if ((TWSR & 0xF8) == 0x18)
    		{
    		return 0;
    		}
    	else
    		{
    		return 1;
    		}		
    	}
    	
    int twi_daten(void)
    	{
    	TWDR = daten;
    	TWCR = (1<<TWINT)|(1<<TWEN);
    	while(!(TWCR & (1<<TWINT)))
    	if ((TWSR & 0xF8) == 0x28)
    		{
    		return 0;
    		}
    	else
    		{
    		return 1;
    		}		
    	}
    	
    void twi_stop(void)
    	{
    	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
    	}
    und hier der Slavecode:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    unsigned volatile char slave_adresse, daten;
    
    
    int main(void)
    	{
    	sei();
    	DDRB = 0xFF;
    	PORTB &= ~(1<<PB0);
    	TWAR = 0x02;
    	TWBR = 0xC;
    	TWCR = (1<<TWEA)|(1<<TWEN);
    	TWSR &= 0b11111100;
    	for(;;)
    		{
    		if(daten == 0x03)
    			{
    			PORTB = (1<<PB0);
    			}
    		else
    			{
    			PORTB &= ~(1<<PB0);
    			}
    		}
    	}
    	
    SIGNAL (SIG_2WIRE_SERIAL)
    	{
    	if((TWSR & 0b11111000) == 0x80)
    		{
    		daten = TWDR;
    		}
    	TWCR |= (1<<TWINT);
    	}
    ich hoffe jemand blickt den Code und kann mir helfen! Helft mir!
    Gruß Michi

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.08.2004
    Ort
    Großbardorf
    Alter
    37
    Beiträge
    674
    Es kann sein, dass du "sei" nach dem Initialisieren des TWI machen musst, allerdings bin ich mir da nicht so sicher.
    Aber auf jeden Fall musst du beim slave am Anfang noch durch ein TWCR |= ( 1 << TWINT ) das TWI-Modul aktiv schalten. Der Befehl kommt hinter das "sei".

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi Pascal,
    danke für die Antwort!!
    Hat aber leider nichts gebracht!
    Findest du sonst noch Fehler in meinem Code?
    Gruß Michi

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.08.2004
    Ort
    Großbardorf
    Alter
    37
    Beiträge
    674
    Bei der Initialisierung des TWI beim client fehlt etwas. Du musst den TWI-Interrupt aktivieren, wenn du interruptbasiert arbeiten willst.
    Statt
    Code:
    TWCR = (1<<TWEA)|(1<<TWEN);
    müsstest du folgendes schreiben:
    Code:
    TWCR = (1<<TWEA)|(1<<TWEN) | (1<<TWIE);

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi Pascal,
    danke!! es funktioniert aber ich glaube mein Master sendet nur einmal und dann nicht mehr!! Mein aktueller Mastercode:
    Code:
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    
    unsigned volatile char slave_adresse, daten, error; 
    
    int twi_start(void); 
    int twi_adresse(void); 
    int twi_daten(void); 
    void twi_stop(void); 
    
    int main(void) 
       { 
       DDRB = 0x00; 
       TWAR = 0x01; 
       TWBR = 0xC; 
       slave_adresse = 0x02; 
       daten = 0x04; 
       for(;;) 
          { 
          error = twi_start(); 
          error = twi_adresse(); 
          error = twi_daten(); 
    	  twi_stop();
          if(error == 1) 
             { 
             PORTB = (1<<PB0); 
             } 
          else 
             { 
             PORTB &= ~(1<<PB0); 
             } 
          } 
       } 
        
        
    int twi_start(void) 
       { 
       TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); 
       while (!(TWCR & (1<<TWINT))); 
       if ((TWSR & 0xF8) == 0x08) 
          { 
          return 0; 
          } 
       else 
          { 
          return 1; 
          } 
       } 
        
    int twi_adresse(void) 
       { 
       TWDR = slave_adresse; 
       TWCR = (1<<TWINT)|(1<<TWEN); 
       while(!(TWCR & (1<<TWINT))); 
       if ((TWSR & 0xF8) == 0x18) 
          { 
          return 0; 
          } 
       else 
          { 
          return 1; 
          }       
       } 
        
    int twi_daten(void) 
       { 
       TWDR = daten; 
       TWCR = (1<<TWINT)|(1<<TWEN); 
       while(!(TWCR & (1<<TWINT))) 
       if ((TWSR & 0xF8) == 0x28) 
          { 
          return 0; 
          } 
       else 
          { 
          return 1; 
          }       
       } 
        
    void twi_stop(void) 
       { 
       TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); 
       }
    und der Slavecode:
    Code:
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    
    unsigned volatile char slave_adresse, daten; 
    
    
    int main(void) 
       { 
       sei(); 
       DDRB = 0xFF; 
       PORTB &= ~(1<<PB0); 
       TWAR = 0x02; 
       TWBR = 0xC; 
       TWCR = (1<<TWEA)|(1<<TWEN)|(1<<TWIE); 
       TWSR &= 0b11111100; 
       TWCR |= (1<<TWINT);
       for(;;) 
          { 
          if(daten == 0x03) 
             { 
             PORTB = (1<<PB0); 
             } 
          else 
             { 
             PORTB &= ~(1<<PB0); 
             } 
          } 
       } 
        
    SIGNAL (SIG_2WIRE_SERIAL) 
       { 
       if((TWSR & 0b11111000) == 0x80) 
          { 
          daten = TWDR; 
          } 
    	else
    		{
    		daten = 0x00;
    		}
       TWCR |= (1<<TWINT); 
       }
    mal schauen was ich noch verändern muss!
    Ok ich hab auf dem einen Atmega den Slavecode und auf dem anderen den Mastercode der sendet aber dann 0x04 statt 0x03 daher muss die LED am Slave aus sein. Wenn ich dann beide Boards ausschalte und dann zuerst den Slave einschalte(einschalten heißt Strom an) und den Master klappt alles gut denn die LED am Slave leuchtet nicht. Die beiden Boards bleiben eingeschaltet und ich ändere den Mastercode so um dass der Master ab nun nicht mehr 0x04 sendet sondern 0x03. Daher müsste nachdem der Controller geproggt worden ist die LED am Slave angehen, tut sie aber nicht!! Erst wenn ich dann wieder beide Boards ausschalte und dann den Slave zuerst und dann Master wieder einschalte leuchtet die LED! Ich muss beide komplett auschalten!

    Dadurch denk ich mal klar dass mein Master nur einmal sendet und dann nicht wieder!! Ich glaub ich muss meinen Code bisschen umändern!!
    Gruß Michi

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad