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
> 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.
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?
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?
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?!?!
Nimm mal die kleinste Baudrate. Wer weiss, was Bascom unter der Haube alles tut!
Ich habe das ganze nun mit der kleinsten Baudrate getestet, doch es passiert der gleiche Fehler!
Bitte mal den kompletten Code anstelle einzelner Fetzen posten. Dann kann man evtl. helfen. Beste Gruesse
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.
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
@ 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
> 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
karl, soll vielleicht ein Interrupt ausgelöst, wenn daten komplett gesendet bzw empfangen ist?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.