www.mikrocontroller.net

Forum: Compiler & IDEs uart problem


Autor: Freak (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du brauchst ein Handshake, an Hand dessen der Sender erkennt,
ob der Empfänger überhaupt schon wieder gewillt ist, etwas
entgegenzunehmen.  Andernfalls riskierst du, dass du den
Empfangspuffer mit neuem Kram zuknalls, während der AVR gerade
noch damit beschäftigt ist, die vorherige Aufgabe auszuführen.

Autor: Freak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
daran scheint es nicht zu liegen.
auch wenn ich einige zeit mit dem zweiten befehl warte, kommt es zu den
problemen.
also wenn er daten empfängt während von den Timern etwas ausgeführt
wird.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)?

Autor: Günni (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Freak (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Freak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es geht eigentlich nur um eine simple schrittmotorsteuerung.
Vielleicht kennt jemand gute quelltexte, wo ich mir das mal angucken
könnten.

m.f.G.
Freak

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.