www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit UART


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe ein kleines Problem mit meiner seriellen Schnittstelle. Und 
zwar sende ich einen String von einem Terminalprogramm in meinen µC. 
Dort angekommen wird dieser in einer Variable gespeichert und sofort 
wieder an das Terminal zurückgegeben. Nur unterscheidet sich der 
gesendete String sehr vom empfangengen, obwohl diese identisch sein 
müssten. Es ist, als ob der µC den String "durcheinander würfelt". Auch 
die Länge stimmt nicht überein. Was könnte da sein?

Ich programmiere den ATmega8 in BASCOM!

Vielen Dank für eure Hile!!

mfg
Andy

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was könnte da sein?

Alles mögliche.
Angefangen von falschen Baudraten, einem Quarz der nicht
aktiviert ist, bis hin zu einem Programmfehler.

> Ich programmiere den ATmega8 in BASCOM!
Duck und wech.


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, die Baudraten stimmen und der Quarz ist auch richtig aktiviert. 
Der serielle Interrupt sieht folgendermaßen aus:


Onserial:
  Daten = Inkey()

  Buf = Buf + Chr(daten)
  Print Buf
Return


Alos denkbar einfach. Aber wenn ich zum Beispiel den Text "qwertzuiop" 
runtersende, kommt "qwertqweupqwepqwep" zurück. Komisch, oder gibt es 
dafür eine logische Erklärung?

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was mir noch aufgefallen ist: Es kommt erst zu diesen Fehlern, wenn der 
String länger als 6 Zeichen ist. Alles was darunter ist, wird korrekt 
übertragen!

Was ist da los?

Autor: nokio (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo
 die daten die du bekommst sind vom µC gesendet. vielleicht wartest du 
nicht genung bis die daten vom PC an µC komplett gesendet ist?!?!

Autor: e^x Man (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm mal die kleinste Baudrate. Wer weiss, was Bascom unter der Haube 
alles tut!

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das ganze nun mit der kleinsten Baudrate getestet, doch es 
passiert der gleiche Fehler!

Autor: André K. (andre-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte mal den kompletten Code anstelle einzelner Fetzen posten. Dann 
kann man evtl. helfen.

Beste Gruesse

Autor: Marvin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Inkey() wartet doch nur auf irgendein Zeichen, oder?

Dann ist klar, was läuft. Der AVR empfängt ein Zeichen, addierts in den 
Buffer und gibts sofort wieder aus. Beim nächsten Zeichen das Gleiche - 
nur dass er jetzt 2 Zeichen augibt, währenddessen kann er zwar eines 
empfangen, aber das Zweite nicht usw.
Der Print-Befehl ist der Übeltäter, so kann das nicht funktionieren.
Welche Funktion erwartest Du von dem Programm? Dass es den Text exakt 
zurücksendet und dabei speichert? Dann solltest Du nicht bei jedem 
Aufruf den kompletten Text mit Print ausgeben, sondern nur das aktuelle 
Zeichen.
Oder: Den ganzen String lesen und erst am Ende ausgeben.

Autor: André K. (andre-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Print sollte in diesem Falle eigentlich nicht das Problem darstellen 
(abgesehen davon, dass es zeit verschlingt und in einer ISR nix zu 
suchen hat).

Problematisch kann hingegen die Verwendung von Inkey() innerhalb einer 
ISR sein, da fuer das Anlegen und Fuellen des inkey Buffers selbst eine 
URXC-ISR genutzt wird. Allerdings setzt der Compiler den Aufruf dieser 
internen ISR zwischen die Sicherung der Register und die User-ISR. 
Sollte also dennnoch laufen. Ich tippe allerdings auf nebenbei laufende 
Timer, deren ISRs zu lang sind. Sowas bringt Bascom leider sehr schnell 
aus dem Takt und das Prog macht, was es will. Ich wuerde folgendes 
machen:

1. Den kompletten Code hier posten...
2. Die ISR umbenennen. In Onserialx o.ae.
2. HWStack, SWStack und Framesize ueberpruefen. Sollte man testweise 
alle auf  >60 setzen, wenn mal gar nix laeuft.
3. Alle anderen Interrupts deaktivieren.
4. Ueberpruefen, ob in den Variablendeklarationen Overlay genutzt wird. 
Diese Variablen testweise loeschen (nicht 0 setzen, sondern deren 
Deklarationen loeschen).

Beste Gruesse

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Marvin und André

Vielen Dank für eure ausführlichen Antworten. Ich habe nun den Tipp von 
Marvin befolgt und das Print weggelassen und erst zum Schluss meine 
Variable ausgegeben und... Es hat funktioniert. Anscheinend hat das 
Print, wirklich dazu geführt, dass einzelne Zeichen "verschlungen" 
wurden.

Naja, trotzdem vielen Dank für eure Bemühungen.

mfg
Andy

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Anscheinend hat das
> Print, wirklich dazu geführt, dass einzelne Zeichen "verschlungen"
> wurden.

Das Print selbst wahrscheinlich nicht.
Dein eigentliches Problem wird eher darin liegen,
dass du ohne Handshake auf der Leitung fährst. D.h.
der µC teilt dem PC nicht mit, dass er momentan beschäftigt
ist und daher zur Zeit nicht senden kann.
Der Print braucht seine Zeit. Da er aber innerhalb der ISR
augeführt wird, kann der µC in dieser Zeit nichts empfangen.
Nur: Das weiss der PC nicht und sendet weiter munter
drauflos. Da aber niemand die Zeichen abholt: -> Null-Device

Autor: nokio (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
karl, soll vielleicht  ein Interrupt ausgelöst, wenn daten komplett 
gesendet bzw empfangen ist?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kannst du softwaremässig einen Interrupt auslösen?

Normalerweise macht man das so, dass man ein Flag
(also eine globale Variable) benutzt, die anzeigt
ob Daten komplett empfangen wurden oder nicht.

Innerhalb der Empfangsfunktion wird einfach nur
das nächste Zeichen von der UART geholt und in
den Buffer gestellt. Die Funktion stellt dann
noch fest, ob die Übertragung der Daten damit
vollständig ist oder nicht. Ist sie nicht
vollständig macht sie nichts weiter. Ist
sie aber vollständig, so wird das Flag (die
globale Variable) auf zb 1 gesetzt.

Im Hauptprogramm, also ausserhalb der Empfangsroutine
wird nun ständig diese globale Variable beobachtet.
Solange sie 0 ist, passiert nichts weiter. Wenn die
aber plötzlich 1 wird, dann hat die UART-Empfangsroutine
einen kompletten Datensatz empfangen und der muss verarbeitet
werden. Danach wird das Flag wieder auf 0 gesetzt und
wieder solange gewartet, bis diese 1 geworden ist, ...

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.