www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR DMX RXC Interrupt Problem


Autor: Stefan L. (db1sla)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
zu Lernen, AVR-Controller zu programmieren möchte ich mir gerne einen 
DMX-Empfänger bauen. Da habe ich nun folgendes Problem:

Mein Code muss irgendeinen Fehler haben, sodass der Controller nicht in 
die ISR springt. Dies habe ich getestet, inden ich in der ISR einen Pin 
anschalten wollte. Ich verwende einen ATMega8 mit AVRStudio und GCC.

Hier meine Röutine um den USART zu initialisieren:
void USART_init(void)
{
  UBRRL = BAUD_RATE;  //setze auf 250 kBaud
  UBRRH = 0;
  UCSRA = 0;       //lösche flags, schalte U2X aus
  UCSRB = (1<<RXCIE)|(1<<RXEN); //RXComplete Interrupt anschalten
                  //Receiver anschalten
  UCSRC  = (3<<UCSZ0);//8 Daten Bits, 1 Stop Bit, asynchron
  UDR = 0;       //Daten-Register initialisieren
}

und die ISR sieht so aus:
ISR(USART_RXC_vect){
  if(i > 100)
  {
  PORTB |= (1<<PB2);
  i = 90;
  }
  else
  {
  PORTB &= ~(1<<PB2);
  i = 110;
  }
}

i ist hier eine Testvariable, die in der main initialisiert wird. Ich 
dachte mir das dann so: Wenn ein gültiges Byte empfangen wird wird der 
Zustand von PB2 invertiert.
Lasse ich den Code der ISR in einer Endlosschleife des Hauptprogramms 
laufen, funktionierts, in der ISR nicht. Die DMX Daten bekomm ich von 
dem Interface von Digital Enlightenment, von dem ich weiß, dass es 
funktioniert.

Könnt ihr mir helfen?

Grüße,
Stefan

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
volatile

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

und zeig mal den ganzen Code.

Oliver

Autor: Hubert G. (hubertg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UCRSC ist nicht richtig initialisiert. Datenblatt lesen.

Autor: Holger Geisler (cyberhippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Stefan,
da du nicht den vollen code zeigst kann man ja nur raten. Aber es werden 
keine ISR ausgefuert wenn nicht global interrupts enabled sind dazu 
einfach

sei();

ans ende der init routine schreiben.
Und wie schon von Oliver oben gesagt 'i' sollte als 'volotile int i;' 
declariert werden damit es sowohl in main als auch in der ISR immer 
richtig gelesen wird.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Außerdem muss in der ISR das Datenregister des UART ausgelesen werden, 
ansonsten kommt der Interrupt immer wieder und wieder und wieder ....

Autor: Stefan L. (db1sla)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
erst mal danke für eure Antworten. Im Anhang habe ich mal meinen Code
hochgeladen, wie ich ihn ursprünglich vorgesehen habe. Ist im Prinzip
der gleiche wie der oben gepostete, der nur ein Testprogramm war.
sei(); hab ich im Hauptprogram ausgeführt und Variablen, die in
verschiedenen Funktionen verändert werden können sind volatile.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>    PORTB |= (1<<PCB2;

Ich bezweifle hiermit, daß das der Code ist den du wirklich benutzt.

Autor: Stefan L. (db1sla)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da hast du allerdings recht, es sollte heißen PORTB |= (1<<PB2); da 
haben sich die Finger auf der Tastatur wohl etwas überschlagen :-)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>da hast du allerdings recht, es sollte heißen PORTB |= (1<<PB2); da
>haben sich die Finger auf der Tastatur wohl etwas überschlagen :-)

Das macht doch nichts. Du kannst gerne weiter ungeprüfte
Codes posten. Nur wird sich wohl kaum noch jemand die
Mühe machen da mal einen Blick drauf zu werfen.

Autor: Stefan L. (db1sla)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hubert G. schrieb:
> UCRSC ist nicht richtig initialisiert. Datenblatt lesen.

Ich habe es mir nochmal angeschaut und hab die Register mal einzeln 
initialisiert.
void USART_init(void)
{
  UCSRA = 0;
  UCSRB = (1<<RXCIE)|
      (1<<RXEN)|
      (0<<UCSZ2); //8-Bit --> UCSRC
  UCSRC = (1<<URSEL)| //Zugriff auf UCSRC
      (0<<UMSEL)| //asynchroner Modus
      (1<<UCSZ1)| //8-Bit
      (1<<UCSZ0); //8-Bit
}
Ist das so richtig?

Grüße,
Stefan

Autor: Henne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Großen und Ganzen entspricht Deine ISR ja dem Verhalten von meiner 
Lib.
Da diese funktioniert, kannst Du ja beide vergleichen und schauen, wo es 
hakelt.

BTW:
Switch-Listen sind in ISRs meist suboptimal. Hatte ich auch mal 
verwendet und kostete >1us @8MHz. (Eine Ausnahme ist mein RDM-Handler: 
Hier dauerte mal das Durchhangeln der vielen if-Bedingungen länger...)

Wenn Du Data Overruns bekommst, ist eh alles zu spät. Evtl. macht 
während der Entwicklung eine Indizierung davon Sinn, falls es komische 
Fehler gibt. In diesem Fall müssten die anderen ISRs entschlackt werden.


Viel Erfolg,
Hendrik

Autor: Stefan L. (db1sla)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Hendrik,
vielen Dank für die nützlichen Tips. Da werd ich mich gleich mal 
dahinterklemmen.

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.