www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik BASCOM: Zeichenumwandlung nach Vorgaben aus einer Tabelle


Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe ein Gerät, das eine eigene ASCII Tabelle verwendet zur 
Darstellung von Zeichen auf einem Bildschirm. Z.B. entspricht der 
Hexwert 00 dem Buchstaben "A" und nicht wie beim ASCII Zeichensatz dem 
Leerzeichen.

Jetzt habe ich einen String in BASCOM der so aussieht:

"TEST12345"

Diesen muss ich zerlegen und dann sollte jedem Char im String der 
entsprechende Hexwert der ASCII Tabelle des Gerätes zugewiesen werden.

T -> &H13
E -> &H04
S -> &H12
T -> &H13

Wie kann ich das mit Bascom realisieren?

Danke schonmal für die Antworten.

Max

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Max wrote:
>
> T -> &H13
> E -> &H04
> S -> &H12
> T -> &H13
>
> Wie kann ich das mit Bascom realisieren?

Mit einer Tabelle (Array)?

In einer Schleife, die über die Länge des Strings geht (Doku 
nachschauen, wie man in BACOM rauskriegt wieviele Zeichen in einem 
String enthalten sind): Für jedes Zeichen im String, isolierst du jedes 
Zeichen einzeln aus dem Eingabestring (Doku nachschauen, wie man bei 
BASCOM an einzelne Zeichen eines Strings rankommt). Jedes Zeichen wird 
als Index in die Tabelle genommen (Doku nachschauen, wie man ein Array 
dimensioniert und mit Werten füllt) und dort steht der Wert, der 
stattdessen zu verwenden ist. Diesen Wert nimmst du und schreibst in 
anstelle des ursprünglichen Zeichens in den String (Doku nachschauen, 
wie man in BASCOM ein Zeichen eines Strings auf einen bestimmten Wert 
setzt)

Summa Summarum: Bis auf den Teil: Du brauchst ein Array als 
Codeumsetzer, läuft fast alles auf Dokustudium hinaus. Und die Idee 
eines Array als Codeumsetzer, hattest du alleine auch schon :-)

(Im übrigen würde ich mal damit anfangen, die Doku zu studieren, ob es 
bestimmte Zeichen gibt, die man in BASCOM nicht in einen String packen 
kann. Wäre nämlich blöd, wenn sich hinterher dann rausstellt, dass das 
so gar nicht funktionieren kann, weil deine Umsetztabelle zu einem 
ungültigen Ergebnisstring führen wird.)

Autor: Ralf Schwarz (spacedog) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Zeichen in deinem selber kreierten Zeichensatz die selbe 
Reihenfolge haben, wie die Zeichen im ASCII, dann lässt sich deine 
Codewandlung durch eine Subtraktion erledigen.

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ralf
Die Reihenfolge ist leider nicht gleich der im ASCII Zeichensatz. Sonst 
wäre es ja auch zu einfach :-)

@Karl Heinz
Wie ich die Stinglänge rausbekomm weiß ich. Wie ich die einzelnen 
Zeichen aus dem String bekomme weiß ich auch. Aber den Rest hab ich 
nicht verstanden.

Was meinst du mit "Schleife die über die Stinglänge geht" ? Wenn ich die 
einzelnen Zeichen habe, wie sage ich BASCOM das aus A ein &H00 werden 
soll?

Danke!

Max

Autor: Dominique Görsch (dgoersch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann Bascom Arrays mit Key => Value-Paaren? Wenn ja einfach eine 
entsprechende Tabelle anlegen, vll auch in einem Data-Bereich um ein 
wenig Ram zu sparen...

Autor: Null Checker (yah996)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kleiner Tipp

Print Asc("a")

Autor: Wigbert Picht (wigbert) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
Schau Dir mal den Befehl "Lookupstr" an.

Wigbert

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Max wrote:
> Hexwert 00 dem Buchstaben "A" und nicht wie beim ASCII Zeichensatz dem
> Leerzeichen.


Na, ja.
Das Leerzeichen hat zwar im ASCII Code einen ganz anderen Wert, aber 
seis drum.

Dein Problem besteht darin, dass BASCOM anscheinend, ähnlich wie C, 
seine Strings mit 0 abschliesst.
Und da dein Gerät bei einem 'A' den Code 0 sehen will, ist damit das 
ganze Konzept des 'einen String in einen anders codierten String zu 
verwandeln' schon mal den Bach runter.

Da wird dir nichts anderes übrig bleiben, als die Codeumsetzung direkt 
bei der Ausgabe an das Gerät zu machen. Das erscheint mir jetzt 
einfacher, als dich in eine 'Na dann wirds wohl nichts mit Strings, da 
müssen dann Arrays als Stringersatz herhalten'-Strategie zu jagen.

Autor: Dominique Görsch (dgoersch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Da wird dir nichts anderes übrig bleiben, als die Codeumsetzung direkt
> bei der Ausgabe an das Gerät zu machen. Das erscheint mir jetzt
> einfacher, als dich in eine 'Na dann wirds wohl nichts mit Strings, da
> müssen dann Arrays als Stringersatz herhalten'-Strategie zu jagen.

Niemand will hier Strings durch Arrays ersetzen. Er will ein Mapping 
zwischen einem Zahlenwert und einem Buchstaben herstellen, das macht man 
nunmal über eine Tabelle, in fachkreisen dann auch Array genannt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dominique Görsch wrote:
> Karl heinz Buchegger wrote:
>> Da wird dir nichts anderes übrig bleiben, als die Codeumsetzung direkt
>> bei der Ausgabe an das Gerät zu machen. Das erscheint mir jetzt
>> einfacher, als dich in eine 'Na dann wirds wohl nichts mit Strings, da
>> müssen dann Arrays als Stringersatz herhalten'-Strategie zu jagen.
>
> Niemand will hier Strings durch Arrays ersetzen. Er will ein Mapping
> zwischen einem Zahlenwert und einem Buchstaben herstellen, das macht man
> nunmal über eine Tabelle, in fachkreisen dann auch Array genannt.

Yep. Und blöderweise ist sein Mapping so, dass er das Ergebnis dieser 
Umsetzung in einem BASCOM String nicht mehr speichern kann, damit er es 
dann seiner vorgefertigten (UART)-Schreibfunktion übergeben kann, die 
den so umgemappten String zum Gerät überträgt.

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Habe es noch nicht ausprobiert aber würde es in etwa so funktionierten:

dim text as string*10
dim char(10) as byte
dim i as byte
dim index(10) as byte

text = "ABCDEFGHIJ"
i = 1

Do

  'Einzelne Chars aus String ziehen
  char(i) = mid(text , i , 1)

  'Char in Tabelle data1 suchen und den Index speichern
  index(i) = lookdown(char(i) , data1 , 1)

  'Wert von Index in Tabelle data2 suchen
  char(i) = lookup(index(i) , data2)

loop until i = 10

printbin char(1) ; char(2) ; char(3) ; ...


data1:
data "A" , "B" , "C" , "D" , "E" , ...

data2:
data &H00 , &H01 , &H02 , &H03 , ...

Max

Autor: D. S. (jasmin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich empfehle die karo einfach Methode.

Den String zeichen für Zeichen auslesen.
Dann einfach in einer CASE Anweisung das Mapping von Istzeichen zu 
Sollzeichen durchführen und diese dann einfach seriell ausgeben.
Brühwarm ins Senderegister kopieren.

Das ist trivial und rasend schnell.


Natürlich mußt du noch ein wenig Logik reinbringen was Stringende etc. 
betrifft.

Das ist aber sehr einfach, keine Interrupts, DO Loop und fertig.

Autor: Dominique Görsch (dgoersch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne es getestet zu haben, aber aus dem Bauch heraus bezweifel ich, dass 
Schleife und Lookup langsamer sind als ein CASE. Denn Case wird doch im 
Endeffekt auch nur in haufenweise Verschachtelte If's aufgelöst und wenn 
du z.B. nach dem letzten Zeichen suchst, durchläufst du jede einzelne 
Entscheidung...

Das obige Beispiel ist schon nicht schlecht, allerdings braucht man 
"index" nicht als Array, da dort immer nur ein Wert beim 
Schleifendurchlauf zwischengespeichert wird. Was oben noch fehlt ist 
eine Logik zur Erkennung des Stringende, damit man nicht auf feste 
Längen angewiesen ist.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum einfach, wenn's auch kompliziert geht ;-)

Untenstehender Code sollte das Gewünschte wirtschaftlich und schnell 
erledigen, allerdings nicht getestet.

Damit würde man z.B. nur Buchstaben umzuwandeln. Man könnte auch den 
kompletten alten Zeichensatz übersetzen, muss dann aber auch eine 
vollständige Lookuptabelle mit allen 256 Einträgen erzeugen. Für diesen 
Fall die mit Sternchen bezeichneten Codeteile weglassen.
Const Strl = 20                                             ' Länge des Strings
Const Orig_char_start = 64                                  ' Dezimalwert bei dem die alten Zeichen beginnen
Const Orig_char_end = 91                                    ' Dezimalwert bei dem die alten Zeichen enden
Dim String_in As String * Strl
Dim String_char(strl) As Byte At String_in Overlay
Dim Char_ctr As Byte , Char_val As Byte

Char_ctr = 0
Char_val = String_char(char_ctr)

While Char_val > 0
  If Char_val >= Orig_char_start And Char_val <= Orig_char_end Then       ' ***
    Char_val = Char_val - Orig_char_start                   ' ***
      String_char(char_ctr) = Lookup(char_val , New_char_val)
        Incr Char_ctr
          Char_val = String_char(char_ctr)
  End If                                                    ' ***
Wend

End

New_char_val:
Data 12 , 22 , 44 , 18 , 5                                  ' usw.


Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, Fehler bemerkt:

Incr Char_ctr

muss natürlich unmittelbar nach If/Then stehen, sonst gibt's 'ne 
Endlosschleife.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag, die Zweite:
...
  End If                                                    ' ***
        Incr Char_ctr
          Char_val = String_char(char_ctr)
Wend
...

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Array Indexe beginnen bei Bascom - blöderweise - bei 1.

Char_ctr = 0
Char_val = String_char(char_ctr)

Gruß

Rolf

Autor: Dominique Görsch (dgoersch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Find ich auch immer wieder nervig, bei andern Basic-Derivaten kann man 
es manchmal wenigstens konfigurieren.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@gast:

Ja, Danke, Du hast recht, hatte ich einen Moment nicht dran gedacht.

Würde ja für den OP viel zu leicht, wenn man wirklich fehlerfreien Code 
liefern würde. :D

Problem ist einfach zu lösen, indem statt mit 0:

Char_ctr = 1

initiert wird, weitere Änderungen sind nicht notwendig.

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@MWS

Vielen Dank für deinen Code. Ich habe ihn getestet und soweit 
funktioniert er auch, allerdings komme ich mit der lookup tabelle nicht 
ganz klar.

Hier nochmal der Code:
Const Strl = 20                                             ' Länge des Strings
Const Orig_char_start = 64                                  ' Dezimalwert bei dem die alten Zeichen beginnen
Const Orig_char_end = 91                                    ' Dezimalwert bei dem die alten Zeichen enden
Dim String_in As String * Strl
Dim String_char(strl) As Byte At String_in Overlay
Dim Char_ctr As Byte , Char_val As Byte

Char_ctr = 1
Char_val = String_char(char_ctr)

While Char_val > 0
  If Char_val >= Orig_char_start And Char_val <= Orig_char_end Then       ' ***
    Char_val = Char_val - Orig_char_start                   ' ***
      String_char(char_ctr) = Lookup(char_val , New_char_val)
  End If                                                    ' ***

  Incr Char_ctr
  Char_val = String_char(char_ctr)

Wend

End

New_char_val:
Data 12 , 22 , 44 , 18 , 5                                  ' usw.

string_in ="AAAAAAAAAABBBBBBBBBB"

Ich habe testweise den Wert von char_val mit print char_val am UART 
ausgegeben und es erscheinen auch die Dezimalwerte 65 und 66 (jeweils 
10x).

Wie löse ich das mit der lookup tabelle?

Ich bekomme ja für ein "A" als char_val 65. Muss ich die Tabelle jetzt 
mit mindestens 65 Werten füllen, damit per lookup der Wert für "A" 
gefunden wird.

Vielleicht kannst Du mir nochmal ein kurzes Beispiel geben.
Folgende Hexwerte sollen den Chars entsprechen
A = &H00
B = &H01
C = &H02
...
1 = &H1E
2 = &H1F
3 = &H20
...

Danke schonmal.

Autor: Martha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Max wrote:
>Ich bekomme ja für ein "A" als char_val 65. Muss ich die Tabelle jetzt
>mit mindestens 65 Werten füllen, damit per lookup der Wert für "A"
>gefunden wird.

Kommt drauf an, welche Zeichen du alle darstellen willst.
Großbuchstaben gehen von dezimal 65 - 90, Zahlen von 48-57.
Wenn das alles ist und du es so machen willst wie oben beschrieben, 
fängst du in deinem Data mit dem char_val des kleinsten Wertes an, also 
mit der 0.
Dieses hat dann den Index 0, also musst du immer 48 vom Byte-Wert des 
Zeichens abziehen.
Dazu hat MWS das hier eingefügt:
Char_val = Char_val - Orig_char_start                   ' ***
wobei du

Const Orig_char_start = 64 abändern musst in

Const Orig_char_start = 65

weil Lookup widerum bei 0 anfängt

Wenn du sonst keine anderen Zeichen darstellen willst, kannst du auf das 
ganze Lookup und Data Zeugs verzichten und schreibst einfach:

Char_ctr = 1
While String_char(char_ctr) > 0
  If String_char(char_ctr) > 64 Then       ' ***
    Char_val = Char_val - 65                  ' für die Großbuchstaben
  else
    Char_val = Char_val - 48                  'für die Zahlen
  End If                                                    ' ***
  Printbin char_val;
  Incr Char_ctr
Wend

Gruß

Martha

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.