Hallo Habe da ein kleines Problem. Ich möchte gern meine 16Bit Hex- Werte über die Serielle Schnittstelle ausgeben. Die Umwandlung habe ich schon realisiert und mir liegt jetzt meine 16Bit Zahl in den 3 (BCD gepackten) Registern BCD0,BCD1,BCD2 vor. Aber wie übertrage ich jetzt dieses Format? Mit Text-strings usw. komme ich ja klar aber hier habe ich so meine Probleme. Muss ich BCD0 usw. nach und nach einfach nur in einen pointer laden und dann dem UART übergeben oder wie stelle ich das an ??? Danke schonmal im Voraus... Gruß Alex
Ein Textstring ist doch auch nichts anderes als ein Feld von Byte... Die Idee mit dem Pointer solltest Du in die Tat umsetzen. Übrigens sind Pointer nur Speicherstellen, die Adressen beinhalten, die auf die eigentlichen Daten weisen... fertigkluggeschissenhat
Entweder Du lässt das mit den gepackten BCD und speicherst es gleich beim Konvertieren als String (einfacher) oder Du machst einen Index-Zähler zusätzlich zum Ptr, der von 0-5 die 6 BCD-Nibbles anspricht. Ist aber relativ komplex und erreicht nur 3 Byte Speicherersparnis gegenüber einem normalen String ... oder Du schreibst (suchst) Dir eine Funktion Hex-Out, die ein Byte als 2 Hex-Werte an den UART ausgibt. Die rufst Du nacheinander mit BCD0, BCD1 und BCD2 auf. Da in jedem Nibble eine Dezimalziffer 0-9 steht, sollte Deine Dezimalzahl 6-stellig korrekt ausgegeben werden. Stefan
Hallo Alex... Warum über BCD wenn du HEX ausgeben willst? Du hast 16 Bit-Werte, also 2 Byte bzw. 4 Nibbles (je 4 Bit). Jedes Nibble (Halbbyte) wird durch eine Hex-Ziffer repräsentiert. Isoliere nacheinander die Werte deiner Nibbles (höherwertigste zuerst), prüfe, ob sie unter 10 sind, also ob es noch Ziffern (0...9) oder schon Buchstaben (a...f) sind, schau in die ASCII-Tabelle um die Codes von Ziffern und Buchstaben zu ermitteln und addiere den jeweiligen Offset für Ziffern bzw. Buchstaben und du hast den ASCII-Wert, den du per Schnittstelle versenden kannst. Und das nacheinander für alle 4 Nibbles... Kleiner Tip: Für Ziffern wirst du wohl die Konstante 48 addieren müssen, bei Buchstaben kommt es darauf an, ob sie groß oder klein dargestellt werden sollen. Viel Erfolg... Bit- & Bytebruch... - ...HanneS...
Ich nehme mql an, er will eine 16-Bit Zahl dezimal ausgeben (0 .. 65.000) Sonst würde er ja nicht auf 6 Ziffern (= 3 gepackte BCDs) kommen. Stefan
vermute ich auch. Umd die aber auf einem PC auszugeben wäre es sinnvoll, sie in Ascii zu wandeln, weil es sonst nur Steuerzeichen wären... Der einfachste Weg wäre, BCD-Zahl + 48 zu rechnen, da das die "ASCII-0" ist.
gepackt-BCD ist aber nochmal was anderes. Da sind 2 Ziffern (0-9) in einem Byte zusammengepackt (in jedem Nibble eines). Wenn man ein solches Byte als Pseudo-Hexwert ausgibt, dann bekommt man beide Ziffern korret angezeigt. Stefan
hmmm... das mit den gepackten BCDs habe ich überlesen. Natürlich hat man in diesem Fall eine saubere Darstellung der Zahlen. Mich würde schon interessieren, an wen er die schickt. Gute Nacht Rahul
Hallo Rahul & Stefan... Völlig korrekt, was ihr da schreibt, ich bezog mich aber auf den allerersten Beitrag dieses Threads, da steht: "Ich möchte gern meine 16Bit Hex- Werte über die Serielle Schnittstelle ausgeben." In den Registern oder im RAM stehen aber nunmal keine Hex-Werte, sondern Bits oder Bytes, die im allgemeinen eine 16-Bit-Ganzzahl darstellen. Hex ist ja nur eine Darstellungsform des Zahlenwertes in ASCII-Text, genau wie dezimal, oktal oder binär. Und da Alex seine "16-Bit-Hex-Werte" (also eine vierstellige Hex-Zahl) an die serielle Schnittstelle schicken wollte, nahm ich an, dass dies in Hex am besten geht. Gut, ich empfahl ihm nicht, ein Trennzeichen [z.B. chr$(32) oder chr$(13)] hinterher zu schicken, da sollte er selbst drauf kommen... Mit besten Grüßen, Bit- & Bytebruch... - ...HanneS...
Danke für die vielen Antworten. Ja ich habe mich etwas blöd ausgedrückt. Ich möchte meine 16Bit Messwerte so umformen (also in BCD) das ich sie über die Serielle Schnittstelle senden kann um später im Hyperterminal meine Werte von 0 bis 65000 ablesen kann. gruß alex
Dann solltest Du sie nicht in Richtung BCD wandeln, sondern in (ascii)-Text. Wenn Du gepackte BCDs an Hyperrterminal sendest, macht der daraus Buchstaben und da kann es vorkommen, dass da nur wirres Zeug steht. Hyperterminal ist leider zu doof, um gepackte BCDs zu erkennen. Besser ist es entweder jede Ziffer als Ascii-Text zu übermitteln, oder ein kleines Programm auf dem PC zu erstellen, das die BCDs wieder entpackt. Die zweite Variante ist bei der Übertragung chneller, die erste erfordert weniger Aufwand auf der PC-Seite. Jetzt musst Du halt entscheiden, was du eher brauchst bzw. realiseren kannst. Gruß Rahul
Aha wieder was gelernt... Ich dachte das ich mit der umwandlung nach BCD all diese Probleme aus dem weg geräumt hatte aber naja. Jetzt mal ne andere Frage... wie wandle ich denn meine Hex Zahl in ASCII-Text um ????
Wenn Ziffernanzeige mit Führungsnullen erwünscht ist, dann ist der Schritt über BCD schon sinnvoll, bei knappen Registern auch über gepackte BCD. Dann jedes Nubble isolieren, 48 dazu und ab zur Post... Ganz so einfach ist es denn aber auch wieder nicht, denn man darf der seriellen Schnittstelle das nächste Byte erst anbieten, wenn sie mit dem Vorherigen fertig ist... Bit- & Bytebruch... - ...HanneS...
dazu kann man die Bytes ja auch in ein String / Array schreiben...Das Senden würde dann per Interrupt geschehen. Ich bin leider gerade im Moment mit was anderem (wesentlich dringenderem) beschäftigt, sonst würde ich dir ein Programm in C basteln. Vielleicht guckst du mal in der Lib-c nach, ob da eine Funktion zur Umwandlung von long (2Byte) in Text beschrieben ist.
Vielen Dank für das Angebot aber "C" ist nicht notwendig da ich mit reinem Assembler Code programmieren möchte.. Was ist eigentlich mit "jedes Bit einzeln isolieren" gemeint? oder besser aus gedrückt wie addiere ich zu jedem nibble die 48 und wie übergebe ich dann die einzelnen nibbles der schnittstelle?
Na wenn Du doch die Umwandlung in gepackte BCD schon hast, dann brauchst Du doch nur noch eine Routine, die 3 Bytes als Hex-Wert bzw. 2 Ziffern auf die Schnittstelle ausgibt. Keine Angst, Du siehst nachher keine Hex-Zahl auf dem Terminal, sondern Deine Dezimalzahl mit 6 Stellen. Leider hast Du noch nicht verraten, welche CPU Du benutzt. Ich mache sowas immer mit einer Tabelle, in der die 16 Hex-Ziffern drinstehen, und nehme jeweils 1 Nibble zum Indizieren auf diese Tabelle. Hab Dir mal nen Code angehängt für eine NEC-CPU, für Atmel habe ich es leider noch nicht. hextab db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' send_hex ;auszugebendes Byte steht in A: push HL push BC mov C,A ror A,1 ror A,1 ror A,1 ror A,1 and A,#15 movw HL,#hextab mov B,A mov A,[HL+B] call send_txd_char mov A,C and A,#15 mov B,A mov A,[HL+B] call send_txd_char pop BC pop HL ret Stefan
Hi Alex... Nicht Bits isolieren, sondern Nibbles... Jedes deiner gepackten BCD-Bytes enthält doch 2 Ziffern... Eine davon im oberen Nibble (Halbbyte), eine im Unteren. Nun willst du daraus ASCII machen, aus jedem Nibble ein Zeichen. Also musst du aus dem Byte das gewünschte Nibble erstmal isolieren. Dies geht am besten, indem du es in ein Hilfsregister (temp) kopierst, wenn du das obere Nibble brauchst, dann tauscht du die Nibbles (swap tmp), wenn das gewünschte Nibble unten ist, blendest du die oberen aus (andi tmp,15). Tmp hat nun den Wert der Ziffer, also 0...9. Da du aber nicht die Ziffern als Wert senden willst addiert du den Wert 48 hinzu, wodurch der ASCII-Code der Ziffer gebildet wird. Dieses kannst du dann an die serielle Schnittstelle senden. Für ADD Konstante gibt es keinen Befehl, da hilft subi temp, (-48). Falls du im PC-Terminal nicht nur unformatiert aufeinanderfolgende Ziffern sehen willst, solltest du nach der Übertragung jeder Zahl ein Trennzeichen schicken. Da 6 Halbbytes (Nibbles) mit BCD hast, deine Zahl (0...65535) aber maximal 5-stellig wird, solltest du überlegen, ob du die Ziffer mit der höchsten Wertigkeit überhaupt sendest, sie ist eh 0... Wenn du genügend Rechenzeit hast, also wenn dein AVR während der Datenübertragung sowiso nix Anderes zu tun hat, dann bietet sich an, auf Schleifen und UART-Interrupt zu verzichten und für jede Stelle der Zifferbildung separaten Code zu schreiben, dabei vor jedem Senden auf die Fertigmeldung des UART zu warten. Das dürfte am einfachsten sein... Viel Erfolg... Bit- & Bytebruch... - ...HanneS...
Aha das war eindeutig..Damit dürfte ich klarkommen. Ich nutze jetzt gleich mal die Gelegenheit um noch eine weitere Frage zu stellen die ihr mir evtl. ebenfalls beantworten könnt. Also wie ich bereits schon erwähnt habe, möchte ich meine erfassten und berechneten Messwerte über das Hyperterminal ausgeben. (in meinem Fall eine Drehzahl) ich möchte vermeiden das im Hyperterminal, die sich ständig ändernden Werte in neuen Zeilen dargestellt werden bsp. DREHZAHL 8000 DREHZAHL 7867 so nicht...!!!!! DREHZAHL 7834 DREHZAHL 6578 ... ... usw. Sondern immer an der gleiche position in etwa so: Drehzahl: ....... ist das möglich ? gibt es da ein Steuerzeichen im ASCII CODE welches dieses ermöglicht? Ich hoffe ihr versteht was ich meine und bedanke mich für die doch so zahlreichen Antworten. Gruß Alex
Hi Alex... Sorry, da kann ich dir nicht helfen, da ich Hyper-Terminal nicht nutze. Ich selbst habe auch noch keine serielle Verbindung PC-AVR realisiert, es war bisher nicht notwendig. Probieren könntest du mal mit chr$(10), das ist der Code für "Wagenrücklauf". Es kommt nun darauf an, wie das Terminalprogramm das interpretiert... Als ich mit einen AVR (AT90LS8535) (eigentlich mit der am AVR angeschlossene Smart-Media-Karte) kommunizieren musste, realisierte ich das mit einer Nibble-orientierten Schnittstelle über den Druckerport und schrieb in QB (QuickBASIC für M$-DOS) mein eigenes Transferprogramm, das von einem eigenen Windows-Programm (VB) als "Treiber" aufgerufen wird. Naja, sind große Umwege, aber aus VB kann ich den LPT nicht ansprechen, dazu bin ich noch zu doof. Und mit GFA-BASIC konnte ich mich noch nicht anfreunden, mit VB und QB klappts, mit GFA müsste ich total von vorn beginnen... Aber vielleicht hat ja jemand Anderes Erfahrungen mit dem Terminal und kann sich hier mal äußern... Viel Erfolg... Bit- & Bytebruch... - ...HanneS...
Mit Hyperterminal habe ich auch ewig nicht mehr gearbeitet (gibt ja eigentliche keinen Grund mehr, da es kaum noch Mailboxen gibt). Eine Anwendung in VB ist mir geringem Aufwand möglich, sofern man damit schon mal gearbeitet hat. Die Position des Cursors bei Hyperterminal zu verändern ist schon ein interessantes Problem, das mich an die C64er-Zeiten erinnert, wo man die entsprechende Anzahl an Pfeiltasten in einem String angeben musste. Da wurden die Sonderzeichnen (alle Zeichem im ASCII-Code <32) noch mitgespeichert. Ich bin mir nicht ganz sicher, aber es gab einen Code für einen Rückschritt. Den müsste man nur entsprechend häufig anwenden (ca. fünf mal), um wieder die Schreibpostion zu erreichen. Zumindest hat das bei Mailboxen damals so in etwa funktioniert. Es könnte sein, dass es der CR-Code (chr(13)) war, der ist aber eher mit einem Wagenrücklauf zu vergleichen. Wenn ich mich recht erinnere, gibt es bei Hyperterminal die Möglichkeit die zum Zeilenumbruch notwendigen Befehle festzulegen. Dabei unterscheidet man zwischen LF (Line Feed = Chr(10)), CR (carrige return = chr(13) und LF+CR, wobei ein Linefeed dafür sorgt, dass das "Blatt" eine Zeile hochgeschoben wird, aber die Spalte des Cursors beibehält. CR sorgt für einen Wagenrücklauf, sprich: der Cursor wird an den Anfang der Zeile gesetzt. Je nach Einstellung wird das "Blatt" dann noch eine Zeile hochgeschoben oder halt nicht. Irgendwo müsste ich noch eine ASCII-Übersicht haben, in der das beschriebenist (Applesoft-Basic). So, gute Nacht Rahul
Hallo... @Rahul: Stimmt 10 iss Zeile, 13 iss Rücklauf, hatte ich in der Eile verwechselt, kommen ja bei M$ immer gemeinsam vor... Übrigens komme ich nicht vom C64 sondern von seinem schwarzen Bruder, dem Plus/4. Hatten aber den gleichen Zeichensatz. C64 war besser zum Spielen, Plussi hatte besseres BASIC, beide waren für ihre Zeit große Klasse. Einen Plussi benutze ich noch gelegentlich zum Brennen von EPROMs... Mit VB4 gelang es mir mal vor 7 Jahren nicht, einen Rolley-Diaprojektor per V.24 sauber anzusprechen, mal ging es, mal nicht. Seitdem habe ich es nicht wieder versucht. Inzwischen nutze ich auch VB6. Das probiere ich aber bei Gelegenheit mal, ich muss mir mal einen Pegelwandler mit MAX232 bauen, den ich an AVR-Schaltungen anstecken kann. @Alex: Die Rücktaste ist chr$(8)... Ich halte es aber für möglich, dass diese als "Klotz" dargestellt wird. WINDOOF ist da manchmal etwas unflexibel. Viel Erfolg... Bit- & Bytebruch... - ...HanneS...
Danke nochmal für die Antworten.. Mein Programm läuft jetzt genauso wie ich es mir vorgestellt habe. Das von mir gesuchte ASCII Steuerzeichen ist chr(8)..--> Hannes du hattest recht. Na denn bis zum nächsten Problem... Gruß Alex
Hi Alex... Mir greht es nicht ums "Rechthaben", bin selbst AVR-Anfänger. Aber es freut mich, dass ich helfen konnte... Viel Erfolg... Bit- & Bytebruch... - ...HanneS...
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.