Forum: Mikrocontroller und Digitale Elektronik I2C atmega interrupt geht nicht


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von der_elektro_thorben (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
hallo liebe elektro kollegen,


ich hab da ein problem mit i2c. alles läuft soweit zwischen meinen 2 
atmegas (schreiben und lesen bei beiden), jedoch wird bei beiden kein 
interrupt ausgelöst. zuerst klatsche ich cli(), danach initialisiere ich 
I2C und anschließend sei(). interrupt-bit ist während der I2C init. 
gesetzt.

es soll eine led blitzen, dann 1000 ms warten und wieder blitzen.

jeweils beim slave und master passiert es nicht.

meine funkktionskopf sieht so aus für das interrupt:

ISR(TWI_vect).


danke liebe kollegen, ich liebe euch alle

von Ruhmtreiber (Gast)


Bewertung
0 lesenswert
nicht lesenswert
der_elektro_thorben schrieb:
> danke liebe kollegen, ich liebe euch alle

Ja bitteschön gerne, Herr Kollege .....  aber wofür?

von c-hater (Gast)


Bewertung
0 lesenswert
nicht lesenswert
der_elektro_thorben schrieb:

> zuerst klatsche ich cli(), danach initialisiere ich
> I2C und anschließend sei().

Schön, damit sind also global die Interrupts enabled. Das ist schonmal 
eine wichtige Voraussetzung dafür, dass überhaupt irgendein Interrupt 
ausgelöst werden kann.

> interrupt-bit ist während der I2C init.
> gesetzt.

Welches Interupt-Bit ist da gesetzt? Das globale ja wohl nicht, dem 
widerspräche deine obige Aussage. Bleibe also nur das lokale für I2C. 
Aber welches, das Masken-Bit oder das Flag-Bit?
Und übrigens, egal welches von beiden: Das IST sicher keinesfalls 
gesetzt, während I2C init, bestenfalls WIRD das Richtige von beiden 
im Zuge der Initialisierung irgendwann von deinem Code gesetzt.

Nun brauchst du also nur noch zu zeigen, wo und wie du das machst...

von der_elektro_thorben (Gast)


Bewertung
0 lesenswert
nicht lesenswert
danke für die antworten, kollegen.

ich erkläre kurz mal, wie ich es gemacht habe.

zuerst setze ich die frequenz, was auch klappt.

anschließend wird das TWIE bit in TWCR gesetzt.

so sieht mein befehl, nachdem die frequenz gesetzt wurde, aus:

TWCR |= (1 << TWIE);


beim master klappt es soweit, jedoch beim slave nicht.
der reagiert nicht dadrauf.

löst sich der interrupt aus, wenn die übertragung (lesen und schreiben) 
erfolg ist?


besten dank

der thorben

von Karl H. (kbuchegg) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
der_elektro_thorben schrieb:
> danke für die antworten, kollegen.
>
> ich erkläre kurz mal


erkläre es nicht, zeig einfach den Code.

von der_elektro_thorben (Gast)


Bewertung
0 lesenswert
nicht lesenswert
okay, kann ich machen, muss mich auch korrigieren, geht beim master auch 
nicht

hier ist die initialisierungs funktion:

//////////////////////////////////////////  TWI_M_init  //////////////////////////////////////////
  
  /*
  generates bit rate in kHz, max 400 kHz 
  */
  int8_t TWI_M_init(uint32_t f_cpu, uint16_t f_scl, uint8_t twi_interrupt_enable)
  {
  
      if(f_scl > 400)
      {
        
        return FREQUENCY_SCL_TOO_HIGH;
        
      }
  
      if( ( f_cpu / (f_scl*1000) ) < 16 )
      {
        
        return FREQUENCY_SCL_NOT_RIGHT;
        
      }
    
    uint8_t twbr = ( ( f_cpu / (1000*f_scl) ) - 16 ) / 2;
    
    TWCR |= (twi_interrupt_enable << TWIE);
    
      if( twbr <= 255)
      {
      
        TWBR = twbr;
      
        return BITRATE_IS_INIT;
      
      }
    
    return SETTING_TWBR_GONE_WRONG;  
  
  }

//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$


von spess53 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi

>beim master klappt es soweit, jedoch beim slave nicht.
>der reagiert nicht dadrauf.

Kann auch nicht. Im Slavemode wird das von der Hardware bedient.

MfG Spess

von der_elektro_thorben (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das steht bei mir in der main datei:
cli();
  
      if(TWI_M_init(F_CPU, 100, TWIE_ENABLE) == BITRATE_IS_INIT)
      {
      
        sendStringToPos("init succeed", 1, 1); // LCD display
      
      }  
  
  sei();


So sieht meine ISR funktion aus:

die toggle funktion funktioniert auch

ISR(TWI_vect)
{
  
  toggle_yellowLED(); // LED toggle
  
  
}


von der_elektro_thorben (Gast)


Bewertung
0 lesenswert
nicht lesenswert
TWIE_ENABLE ist 1 bei mir

nachdem ich zum slave was sende und dieser korrekt reagiert, toggled die 
LED nicht.

von A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
der_elektro_thorben schrieb:
>     uint8_t twbr = ( ( f_cpu / (1000*f_scl) ) - 16 ) / 2;
>       if( twbr <= 255)

Das ist für die Tonne, weil ein uint8_t Wert immer <= 255 ist.

von c-hater (Gast)


Bewertung
0 lesenswert
nicht lesenswert
der_elektro_thorben schrieb:

> TWCR |= (1 << TWIE);

Das sieht irgendwie richtig aus.

Aber: Hast du auch TWEN gesetzt? Das ist zwingend erforderlich. Wenn die 
Hardware überhaupt nicht läuft, kannst die Interrupt-Masken setzen, 
soviel du willst, der Interrupt wird sicher niemals ausgelöst werden.

Ganz analog z.B. zur UART. Da kannst du RXCIE und TXCIE setzen bis zum 
Abwinken, wenn nicht gleichzeitig auch TXEN und RXEN gesetzt ist, 
passiert da garnix.

Fuck: RTFM.

von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Scheinbar habt ihr alle bessere Glaskugeln wie ich :-(

Das ist gemein! (Wo kann ich mich beschweren?)

Vielleicht kann der TO für Chancengleichheit sorgen, wenn er den 
kompletten Code veröffentlicht?

von der_elektro_thorben (Gast)


Bewertung
0 lesenswert
nicht lesenswert
ja danke für das mit tbwr, du hast recht, ist sinnlos.

ich kann, wenn ihr wollt, auch den ganzen code senden.


dank euch allen

von der_elektro_thorben (Gast)


Bewertung
0 lesenswert
nicht lesenswert
ich probiere später es mit twint auch nochmal, dachte man muss twint 
nicht setzen und es setzt sich von allein.


schaue dann und schreibe später, obs so geht

von der_elektro_thorben (Gast)


Bewertung
0 lesenswert
nicht lesenswert
sorry, will nicht vollspawnen, aber das mit twbr und der if abfrage 
mache ich, aufgrund der rechnung von oben :D. mein vorheriger post war 
nicht korrekt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.