serielles Kommunikationsproblem Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte
Autor |
serielles Kommunikationsproblem |
|
|
|
|
BID = 849081
PhyMaLehrer Schriftsteller
Beiträge: 911 Wohnort: Leipzig
|
|
Heute habe ich auch einmal eine Frage.
Ich habe dieses LCD-Modul, das ich ansteuern möchte. Eine Suche brachte mich zu diesem Thread über einen 320x240 Pixel LCD-Controller im Textmodus. (Diese Seite lädt bei mir seeehr langsam. Aber bitte erst einmal weiter lesen! )
Der Controller arbeitet mit dem ATmega8 und wurde in Assembler programmiert. Das habe ich für Mikrocontroller noch nie getan, aber die Umstellung auf den im Programm schon vorhandenen Zeichensatz mit 10 Pixeln Höhe und auf 200 Pixelzeilen (20 Zeichenzeilen) war ja noch einfach.
Ich war schon mal begeistert, als ich danach schon etwas auf dem Bildschirm erkennen konnte. Allerdings hat dieses LCD 640 x 200 Pixel im Hochformat (sehr seltsam!), so daß nur die Hälfte der Bildschirmbreite mit lauter magersüchtigen Zeichen ausgenutzt wurde. Mit viel Versuch und noch mehr Irrtum ist es mir aber gelungen, das Programm so zu ergänzen, daß jetzt (neu definierte) Zeichen mit 16 Pixelspalten richtig dargestellt werden und der Bildschirm mit 20 Zeilen zu je 40 Zeichen ausgefüllt ist. In der unteren Bildhälfte sieht man, wie der Controller beim Start den Bildschirm mit dem Zeichensatz voll schreibt.
Soweit ist alles prima.
Nun aber sollen dem Controller Steuerzeichen und darzustellende Zeichen per serieller Schnittstelle übergeben werden. Er empfängt nur über RxD und sendet seinerseits nichts über TxD zurück. Am Programm habe ich an dieser Stelle nichts verändert, ich habe nur bei der Definition von Konstanten die Baudrate auf 9600 gesetzt.
Leider ist es nun so, daß mehrere aufeinander folgende Zeichen falsch dargestellt werden. (Das war auch schon mit der "unverbastelten Urversion" so, die nur den halben Bildschirm beschrieb.)
Nun zum Bild:
In der ersten Zeile habe ich den Finger auf der Leertaste gelassen. Das erste Leerzeichen ist nicht zu sehen, dann wechseln sich das Leerzeichen und das Zeichen mit dem um 128 höheren ASCII-Code ab. Der Fehler hängt übrigens nicht von der Geschwindigkeit ab, also kein Problem des Puffers (?). Auch wenn ich die Zeichen langsam eingebe, kommt es zu diesem Fehler.
Folgen verschiedene Zeichen aufeinander, funktioniert alles prima, wie man an dem Satz ab der zweiten Zeile sieht.
Nach diesem Satz habe ich Nullen getippt, wobei wieder zweimal richtig eine Null erscheint, und dann wieder die Null und das um 128 größere Zeichen.
Unterschiedliche Zeichen nacheinander (AB in Zeile 5) werden richtig angezeigt.
Eine Reihe M in Zeile 6 ergibt wieder zweimal das M und dann M und das um 128 größere Zeichen abwechselnd.
Der ATmega8 wird mit 16 MHz Quarzfrequenz betrieben, ergibt also wahrscheinlich keine 100-prozentig "glatten" 9600 Baud, aber der Fehler tritt ja nur bei mehr als 2 aufeinanderfolgenden gleichen Zeichen auf.
Und hier noch die entscheidenden Teile des Programms:
Code : |
;Werte
.equ Baudrate =9600 ; Baudrate
.equ Framerate =50 ; Refreshrate
.equ F_CPU =16000000 ; CPU Freq
; Interne Konstanten
.equ HFREQ =Framerate*200
.equ TDIV =((F_CPU/8+(HFREQ)/2)/HFREQ)
.equ CSize =10
.equ XSize =40
.equ YSize =200/CSize
.dseg
DDRAM: .byte XSize*YSize ;DDRAM
...
...
...
;********************************************************
; Hauptprogramm
;********************************************************
Mainloop:
sbic UCSRA, RXC ;Daten im UART Puffer ?
rcall rxuart
rjmp Mainloop
rxuart: ;UART Daten verarbeiten
in RX, UDR
cpi RX, 32
brlo command
st Y+, RX ;Daten
ldi temp, high(XSize*YSize+DDRAM)
cpi YL, low(XSize*YSize+DDRAM)
cpc YH, temp
brlo skipwpreset
ldi YL, low(DDRAM)
ldi YH, high(DDRAM)
skipwpreset:
ret
|
|
Ab der Marke rxuart wird geprüft, ob das empfangene Zeichen < 20H ist. Wenn ja, ist es ein Steuerzeichen, ansonsten ein darzustellendes Zeichen. Die folgenden Zeilen überprüfen nach meinem Verständnis, ob schon das Ende des Bildschirms erreicht ist. Wenn ja, geht das Beschreiben wieder oben los. Es gibt doch hier also kaum Programmzeilen, die tatsächlich mit der seriellen Kommunikation zu tun haben und wo das Problem stecken könnte, oder?
Womöglich übersehe ich nur eine klitzekleine Kleinigkeit, bei der die Experten diesen hier machen, aber es wäre schön, wenn ich einen helfenden Tip bekommen könnte, wonach ich schauen oder was ich verändern müßte.
Vielen Dank schon mal, auch dafür, daß ihr mit Lesen bis hierher durchgehalten habt! |
|
BID = 849124
Jornbyte Moderator
Beiträge: 7178
|
|
Ich sehe hier nix, aber wie geht es bei brlo command weiter?
_________________
mfg Jornbyte
Es handelt sich bei dem Tipp nicht um eine Rechtsverbindliche Auskunft und
wer Tippfehler findet, kann sie behalten. |
|
BID = 849131
PhyMaLehrer Schriftsteller
Beiträge: 911 Wohnort: Leipzig
|
Da wird das empfangene Byte, das ja an dieser Stelle kleiner als 20H ist, nacheinander auf die verschiedenen Steuerzeichen (Bildschirm löschen, neue Zeile usw.) überprüft und die jeweilige Aktion ausgeführt. Das habe ich zwar noch nicht überprüft, aber ich nehme an, daß auch das funktionieren wird, wenn die Darstellung der Buchstaben ordentlich klappt.
Wundern tut mich vor allem, daß zwei gleiche Zeichen hintereinander funktionieren, aber nicht mehr...
|
BID = 849133
Jornbyte Moderator
Beiträge: 7178
|
Du hast einen Pufferüberlauf. Der M8 hat 1024 Byte Ram
.equ CSize =10
.equ XSize =40
.equ YSize =200/CSize
benötigt 800Byte.
ldi temp, high(XSize*YSize+DDRAM)
cpi YL, low(XSize*YSize+DDRAM)
Hier wir die Position + Pufferlänge erwartet und läuft mit großer wahrscheinlichkein in den Stack rein.
_________________
mfg Jornbyte
Es handelt sich bei dem Tipp nicht um eine Rechtsverbindliche Auskunft und
wer Tippfehler findet, kann sie behalten.
|
BID = 849139
PhyMaLehrer Schriftsteller
Beiträge: 911 Wohnort: Leipzig
|
Aber das "XSize*YSize+DDRAM" ist nach meinem Verständnis doch nur der Ausdruck für das obere Ende des Bildschirmspeichers, oder? Eben 800 Byte nach dem Anfang des DDRAM.
Und ein Pufferüberlauf sollte doch unabhängig von der Art (bzw. Wiederholung) der übermittelten Zeichen sein...
Da muß ich mal weiter drüber nachdenken, aber heute nicht mehr. Ich gehe jetzt erst einmal an der Matratze horchen. (Muß morgen wieder um 4.20 Uhr raus ) Vielen Dank bis hierher für dein Mitdenken!
|
BID = 849235
PhyMaLehrer Schriftsteller
Beiträge: 911 Wohnort: Leipzig
|
Solche Fehler mag ich aber gar nicht, die verschwinden und man weiß nicht, woran es gelegen hat!
Dabei probiere ich ja nicht erst seit gestern, sondern schon ein paar Tage. Heute aber - siehe Bild!
Das "fast immer" im Text bezieht sich darauf, daß nach einem Schließen und erneuten Öffnen des Terminalprogramms der Fehler noch einmal kurz auftrat, dann aber nicht mehr.
Auch die Rücktaste funktioniert, also wird das mit den Steuerzeichen auch klappen.
Jetzt bleibt nur noch die Tatsache, daß nach dem Reset das erste Zeichen "verschluckt" wird. Das soll aber der kleinste Kummer sein, da sende ich eben am Anfang zweimal "Bildschirm löschen"!
|
BID = 849275
perl Ehrenmitglied
Beiträge: 11110,1 Wohnort: Rheinbach
|
Zitat :
| Jetzt bleibt nur noch die Tatsache, daß nach dem Reset das erste Zeichen "verschluckt" wird |
Etliche Terminalprogramme benutzen das Timing des ersten eintreffenden Zeichens, gewöhnlich ist das ein CR, um die Übertragungsgeschwindigkeit festzustellen.
|
BID = 849412
sub205 Schriftsteller
Beiträge: 916 Wohnort: Gründau
|
Zitat :
perl hat am 24 Sep 2012 20:30 geschrieben :
|
Zitat :
| Jetzt bleibt nur noch die Tatsache, daß nach dem Reset das erste Zeichen "verschluckt" wird | Etliche Terminalprogramme benutzen das Timing des ersten eintreffenden Zeichens, gewöhnlich ist das ein CR, um die Übertragungsgeschwindigkeit festzustellen.
|
Welche Terminalprogramme sind das?
Ich kenne dieses Verhalten nur von guten alten seriellen Modems. Die haben anhand des "AT" die nötige Baudrate erkannt.
Bei den mir bekannten Terminalprogrammen stellt man die Übertragungsparameter immer fest ein. Woher sollte ein angeschlossenes Gerät ein CR senden? Unvermittelt - es weiß ja auch nicht das nun ein Gerät lauscht.
Gruß, Stephan
|
BID = 849447
Brizz Stammposter
Beiträge: 386 Wohnort: Rheine
|
Falls der Fehler wieder auftritt, kannst Du mal beim Sender 2 Stoppbit einstellen.
In dem von Dir beigefügten Code ist nur ersichtlich, das in Mainloop
lediglich geprüft wird, ob sich ein neues Zeichen im Empfangregister der UART befindet, und dieses dann ausgelesen, geprüft und ausgegeben, falls es nicht kleiner als Space ist. Andernfalls wird die Routine skipwpreset aufgerufen.
Die eigentliche Initialisierung der UART wir da stattfinden, wo im Code das Symbol BAUDRATE auftaucht.
Im vorliegenden Fall, kann es sich aber nur um erste Schritte zum Test der UART handeln.
Für eine richtige UART-Bearbeitung sind interrupt-gesteuerte RX- und TX-Routinen mit entsprechenden Puffern erforderlich, um sicherzustellen, dass auch während der Bearbeitung komplexer Formeln beispielsweise, kein Zeichen an der UART verloren geht.
[ Diese Nachricht wurde geändert von: Brizz am 25 Sep 2012 22:50 ]
|
BID = 849466
perl Ehrenmitglied
Beiträge: 11110,1 Wohnort: Rheinbach
|
Zitat :
| Welche Terminalprogramme sind das?
Ich kenne dieses Verhalten nur von guten alten seriellen Modems. |
Na, die Geräte, die typischerweise an diese gar nicht so guten alten Modems angeschlossen wurden.
Zitat :
| Die haben anhand des "AT" die nötige Baudrate erkannt. |
Nein, mittels eines AT Kommandos wurde die gewünschte Übertragungsgeschwindigkeit eingestellt. Die ist in den meisten Fällen übrigens nicht identisch mit der Baudrate, sondern höher.
Dazu muß das Modem aber selbst erst einmal AT-Kommandos verstehen, und wenn es über eine serielle Verbindung mit dem Endgerät oder dem Computer verbunden war, besorgte es sich die Geschwindigkeit für diese Strecke entweder über das Mäuseklavier oder eben über das erste Zeichen.
Die Kommunikation über die Telefonleitung, selbst bei den 56k Modems, begann immer mit 300 Bd.
Lustigerweise kann man damit kurze Nachrichten schneller auf den Weg bringen, als mit den hohen Geschwindigkeiten, bei denen dann erst einmal Prozeduren ausgehandelt und Entzerrer trainiert werden müssen.
|
BID = 849477
sub205 Schriftsteller
Beiträge: 916 Wohnort: Gründau
|
Zitat :
|
Zitat :
| Die haben anhand des "AT" die nötige Baudrate erkannt. | Nein, mittels eines AT Kommandos wurde die gewünschte Übertragungsgeschwindigkeit eingestellt. Die ist in den meisten Fällen übrigens nicht identisch mit der Baudrate, sondern höher.
|
Entschuldige, da muß ich dir als Programmierer eines Fidonet-Mailers widersprechen. Das Modem (das ja im ersten Moment garnicht wußte wie schnell das Terminal eingestellt war) hat sich anhand der AT-Sequenz die nötige Baudrate selbst ermittelt. Danach hat es die AT-Commands angenommen und seine internen Einstellungen entsprechend gestellt.
Die CONNECT-Rate ist vollkommen unabhängig von der RS232-Geschwindigkeit. Das Modem ist im DCD-Mode ja mehr oder weniger ein Umsetzer mit Puffer.
Nun schreibst du doch das selbe wie ich:
Zitat :
|
Dazu muß das Modem aber selbst erst einmal AT-Kommandos verstehen, und wenn es über eine serielle Verbindung mit dem Endgerät oder dem Computer verbunden war, besorgte es sich die Geschwindigkeit für diese Strecke entweder über das Mäuseklavier oder eben über das erste Zeichen.
Die Kommunikation über die Telefonleitung, selbst bei den 56k Modems, begann immer mit 300 Bd.
Lustigerweise kann man damit kurze Nachrichten schneller auf den Weg bringen, als mit den hohen Geschwindigkeiten, bei denen dann erst einmal Prozeduren ausgehandelt und Entzerrer trainiert werden müssen.
|
Jaja, die gute alte Zeit der Trägeraushandlung. Die 300Baud-Dinger haben nicht wirklich irgendwas ausgehandelt, die haben einfach gesendet und empfangen. Klar, da ging der Kram direkt raus. Hab irgendwann mal nen Dinosaurier dieser Art auf dem Wertstoffhof gefunden, ist aber schon bestimmt 15 Jahre her...
Interessant fand ich, als jemand der schon recht früh in diese Technik eingestiegen ist, der Komplexitätsanstieg bei der Leitungsvermesssung. Mein erstes 14k4 war noch ein V32bis-Gerät. Danach die V34-Geräte und später K56/V90. Insbesondere bei der letzten Generation war es ja so das eine Seite zwingend an einem ISDNer hängen mußte um das Timing bei den DA-Wandlern in der Vermittlungsstelle auszunutzen.
Egal, wird OT...
Gruß, Stephan
|
BID = 849564
PhyMaLehrer Schriftsteller
Beiträge: 911 Wohnort: Leipzig
|
Zitat :
Brizz hat am 25 Sep 2012 22:46 geschrieben :
|
Für eine richtige UART-Bearbeitung sind interrupt-gesteuerte RX- und TX-Routinen mit entsprechenden Puffern erforderlich, um sicherzustellen, dass auch während der Bearbeitung komplexer Formeln beispielsweise, kein Zeichen an der UART verloren geht. |
In den knappen Hinweisen zum Programm steht, daß ein Puffer von 30 Zeichen vorhanden ist, der eigentlich immer ausreichen sollte, falls nicht gerade ständig "gesamten Bildschirm löschen" gesendet wird. Wo dieser Puffer aber vereinbart wird, weiß ich nicht. Es werden ein paar Register gesetzt, deren Bedeutung sich mir aber auch mit dem Datenblatt (noch) nicht so recht erschließt. Da habe ich noch ein bißchen was vor...
Der Fehler ist übrigens zunächst wieder aufgetreten. Ich habe den Oszi am RxD des Mikrocontrollers angeschlossen und den Finger auf einer Computertaste gelassen. Das Oszi-Bild flackert ganz schön, da die Pause zwischen den Zeichen viel länger als die Zeichendauer ist. Jedenfalls ist aber zu sehen, daß die Anzeige "flattert". Es könnte also sein, daß wirklich das höchstwertige Bit mal 0 und mal 1 ist.
Nachdem ich aber etwa den halben Bildschirm durchgehend (also ohne den Finger von der Taste zu nehmen) auf diese Weise fehlerhaft beschrieben hatte, verschwand der Fehler und alles ging gut. (Auch nach Reset, bis auf das dann fehlende erste Zeichen.)
Ich habe auch eine Textdatei 'rübergeschickt und sie wurde richtig angezeigt - bis auf die Umlaute, die auf anderen Codes liegen.
Ich hatte ja schon an mehreren Tagen zuvor getestet und immer trat der Fehler auf. Da habe ich aber auch nicht so lange hintereinander ein Zeichen gesendet, sondern zwischendurch immer wieder aufgehört. Da ist der Fehler nicht "verschwunden"... Seltsam!
Mein Mikrocontroller sendet ja nichts zurück - muß er ja auch nicht. Ich habe deshalb den somit freien controllerseitigen TxD-Anschluß am Schnittstellenkabel (oder ist es eine Leitung?? ) mit RxD verbunden und die fortlaufend gesendeten gleichen Zeichen wurden im Terminalprogramm alle richtig angezeigt, auch als ich das "flatternde", fehlerhafte Oszi-Bild hatte...
|
BID = 849591
Nukeman Schriftsteller
Beiträge: 754 Wohnort: bei Kleve
|
Hallo PhyMa-Lehrer,
das gleiche (sehr gute und geniale) Programm hatte ich auch schon bei mehreren
Displays eingesetzt. Der Fehler, dass das erste Zeichen nach Reset verschluckt
wird, kommt mir auch bekannt vor Mein Host-Controller schmeißt ihm den
Reset-Code deshalb gleich mehrfach um die Ohren.
Das Flattern auf dem Scope kann auch daher rühren, dass aufgrund des langen
Zeichenabstands das Scope auf Autotrigger geht und somit ein Jitter im Bild
entsteht.
Vielleicht mal eine große Datei mit einem konstanten Zeichen generieren, diese
rüber schicken und dann nochmal aufs Scope schauen.
Verstehe ich das richtig, dass Du bei dem TxD-Test die TxD-Ader direkt in Hardware auf RxD gebrückt hast, so dass ein Hardware-Echo entsteht?
Da das OK war, dann vielleicht mal eine Loop im Controller-Code machen,
und Du siehst genau, was er so erlebt hat und ob da irgendwo Zeichen
hinzuerfunden worden sind.
Mit der Speicherorganisation muss ich nochmal nachsehen, das RAM dafür wird im Assembler indirekt per Pointer abgeklappert. Kann schon sein, dass bei Stack-
Überschreibern diese Art von Problemen auftritt, wie auch schon von Jorn
angesprochen.
Gruß,
Stefan
|
BID = 849593
Nukeman Schriftsteller
Beiträge: 754 Wohnort: bei Kleve
|
War zu spät für edit:
Hab eben mal nachgesehen, bei einer meiner Configs habe ich:
.equ CSize =12
.equ XSize =60
.equ YSize =200/CSize ; 200/12 = 16,666 -> 16x12=192 Zeilen sichtbar
was einen RAM-Bedarf von 960 Bytes ergibt. Dazu kommen noch 32 Bytes
Rx-Buffer, bei mir noch 16 Bytes Zeileninvertierung und 2 Bytes TX-Buffer.
Macht einen RAM-Verbrauch von insgesamt 1010 Bytes, bleiben nur noch 14 Bytes für
den Stack ( IRQs und Calls ).
Trotzdem scheint der Stack hier ausreichend zu sein. In den Ints wird nur das SREG
gesichert. Die Call-Schachtelungstiefe liegt bei 2, es liegen also max. 3
Rücksprungadressen auf dem Stack.
2xmain + 1xInt = 3*2(?) + 1 SREG = 7 Bytes wenn ich mich nicht verrechnet habe.
Der Stack müsste bei mir also immer noch 7 Bytes Luft haben, bevor er in irgendwelche anderen Speicherbereiche hineinragt. Bei Dir sollte das also
noch wesentlich entspannter sein.
Gruß,
Stefan
|
BID = 849618
PhyMaLehrer Schriftsteller
Beiträge: 911 Wohnort: Leipzig
|
Vielen Dank für die ausführliche Antwort!
Ja, RxD und TxD habe ich direkt gebrückt. Das Hardware-Echo zeigte auch dann die richtigen Zeichen, wenn das LCD abwechselnd richtige und falsche Zeichen anzeigte.
Das mit dem Flattern und Flackern meinte ich so:
Die Oszi-Anzeige flackert, weil die Zeichenlänge kurz ist gegenüber dem Zeichenabstand, wenn ich den Finger auf der Taste lasse.
Mit "flattern" meinte ich, daß während der fehlerhaften LCD-Anzeige auf dem Oszi tatsächlich zu sehen war, daß ein Bit zwischen 0 und 1 wechselt. - Als der Fehler dann nicht mehr auftrat und richtig immer dasselbe Zeichen angezeigt wurde, "flatterte" das Oszi-Bild auch nicht mehr.
Ich habe bisher mit meinem Laptop getestet und hatte jetzt schon den Verdacht, daß es dort Probleme gibt. Also habe ich gestern abend mehrere serielle Kabel zusammengestöpselt und ins Wohnzimmer zum "großen" Computer gezogen. Die Anzeige funktionierte gleich richtig! (Bis auf das erste Zeichen, aber darüber mache ich mir jetzt wirklich keine Gedanken, da es nur ganz am Anfang bzw. nach Reset auftritt. Und da am Anfang ohnehin der Bildschirm gelöscht werden muß, kann ich das auch zweimal tun.)
Nun habe ich das ganze noch einmal ausgeschaltet, eine Minute gewartet und den Laptop angesteckt. Und auch da trat der Fehler nicht auf...
Da die Sache schaltungstechnisch funktioniert, werde ich das kleine Problem auf später verschieben und das LCD mit der Stromversorgung und der Ansteuerung in ein Gehäuse zu bringen versuchen. Aber wie ich mich kenne, kann das dauern!
Es war zunächst auch "nur" ein Versuch mit dem billigen Display und der Ansteuerung, an der quasi nix dran ist. Einen konkreten verwendungszweck habe ich noch nicht, aber da wird sich etwas finden.
Vielen Dank also zunächst für die nützlichen Hinweise!
|
|
Zum Ersatzteileshop
Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum
Datenschutz
Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland
gerechnet auf die letzten 30 Tage haben wir 20 Beiträge im Durchschnitt pro Tag heute wurden bisher 5 Beiträge verfasst © x sparkkelsputz Besucher : 182393919 Heute : 1115 Gestern : 7548 Online : 590 25.11.2024 8:42 6 Besucher in den letzten 60 Sekunden alle 10.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
|
xcvb
ycvb
0.0667538642883
|