uart problem

Gast #364113
Lesenswert?
• ▲
▼
Hallo,

ich bin relativ neu in der AVR programmierung.
ich sende meine Befehle für den controller (Atmega8515) per USART.
zur zeit besteht ein befehl aus 7 bytes.
Wenn ich jedoch vom pc 2 befehle schnell hintereinander sende, geht
anscheinend alles durcheinander.befehle werden falsch oder garnicht
mehr ausgeführt

folgendes system verwende ich:

uint8_t bytesReceived = 0;
uint8_t receiveBuffer[7];

//Einsprungpunkt der UART Empfangsroutine
ISR(UART_RX_vect) {
  receiveBuffer[bytesReceived] = UDR;
  bytesReceived++;

  if (bytesReceived == 7) {
  ...
  bytesReceived = 0;
  }
}

Die eigentliche abarbeitung der Befehler erfolgt nicht im
empfangsinterrupt. sondern wird von einem timer nebenbei erledigt.
woran kann das liegen?
baudrate ist richtig eingestellt. (vom controller an den PC senden
funktioniert reibungslos...)

was geschiet mit bytes die empfangen werden, während eine interrupt
routine des timers arbeitet? dann scheint der fehler aufzutreten.
Gast #364116
Lesenswert?
• ▲
▼
In welchem Interruptlevel (Priorität) läuft dein UART und in welchem
dein Timer? Sperrst du in der Timerroutine die Interrupts? Alle (böse)
oder nur per Interruptmaske einige z.B. den Timer (Gut)?
Gast #364117
Lesenswert?
• ▲
▼
Hallo,

u.U. manipulierst Du den Buffer für den Befehl, bevor er abgearbeitet
wurde.
Du mußt sicherstellen, dass der Befehl abgearbeitet wurde bevor neue
Daten in den Buffer geschrieben werden.
Um Zeit zu gewinnen kannst Du den Buffer bei Vollständigkeit in einen
"Abarbeitungsbuffer" kopieren.

Grüße
Günni
Gast #364118
Lesenswert?
• ▲
▼
so wie ich es gelesen hab, sorgt der gcc compiler dafür, dass die
interrupts global deaktiviert werden, wenn einer ausgelöst wird, und
nach abschluss der ISR aktgiviert der compiler sie wieder.
Gast #364120
Lesenswert?
• ▲
▼
>...sorgt der gcc compiler dafür, dass
>die interrupts global deaktiviert werden...

Das stimmt so nicht ganz. Das globale Interrupt Disable während der
Ausführung einer ISR macht nicht der Compiler, sondern die Hardware des
µC. Die kann man 'überlisten', indem man am Anfang der ISR die
Interrupts wieder freigibt (entweder manuell mit sei() oder durch
Verwendung von __attribute__((interrupt)) anstelle von 'ISR' zum
Einleiten der ISR), was man allerdings nur dann tun sollte, wenn man
sich über die möglichen Folgen im Klaren ist.

Möchte man verhindern, dass ein Interrupt, der während einer bestimmten
Aktion aufgetreten ist, nach Beendigung dieser Aktion nicht bearbeitet
wird, dann genügt es nicht, den Interrupt während der Aktion zu
deaktivieren, sondern man muss, bevor man ihn wieder aktiviert, das
entsprechende Flag löschen. Tut man das nicht, wird der Interrupt
sofort nach der Reaktivierung bearbeitet!

Gruß

Johnny
Gast #364121
Lesenswert?
• ▲
▼
>...sorgt der gcc compiler dafür, dass
>die interrupts global deaktiviert werden...

Das stimmt so nicht ganz. Das globale Interrupt Disable während der
Ausführung einer ISR macht nicht der Compiler, sondern die Hardware des
µC. Die kann man 'überlisten', indem man am Anfang der ISR die
Interrupts wieder freigibt (entweder manuell mit sei() oder durch
Verwendung von __attribute__((interrupt)) anstelle von 'ISR' zum
Einleiten der ISR), was man allerdings nur dann tun sollte, wenn man
sich über die möglichen Folgen im Klaren ist.

Möchte man verhindern, dass ein Interrupt, der während einer bestimmten
Aktion aufgetreten ist, nach Beendigung dieser Aktion bearbeitet wird,
dann genügt es nicht, den Interrupt während der Aktion zu deaktivieren,
sondern man muss, bevor man ihn wieder aktiviert, das entsprechende Flag
löschen. Tut man das nicht, wird der Interrupt sofort nach der
Reaktivierung bearbeitet!

Gruß

Johnny

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.