Forum: Mikrocontroller und Digitale Elektronik Probleme mit UART


von Andy (Gast)


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

von Karl heinz B. (kbucheg)


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.


von Andy (Gast)


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?

von Andy (Gast)


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?

von nokio (Gast)


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?!?!

von e^x Man (Gast)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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

von André K. (andre-)


Lesenswert?

Bitte mal den kompletten Code anstelle einzelner Fetzen posten. Dann 
kann man evtl. helfen.

Beste Gruesse

von Marvin (Gast)


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.

von André K. (andre-)


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

von Andy (Gast)


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

von Karl heinz B. (kbucheg)


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

von nokio (Gast)


Lesenswert?

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

von Karl heinz B. (kbucheg)


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, ...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.