Hallo liebes Forum,
ich hab jetzt hier das forum und internet durchstöbert aber leider nix
passendes gefunden.
Ich muss meine Daten 3 ASCII zeichen in ein Binärbyte umwandeln. Meine
Werte sind immer kleiner gleich 255.
Ich habe eine Routine gefunden die das kann, weiss aber nicht so recht
wie ich dieser Routine die Daten übergeben muss damit ich hinterher mein
binär Byte rauskriege.
Zum Beispiel: ich hab drei zeichen im SRAM stehen sram1: 2 Sram2: 5 sram
3: 4
das würde dann einem Wert binär von 254 ergeben.
Wie muss ich den Z pointer jetzt einstellen damit er mir das umwandelt?
und wie müssen die ASCII zeichen im SRAM abgelegt sein damit die
berechnung hinterher stimmt ?
Grüße
Stefan
; AscToBin2
; =========
; converts an ASCII coded number to a 2-Byte bi-
; nary
; In: Z points to first digit, conversion stops at first
; digit detected or if overflow of the result occurs,
; end of number must be terminated by a non-decimal
; ASCII-digit!
; Out: Z points to first non-valid digit or to the digit
; where the overflow occurred, if number is valid the
; T-Flag is clear and the number is in registers
; rBin1H:rBin1L
; Used registers: rBin1H:L (result), rBin2H:L (restored
; after use), rmp
; Called subroutines: Bin1Mul10
;
AscToBin2:
clr rBin1H ; Clear the result
clr rBin1L
clt ; Clear error flag bit
AscToBin2a:
ld rmp,Z+ ; ignore leading blanks and zeros
cpi rmp,' ' ; blank?
breq AscToBin2a
cpi rmp,'0' ; zero?
breq AscToBin2a
AscToBin2b:
subi rmp,'0' ; subtract ASCII zero
brcs AscToBin2d ; End of the number
cpi rmp,10 ; check invalid digit
brcc AscToBin2d ; No-decimal char
rcall Bin1Mul10 ; Multiply binary number by 10
brts AscToBin2c ; overflow, return with T-Flag set
add rBin1L,rmp ; add the digit to the binary
ld rmp,Z+ ; read next char
brcc AscToBin2b ; no overflow to binary MSB
inc rBin1H ; Overflow to binary MSB
brne AscToBin2b ; no overflow of binary MSB
set ; Set overflow flag
AscToBin2c:
sbiw ZL,1 ; Back one char, last char end/invalid
AscToBin2d:
ret
; Bin1Mul10
; =========
; multiplies a 16-bit-binary by 10
; Sub used by: AscToBin2, Asc5ToBin2, Bcd5ToBin2
; In: 16-bit-binary in rBin1H:L
; Out: T-flag shows general result:
; T=0: Valid result, 16-bit-binary in rBin1H:L ok
; T=1: Overflow occurred, number too big
;
Bin1Mul10:
push rBin2H ; Save the register of 16-bit-binary 2
push rBin2L
mov rBin2H,rBin1H ; Copy the number
mov rBin2L,rBin1L
add rBin1L,rBin1L ; Multiply by 2
adc rBin1H,rBin1H
brcs Bin1Mul10b ; overflow, get out of here
Bin1Mul10a:
add rBin1L,rbin1L ; again multiply by 2 (4*number reached)
adc rBin1H,rBin1H
brcs Bin1Mul10b ; overflow, get out of here
add rBin1L,rBin2L ; add the copied number (5*number reached)
adc rBin1H,rBin2H
brcs Bin1Mul10b ;overflow, get out of here
add rBin1L,rBin1L ; again multiply by 2 (10*number reached)
adc rBin1H,rBin1H
brcc Bin1Mul10c ; no overflow occurred, don't set T-flag
Bin1Mul10b:
set ; an overflow occurred during multplication
Bin1Mul10c:
pop rBin2L ; Restore the registers of 16-bit-binary 2
pop rBin2H
ret
Stefan S. schrieb:> Ich muss meine Daten 3 ASCII zeichen in ein Binärbyte umwandeln.
Das geht gar nicht. Ein ASCII Zeichen ist genau 8 Bits (vulgo: 1 Byte)
lang. 3 Zeichen brauchen also auch 3 Bytes.
> Zum Beispiel: ich hab drei zeichen im SRAM stehen sram1: 2 Sram2: 5 sram> 3: 4
Das sind keine Zeichen, sondern Zahlen. 2 ist eine Zahl. Das Zeichen '2'
muß in einfache Anführungszeichen gesetzt werden. Und es entspricht dann
der Zahl 50 (siehe https://de.wikipedia.org/wiki/ASCII-Tabelle)
> das würde dann einem Wert binär von 254 ergeben.
Auch wieder falsch. Das ist nicht binär, sondern dezimal. Die
Dezimalzahl 254 besteht aus den Ziffern 2, 5 und 4 - in absteigender
Wertigkeit.
Aber so langsam verstehe ich, was du erreichen willst. Auch wenn du
selber das noch gar nicht verstehst. Du willst aus einem Array, das die
Ziffern einer dreistelligen Dezimalzahl enthält, den Wert der Zahl
ausrechnen.
Und dazu mußt du erst mal wissen, wie sich der Wert einer Dezimalzahl
aus den einzelnen Ziffern ergibt. Dazu empfehle ich weitere
Wikipedia-Artikel:
https://de.wikipedia.org/wiki/Dezimalsystem
Damit solltest du den direkten Weg für eine dreistellige Zahl
hinschreiben können. Hinweis: es kommt eine Multiplikation mit 10 und
eine mit 100 darin vor.
https://de.wikipedia.org/wiki/Horner-Schema
Das ist dann der bessere Weg für Zahlen mit einer variablen Anzahl
Stellen. Es kommen nur noch Multiplikationen mit 10 vor. Und natürlich
Additionen. Das oben gezeigte Programm verwendet diesen Ansatz.
Stefan S. schrieb:> Zum Beispiel: ich hab drei zeichen im SRAM stehen sram1: 2 Sram2: 5 sram> 3: 4> das würde dann einem Wert binär von 254 ergeben.
Nein.
Das würde einen Hex Wert von 0x452 ergeben oder Dezimal 1106.
Binär kennt als Wert nur 0 oder 1.
> Wie muss ich den Z pointer jetzt einstellen damit er mir das umwandelt?> und wie müssen die ASCII zeichen im SRAM abgelegt sein damit die> berechnung hinterher stimmt ?
Steht doch alles oben:
sram1: 0x32 Sram2: 0x35 sram3: 0x34 sram4: 0x00
Z => 0x0001 (zl = 1 / zh = 0)
Und das Resultat ist danach in rBin1H:rBin1L
0x00 : 0xFE
P.S.
Wobei die SRAM Adresse nicht 1 sein kann.
SRAM fängt meistens bei 0x100 an.
ich kenne schon den unterschied zwischen den datentypen... hatte mich
nur verschrieben...
also sagen wir da drin steht als ascii dezimal:
sram3 : 50 Sram2: 53 Sram1: 52
umgerechnet wären dass dann quasi 254 dezimal und binär 0b01111111 wenn
man sie zusammenreiht und das möchte ich...
aber nochmal zu der frage :
Wie muss ich den Z pointer jetzt einstellen damit er mir das umwandelt?
und wie müssen die ASCII zeichen im SRAM abgelegt sein damit die
berechnung hinterher stimmt ?
Marc V. schrieb:>> sram1: 0x32 Sram2: 0x35 sram3: 0x34 sram4: 0x00> Z => 0x0001 (zl = 1 / zh = 0)>> Und das Resultat ist danach in rBin1H:rBin1L> 0x00 : 0xFE>> P.S.> Wobei die SRAM Adresse nicht 1 sein kann.> SRAM fängt meistens bei 0x100 an.
also wäre das zum testen so richtig ?
ldi temp, 53 ;ascii zeichen "4"
sts Sram_start+45, temp
ldi temp, 54 ;ascii zeichen "5"
sts Sram_start+46, temp
ldi temp, 50 ;ascii zeichen "2"
sts Sram_start+47, temp
ldi temp, 0 ;keine zahl als ascii
sts Sram_start+48
ldi ZH, 0
ldi ZL, Sram_start+45
call AscToBin2
out PortB, rBin1L
Stefan S. schrieb:> Wie muss ich den Z pointer jetzt einstellen damit er mir das umwandelt?> und wie müssen die ASCII zeichen im SRAM abgelegt sein damit die> berechnung hinterher stimmt ?
So:
Eine eigene Frage?
Dieser Thread ist über 9 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.