Ich bin gerade dabei von Bascom auf Assembler umzusteigen und schreibe
gerade an meinen ersten Programm, welches nur aus Assembler besteht.
Allerdings bereitet mir folgendes Probleme: Bei Bascom gibt es ja den
INPUT-Befehl, der einen String vom UART empfängt und in einer Variable
speichert. Genau dies möchte ich in Assembler realisieren, da es dort
aber keine Variablen wie in Bascom gibt, weiß ich nicht so recht wie. Im
Moment habe ich den String als Konstante mit .db definiert. Die Länge
ist übrigens zwischen einem und 20 Zeichen.
Das mit dem RAM habe ich schon versucht, hier war aber immer das
Problem, dass teilweise Reste von früheren Übertragungen zurückblieben.
Also es wird ABCDE gesendet und gespeichert, beim nächsten mal aber nur
XYZ, daher ist dann XYZDE im RAM, obwohl nur XYZ da sein sollte.
Hi
>Das mit dem RAM habe ich schon versucht, hier war aber immer das>Problem, dass teilweise Reste von früheren Übertragungen zurückblieben.>Also es wird ABCDE gesendet und gespeichert, beim nächsten mal aber nur>XYZ, daher ist dann XYZDE im RAM, obwohl nur XYZ da sein sollte.
Du brauchst noch ein Kennzeichen für das Stringende. Woher weisst du
eigentlich jetzt, wann ein String komplett empfangen wurde?
MfG Spess
Das Stringende wird bei Bascom wahrscheinlich durch CR definiert, da es
so bis jetzt immer funktioniert hat. Ich habe mir aber überlegt, den
Rest einfach durch Leerzeichen zu füllen, d.h. ich warte einfach immer,
bis es 20 Zeichen sind, dies erspart auch das löschen de RAMs.
Dieter Meinhardt schrieb:> Ich habe mir aber überlegt, den> Rest einfach durch Leerzeichen zu füllen, d.h. ich warte einfach immer,> bis es 20 Zeichen sind, dies erspart auch das löschen de RAMs.
Ehe du das weiter ausführst, musst du dir mit dir selbst eine Konvention
ausmachen, wie du die Länge eines Strings festhalten willst.
Es gibt 2 gängige Verfahren
* die eine speichert zusätzlich zu den einzelnen Zeichen noch
einen Zähler mit ab, der die Anzahl an gültigen Buchstaben
angibt
* die andere benutzt ein spezielles Zeichen, oftmals einfach ein
0-Byte, um zu kennzeichnen: Hier ist der String zu Ende
Dein angedachtes Verfahren ist nicht besonders gut. Du kannst dann den
String "Test" nicht mehr vom String "Test " unterscheiden. Zudem machen
dir die Leerzeichen auch bei der Weiterverarbeitung Schwierigkeiten,
weil du zb bei einem Vergleich 2-er Strings immer diese Leerzeichen mit
berücksichtigen musst.
> Das Stringende wird bei Bascom wahrscheinlich durch CR definiert, da es> so bis jetzt immer funktioniert hat.
Du verwechselst du etwas.
Das eine ist die Definition, woran man das tatsächliche Stringende im
Speicher erkennen kann.
Das andere ist die Definition, woran man bei einer UART Übertragung das
Ende einer Zeile erkennen kann. Gerade bei UART Übertragungen geht man
aber oft so vor, dass man definiert, dass eine übertragene Zeile einfach
nur ein String ist. Das CR kennzeichnet dann das Ende einer Zeile und
das emmpfangende Programm macht dann was immer es benötigt, um die
empfangenen Zeichen (ohne das CR) zu einem für sich gültigen String zu
machen.
Gut, wie ich die Daten empfange und im RAM speichere, weiß ich ja nun,
aber wie hole ich sie wieder raus? Geht es, dass ich die derzeitige fixe
Einbindung mit .db einfach an den RAM Weiterleite?
Dieter Meinhardt schrieb:> Gut, wie ich die Daten empfange und im RAM speichere, weiß ich ja nun,> aber wie hole ich sie wieder raus?
Indem du dir eine Funktion schreibst, die die Zeichen laut deiner
Konvention für 'Stringlänge' wieder Zeichen für Zeichen aus dem Speicher
holt und etwas damit macht (zb an ein LCD weitergeben)
Dieter Meinhardt schrieb:> Das Stringende wird bei Bascom wahrscheinlich durch CR definiert, da es
Hallo Dieter,
leider wird das Ende durch eine Null markiert. Hab ich neulich
festgestellt nachdem ich versucht habe ein Array mit Messwerten einfach
als String (Overlay) zu uebertragen grummel ;o)
Bis dahin dachte ich die Laenge des Strings kann ich extern Definieren.
Hab ich dann auch im hilfe-String so gefunden ;o)
bye Uwe
Wenn jede UART-Sequenz eine definierte Ende-Kennung hat, dann würde ich
es so machen:
Man reserviert sich etwas SRAM, in das der längste zu erwartende
"String" (Sequenz von Bytes mit Ende-Kennung) hineinpasst. Dazu braucht
man noch einen Zeiger auf die aktuelle Position im RAM. In einer
Hochsprache wäre das ein Array mit einem Index. ;-) Ein zweiter
SRAM-Bereich kann dann sehr hilfreich sein, Kollisionen zu vermeiden.
Im RXC-Interrupt prüft man das empfangene Byte auf die Ende-Kennung. Ist
sie es nicht, dann hängt man über den Zeiger das enpfangene Byte an die
bisher letzte Position an. Ist es die Ende-Kennung, kopiert man das
Array bis zur aktuellen Position in das zweite Array, legt eine Kopie
des Zeigerstand für das Hauptprogramm an und setzt den Zeiger wieder auf
Anfang.
Das Hauptprogramm erkennt nun durch zyklische Abfrage seiner
Zeiger-Kopie, ob ein neuer "String" angekommen ist (und als Kopie im
zweiten RAM-Bereich liegt) und wie lang er ist. Ist das der Fall, dann
wird der Inhalt des zweiten RAM-Bereichs analysiert, darauf reagiert und
die Zeiger-Kopie wieder gelöscht.
Das Löschen der RAM-Bereiche ist nicht erforderlich, die "Stringlänge"
wird ja immer durch Zeiger oder Zeigerkopie definiert.
MfG