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

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