Forum: Mikrocontroller und Digitale Elektronik AVR DMX RXC Interrupt Problem


von Stefan L. (db1sla)


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:
1
void USART_init(void)
2
{
3
  UBRRL = BAUD_RATE;  //setze auf 250 kBaud
4
  UBRRH = 0;
5
  UCSRA = 0;       //lösche flags, schalte U2X aus
6
  UCSRB = (1<<RXCIE)|(1<<RXEN); //RXComplete Interrupt anschalten
7
                  //Receiver anschalten
8
  UCSRC  = (3<<UCSZ0);//8 Daten Bits, 1 Stop Bit, asynchron
9
  UDR = 0;       //Daten-Register initialisieren
10
}

und die ISR sieht so aus:
1
ISR(USART_RXC_vect){
2
  if(i > 100)
3
  {
4
  PORTB |= (1<<PB2);
5
  i = 90;
6
  }
7
  else
8
  {
9
  PORTB &= ~(1<<PB2);
10
  i = 110;
11
  }
12
}

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

von Oliver (Gast)


Lesenswert?


von Hubert G. (hubertg)


Lesenswert?

UCRSC ist nicht richtig initialisiert. Datenblatt lesen.

von Holger G. (cyberhippy)


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.

von Stefan E. (sternst)


Lesenswert?

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

von Stefan L. (db1sla)


Angehängte Dateien:

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.

von holger (Gast)


Lesenswert?

>    PORTB |= (1<<PCB2;

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

von Stefan L. (db1sla)


Lesenswert?

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

von holger (Gast)


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.

von Stefan L. (db1sla)


Lesenswert?

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

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

Grüße,
Stefan

von Henne (Gast)


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

von Stefan L. (db1sla)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.