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.
:
Bearbeitet durch User
Du suchst das in Assembler? Da wäre die Angabe des Prozessors nicht schlecht. (Auch wenn die Profis das sicherlich erkennen)
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.
:
Bearbeitet durch User
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 ?
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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:
1 | ;****** Deinen Prozessor eintragen !!! ****** |
2 | .include "m328pdef.inc" |
3 | ;****** Deinen Prozessor eintragen !!! ****** |
4 | |
5 | |
6 | .DSEG |
7 | sram1: .byte 1 |
8 | sram2: .byte 1 |
9 | sram3: .byte 1 |
10 | sram4: .byte 1 |
11 | |
12 | LoByt: .byte 1 |
13 | HiByt: .byte 1 |
14 | |
15 | .CSEG |
16 | Init: |
17 | ldi zl, low(LoByt) ;* Oder auch: ldi zl, low(sram4+1) |
18 | ldi zh, high(LoByt) |
19 | clr r16 |
20 | st -Z, r16 ;* String endet normalerweise mit 0 |
21 | ldi r16, 0x34 |
22 | st -Z, r16 ;* '4' |
23 | ldi r16, 0x35 |
24 | st -Z, r16 ;* '5' |
25 | ldi r16, 0x32 |
26 | st -Z, r16 ;* '2' |
27 | rcall AscToBin2 ;* Z-Reg zeigt jetzt auf sram1 |
28 | sts LoByt, rBin1L ;* Als Kontrolle |
29 | sts HiByt, rBin1H |
30 | Eloop: |
31 | rjmp Eloop |
:
Bearbeitet durch User
vielen Dank nochmal für die Hilfe es geht jetzt alles wunderbar :)
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.