AVR DMX RXC Interrupt Problem

OP #1330639
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
#1330840
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.
OP #1331557
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.
Angehängte Dateien:
Gast #1331616
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.
OP #1331745
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
Gast #1332498
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren