-         
+ Antworten
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 24

Thema: Zusammensetzen von Bytes zu einem Single-Datentyp

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2004
    Ort
    Gelsenkirchen
    Alter
    71
    Beiträge
    16

    Zusammensetzen von Bytes zu einem Single-Datentyp

    Hallo,

    ich möchte gerne über UART eine Single-Variable verschicken und abholen und das über einen längeren Zeitraum. Mit inputbin, aber auch input klappt das auch. Nur, wenn irgendwas nicht stimmt, bleibt das Programm gnadenlos stehen. Man kann noch so komplexe Abfangroutinen 8 inkey(), ischarwaiting usw.) entwerfen, letztendlich gibts dann doch einen Hänger...

    Will jetzt den Weg über den URXC Interrupt gehen. Es wird da byteweise eingelesen. Nur wie setzt man die Bytes - 4 glaube ich - einer ankommenden Single-Variablen wieder zu Single zusammen. Für Integer gibt es Makeint oder 256*msb+lsb. Wie geht das hier? Die ankommenden Bytes kann ich ich ja in ein Feld a(1) bis a(?) einlesen, aber dann ...?

    Wäre nett, wenn mir da jemand auf die Sprünge helfen könnte.

    Wolfgang

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.835
    Bin kein Basic-Guru, da werden sich gleich ein paar melden. vielleicht geht's so:
    a = 0
    i = 1
    data

    Interrrupt / character "data" kommt:
    a = a * 256
    a = a + ASC(data)
    i = i + 1
    if ( i> 4) signal "a is komplett"
    ende Interrrupt


    Ob das für Basic richtig formuliert is, weiss ich jetzt aber nicht mfg

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2004
    Ort
    Gelsenkirchen
    Alter
    71
    Beiträge
    16
    Danke für deinen Beitrag. Entschuldigung, dass ich mich jetzt erst melde. War überrschend in der Zwischenzeit außer Haus, konnte daher hier nicht reinschauen.

    Das Ganze scheint nicht ganz so einfach. Hier ein Ausschnitt aus der Bascom-Hilfe, der wahrscheinlich zeigt, dass das Zusammenfügen wohl aud unüberwindbare Schwierigkeiten stoßen wird:

    Code:
    Floating point (ASM code used is supplied by Jack Tidwell)
    Single numbers conforming to the IEEE binary floating point standard. 
    
    An eight bit exponent and 24 bit mantissa are supported.
    Using four bytes the format is shown below:
    
    31 30________23 22______________________________0
    s    exponent     mantissa
    
    The exponent is biased by 128. Above 128 are positive exponents and
    below are negative.  The sign bit is 0 for positive numbers and 1 for
    negative. The mantissa is stored in hidden bit normalized format so
    that 24 bits of precision can be obtained.
    Wolfgang

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.835
    Ich seh schon, alles klar.
    Ein Kollege (VB Specialist) hat mir gesagt, dass es so etws wie ein Union wie bei C (Redefinition eines Feldes) nicht gibt.
    Wenn'so ist, dann müssen wir das float eben auftröseln und wieder zusammenbauen. d.h wir interpretieren das Bit-Gewusel und rechnen die float einfach wieder aus.
    Leider bin ich heut ein bißchen in Druck und kann mich erst morgen wieder rühren.
    Bis dann halt, oder wem anderen fällt ein besserer Trick ein.
    Kopf hoch ! gibt's nicht, gibt's nicht
    mfg Robert

  5. #5
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.835
    Bist du noch da ?
    Ich schreib mehr oder weniger Pseudo-Code, weil's schon lange her ist, daß ich Basic geschrieben habe. Aber Du denkst ja mit.

    Bezieht sich auf das IEEE -Format, Microchip is a bißerl anders

    Wir brauchen:
    Vorzeichen = 0 (integer)
    Exponent = 0 (integer)
    Ergebnis = 0 (float 32 Bit == 4 Byte)

    Wir haben:
    Zeichen(1) bis Zeichen(4)

    1) Vorzeichen/Exponent: (*g* was sein muß, muß sein *g*)
    Das höchste Bit vom Exponenten ist das Vorzeichen
    WENN (ASC(Zeichen(1)) >= 12 dann:
    Vorzeichen = -1
    Exponent = ASC(Zeichen(1)) - 12 * 2
    ELSE
    Vorzeichen = +1
    Exponent = ASC(Zeichen(1)) * 2
    END-WENN

    2) Exponent Das kleinste Bit vom Exp. ist das höchste von Zeichen(2) bzw. der Mantisse (IEEE). Die Mantisse hat dort aber immer 1, deswegen steht der Einser explizit nicht da, den muß man sich denken

    WENN (ASC(Zeichen(2)) >= 12 dann:
    Exponent = Exponent + 1 (dort gehört der 1er hin)
    ELSE
    Zeichen(2) = CHR(ASC(Zeichen(2) + 12 (keiner da, g'hört aber hin)
    END-WENN
    Exponent = Exponent - 128 (Basis 12

    *schnauf* Diese eigentlich simple Bit-Shifterei geht vielleicht auch in Basic besser, weiss nicht.

    2 Mantisse:
    Ergebnis = asc(Zeichen(2)) * 65535
    + asc(Zeichen(3)) * 256
    + asc(Zeichen(4))

    3 ergebnis zu von 1nnnn auf 1,nnn umrechnen

    Ergebnis = Ergebnis / 8388480

    3 Exponent reinrechnen
    Exp. --> Ergebnis = Ergebnis * (2 hoch (+/-) Exponent)
    Vielleicht als schleife, "exponent"-mal

    4 Vorzeichen
    Ergebnis = Ergebnis * Vorzeichen

    *tiefseufz*

    EXAMPLE
    Testen natürlich mit bekannten Zahlen, einfachster Fall "+1.0"
    es sollte sein
    Zeichen(1) = 64
    Zeichen(2) = 0
    Zeichen(3) = 0
    Zeichen(4) = 0


    Vorzeichen = +1
    Exponent = ASC(Zeichen(1)) * 2 => 128
    Exponent = Exponent - 128 ==> 0
    Zeichen(2) = CHR(ASC(Zeichen(2) + 12 (Einser muß aber sein)

    Zeichen(2) = 128 (erst jetzt)
    Zeichen(3) = 0
    Zeichen(4) = 0

    Ergebnis = 128 * 65535 + 0 + 0 => 8388480
    Ergebnis = Ergebnis / 8388480 ==> 1

    Exp. + --> Ergebnis = Ergebnis * (2 hoch 0 ) ==> 1

    Vorzeichen ist +1 -- => also bleibt 1.0


    *ganztiefseufz*


    Ich hoffe, ich habe dir da keinen Stiefel erzählt, prinzipiell bin ich mir sicher, aber ich werd's selbst noch testen


    Laß hören ! mfg robert

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2004
    Ort
    Gelsenkirchen
    Alter
    71
    Beiträge
    16
    bin noch da, muss zwar nicht essen, aber mit meiner Frau in die Stadt, es weihnachtet langsam... so gegen 19 Uhr denke ich wirds schon..

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2004
    Ort
    Gelsenkirchen
    Alter
    71
    Beiträge
    16
    ooops, das ist ja ne ganze Doktorarbeit geworden. Irgendwie kriege ich keine freie Zeit hin. Jetzt haben wir auch noch Besuch... Aber ich denke, gegen 22 Uhr kann ich mich diesen tollen Gedanken widmen. Meine Güte, Du bist ja ganz schön drin in dieser Materie. Habe viel mit Zahlen zu tun, aber mit Mantissen und Exponenten schon lange nicht mehr.

    Habe zwischenzeitlich auch in einem Bascom Buch das Kapitel über Single gelesen. Habe da nicht viel verstanden, wenn ich ehrlich bin. Habe aber eine Formel:

    x=(-1)s*1.M*2(E-127)

    wobei S das Vorzeichen, M Mantisse und E der Exponent ist. Das fett-geschriebene soll hoch..., also ein Eponent sein. Habe nichts gefunden, wie man das setzt.

    Code:
    b(31) = S
    b(30-23)= E
    b(22-0)=M
    Aber wie gesagt, kann mich erst gleich darum kümmern. Es gibt irgendein Programm AVRCalc, mit dem man das besser aufrödeln kann. Kenne ich leider nicht.

    Danke für die Lösung, die man jetzt noch schön verpacken muss. Tolle Leistung!

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    19.07.2004
    Ort
    Gelsenkirchen
    Alter
    71
    Beiträge
    16
    habe mal eine Struktur daraus gemacht, wie es im Programm aussehen könnte. Noch nicht getestet.

    Code:
    Dim Vorzeichen As Integer
    Dim Exponent As Integer
    Dim Ergebnis As Single
    Dim Fertig As Bit
    Dim Zähler As Byte                 '***** Feldzähler
    Dim Zeichen(4) As Byte
    Dim Temp As Byte
    Dim Sendeanforderung As String * 1
    
    Const True = 1
    Const False = 0
    
    
    On Urxc Hole_bytes
    
    Enable Interrupts
    
    Main:
    
    Sendeanforderung = "!"
    Do
      '..
      '..
      '**** Aufforderung zum Senden
      Printbin Sendeanforderung   '**** ohne Chr(10) und Chr(13)
      '**** Sender sendet nun
      '***** eventuell nur temporär einschalten, falls noch andere Interrupts laufen
      'enable urxc
      i=1 '**** Feldzähler initialisieren
      While Fertig = True
          '***** geht in Bascom nicht in einer Zeile!
          '***** braucht man wahrscheinlich Integer-Variablen für die Zwischenwerte
          '***** muss ich noch klären
          Ergebnis = Zeichen(2) * 65535 + Zeichen(3) * 256 + Zeichen(4)
          Ergebnis = Ergebnis / 8388480       '**** warum?
          Ergebnis = Ergebnis * 2 ^ Exponent
          Ergebnis = Ergebnis * Vorzeichen
          Print Ergebnis
          Fertig = False
      Wend
      'disable urxc
    
    Loop
    
    End
    
    Hole_bytes:
    Temp = Udr                    '**** 1 Zeichen aus Register empfangen, ist ascii
    Select Case Zähler
        Case 1
            If Temp.7 = 1 Then    '**** größer 128
              Vorzeichen=-1
              Exponent = Temp - 128
              Exponent = Exponent * 2
            else
              Vorzeichen = 1
              Exponent = Temp * 2
            endif
            Zeichen(zähler) = Temp
            Incr Zähler
        Case 2
            If Temp.7 = 1 Then
                Incr Exponent
            Else
                Zeichen(Zähler) = Temp + 128       '**** du hast chr(..), warum?
            End If
            Exponent = Exponent - 128
            Incr Zähler
        Case 3 To 4
             Zeichen(zähler) = Temp
             Incr Zähler
             Fertig = True
    End Select
    
    Return
    Auf dieser Basis lässt sich vielleicht weiterarbeiten.

  9. #9
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.835
    Sag ich ja, wenn einer Basic kann, sieht das gleich besser aus, als bei mir.
    Durch den Typ "BYTE", bei dem man die Bits offenbar auch einzeln anquatschen kann, ist natürlich die ganze "ASC" und "CHR" Sache überflüssig. ( ASC("A") => 65, CHR(65) => "A" )

    hoppperla, ogott ogott ogott die zahl 8388480 ist falsch !
    Das soll sein hex "00800000" ==> "8388608"
    Ich bin für öffentliches Auspeitschen ! da kann sich ja keiner auskennen !

    Code u. Test:
    laß dir wirklich eine Zahl schicken, die einfach ist und die du kennst, wie eben 1.0 und schreib' dir auf, am besten als hex oder Bitmuster, wie die vier Zeichen tatsächlich aussehen. Und dann geh dein Programm, das mir übrigens koscher vorkommt, so richtig mit Taschenrechner, Bleistift und Papier step by step durch.

    Tips:
    aufpassen, ob der Typ "BYTE" mit oder ohne Vorzeichen ist. Wenn ja, wär's blöd, weil er dann alle Byte.7 =1 Zahlen als negative Zahlen sieht (das war auch der Grund für meine ASC und CHR)

    Du wirst beim Testen gleich sehen, ob die 4 Byte von rechts oder links kommen.

    Ebenso wirst du sehen, ob man vom Exponenten von wirklich 128 oder doch 127 abziehen muß.

    Performance: Mantisse * 2 ^^ Exponent ist richtig, aber möglicherweise für Arbeit für deinen Fuzzy. Wenn möglich, Byte-Shiften (links => *2, rechts => /2) in einer Schleife.

    Wie auch immer, wenn du da durch bist, hast du über "Computer inside" mehr erfahren als durch drei Mandelbrotmengen.

    Auf geht's ! mfg Robert

    PS Laß hören, ich will ja auch was lernen !

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.11.2003
    Ort
    Dresden
    Alter
    52
    Beiträge
    409
    Der Begriff union kam ja schon, ebenso die Aussage das dies in Bascom nicht geht. Aber es gehen doch wohl absolute Vars.

    Das heißt sowohl der Single Value als auch das Array auf dem selben Speicherplatz. Die BASCOM-Hilfe spuckt dazu aus:

    DIM var AS [XRAM/SRAM/ERAM] type [AT location] [OVERLAY]

    Also mit AT wird der Speicherplatz vorgegeben und die zweite Var muss wohl noch den Qualifier OVERLAY dazubekommen.

    Hab's nicht ausprobiert, aber so sollte es auch gehen, ohne das Float-Format auseinanderzudrieseln.

    Schönen 2. Advent und
    Viele Grüße
    Jörg

+ Antworten
Seite 1 von 3 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Ja
  • Themen beantworten: Ja
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •