- 3D-Druck Einstieg und Tipps         
Seite 5 von 7 ErsteErste ... 34567 LetzteLetzte
Ergebnis 41 bis 50 von 65

Thema: Bascom Inline-Assembler

  1. #41
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hier sind die Berechnungen im Code:
    Code:
    '--Noise filter--
    For I = 1 To 5
      Meanrx(i) = Meanrx(i) * 3
      Meanrx(i) = Meanrx(i) + Empf(i)                           '"lowpass filter" of the RC signal
      Shift Meanrx(i) , Right , 2                               ' (=divide by 4)
      Aempfh(i) = Meanrx(i) + 17                                'upper acceptable fluctuation
      Aempfl(i) = Meanrx(i) - 17                                'lower acceptable fluctuation
      If Empf(i) > Aempfh(i) Or Empf(i) < Aempfl(i) Then        'compare allowed fluctuation with current rc reading
         Empf(i) = Meanrx(i)                                    'if fluctuation was too high -> replace with averaged value
         Print "Error reading channel: " ; I                    'handy to check for RC problems
      End If
    Next
    
    'Empf(X) are filled in "getreceiver". They usually contain values ranging from 63 - 137.
    'Empf(throttlechannel) is the throttle stick. it will be rescaled differently.
    If Empf(throttlechannel) > 61 And Empf(throttlechannel) < 139 Then       'don't process values that can't be correct
      Sempf(throttlechannel) = Empf(throttlechannel) - 61
      Sempf(throttlechannel) = Sempf(throttlechannel) * 3       '==> values ranging from 3 (stick at bottom) to 228 (full throttle)
    End If
    'Now nick, roll, yaw and idle up switch
    
    If Empf(nickchannel) > 61 And Empf(nickchannel) < 139 Then  'don't process values that can't be correct
      Sempf(nickchannel) = Empf(nickchannel) - 100              'convert to values ranging from -37 to +37
    End If
    If Empf(rollchannel) > 61 And Empf(rollchannel) < 139 Then  'don't process values that can't be correct
      Sempf(rollchannel) = Empf(rollchannel) - 100              'convert to values ranging from -37 to +37
    End If
      If Empf(yawchannel) > 61 And Empf(yawchannel) < 139 Then  'don't process values that can't be correct
      Sempf(yawchannel) = Empf(yawchannel) - 100                'convert to values ranging from -37 to +37
    End If
    If Empf(5) > 61 And Empf(5) < 139 Then                      'don't process values that can't be correct
      Sempf(5) = Empf(5) - 100                                  'convert to values ranging from -37 to +37
    End If
    Eigentlich findet alles nicht im Array statt, trotzdem gehts nicht als Byte. Vielleicht liegt das daran, dass bei Fehlerhaftem Signal die Variable Meanrx in Empf geschrieben wird. Sicher bin ich mir da aber nicht. Vielleicht hast du eine Erklärung?

    Gruß
    Chris

  2. #42
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Hatte mich ein wenig gespielt, mit Testumgebung:
    Code:
    $Regfile = "m32def.dat"
    $Crystal = 4000000
    $hwstack = 32
    $swstack = 8
    $framesize = 24
    
    '(
    Isr_int0:
    If Channel > 0 And Channel < 6 Then
      Empf(channel) = Timer0
    End If
    Timer0 = 6
    Incr Channel
    Return
    ')
    
    Dim tmp as Byte
    
    Dim Empf(5) As Word
    Dim Channel As Byte
    Dim Empf_tmp As Word
    
    Do
      channel = 0
        For tmp = 0 To 7
          TCNT0 = 255 - tmp
            Gosub Isr_int0
        Next tmp
    Loop
    
    
    Isr_int0:                                                   ' cycles in range: 53, out of range: 29
    !PUSH    R16
    !IN      R16,       SREG
    !PUSH    R16
    !LDS     R16,       {channel}
    !DEC     R16
    !CPI     R16,       5
    !BRCC    NotInRange
    !PUSH    R17
    !PUSH    XL
    !PUSH    XH
    LoadAdr Empf(1) , X
    !MOV     R17,       R16
    !LSL     R17
    !ADD     XL,        R17
    !CLR     R17
    !ADC     XH,        R17
    !IN      R17,       TCNT0
    !ST      X+,        R17
    !CLR     R17
    !ST      X,         R17
    !POP     XH
    !POP     XL
    !POP     R17
    !NotInRange:
    !INC     R16
    !INC     R16
    !STS     {channel}, R16
    !LDI     R16,       6
    !OUT     TCNT0,     R16
    !POP     R16
    !OUT     SREG,      R16
    !POP     R16
    Return
    
    '(
    Isr_int0:                                                   ' cycles in range: 51, out of range: 30
    !PUSH    R16
    !IN      R16,       SREG
    !PUSH    R16
    !LDS     R16,       {channel}
    !DEC     R16
    !CPI     R16,       5
    !BRCC    NotInRange
    !PUSH    R17
    !PUSH    XL
    !PUSH    XH
    LoadAdr Empf(1) , X
    !CLR     R17
    !LSL     R16
    !ADD     XL,        R16
    !ADC     XH,        R17
    !IN      R16,       TCNT0
    !ST      X+,        R16
    !ST      X,         R17
    !POP     XH
    !POP     XL
    !POP     R17
    !NotInRange:
    !LDS     R16,       {channel}
    !INC     R16
    !STS     {channel}, R16
    !LDI     R16,       6
    !OUT     TCNT0,     R16
    !POP     R16
    !OUT     SREG,      R16
    !POP     R16
    Return
    ')
    die Variable Meanrx in Empf geschrieben wird
    Ich sehe nicht ohne Weiteres, wie groß die werden kann.

    Diese Zugriffe dürften übrigens recht "teuer" sein in Bezug auf die Ausführungszyklen:
    Code:
    If Empf(throttlechannel) > 61 And Empf(throttlechannel) < 139 Then       'don't process values that can't be correct
    Sempf(throttlechannel) = Empf(throttlechannel) - 61
    Wenn Bascom die Arrayadresse nicht zur Compilezeit kennt, wie bei einem durch Variable indizierten Array, so wird zu jedem Vergleich die gleiche Arrayzelle immer wieder neu geladen. Du könntest durch temporäre Variablen eine Beschleunigung der Rechnung erreichen.

    Und da Du ein Word nicht atomar verarbeiten kannst, hättest Du auch ein Problem wenn im Wordarray tatsächlich Werte > 255 drinstehen würden.
    Du kannst nicht verhindern (außer durch Sperren der Interrupts) dass der Interrupt gerade dann unterbricht, nachdem das erste Byte von Empf(x) zum Vergleich eingelesen wurde, die ISR Empf(x) dann beide Bytes verändert und nach Rückkehr das zweite Byte des nun veränderten Empf(x) zusammen mit dem ersten, nicht veränderten Byte weiterverarbeitet wird.

  3. #43
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Also erstmal möchte ich dir frohe Weihnachten wünschen
    Das finde ich sehr nett, dass du dir soviel Mühe gibst.

    Meanrx liegt zwischen 63 und 137, das sind die beiden maximalen Knüppelstellungen. Allerdings stimmt das nicht ganz, da das ja ein Tiefpass ist und dieser normalerweise diese Extremwerte nicht erreichen kann. Eigentlich sehe ich keinen Grund, warum Empf kein Byte sein kann, aber ich habs mal probeweise eingespielt und da hats nicht funktioniert... Ich werds aber morgen nochmal probieren.

    Hm, das habe ich mir schon gedacht. Aber wenns morgen mit einem Byte doch funktionieren sollte, dann ist das ja nicht mehr soooo schlimm, oder?
    Also Werte > 255 werden nie im Empf-Array drinstehen.
    Was genau meinst du mit temporären Variablen? So:
    Code:
    Dim Tmp1 As Word
    Dim Tmp2 As Word
    Dim Tmp3 As Word
    Dim Tmp4 As Word
    Dim Tmp5 As Word
    
    ...
    
    Tmp1 = Empf(1)
    Tmp2 = Empf(2)
    Tmp3 = Empf(3)
    Tmp4 = Empf(4)
    Tmp5 = Empf(5)
    
    If Tmp1 > 61 And Tmp1 < 139 Then
       Sempf(1) = Tmp1 - 61
       Sempf(1) = Sempf(1) * 3
    End If
    Oder so:
    Code:
    Dim Tmp1 As Word
    Dim Tmp2 As Word
    Dim Tmp3 As Word
    Dim Tmp4 As Word
    Dim Tmp5 As Word
    
    Dim Stmp1 As Integer
    Dim Stmp2 As Integer
    Dim Stmp3 As Integer
    Dim Stmp4 As Integer
    Dim Stmp5 As Integer
    
    
    ...
    
    
    Tmp1 = Empf(1)
    Tmp2 = Empf(2)
    Tmp3 = Empf(3)
    Tmp4 = Empf(4)
    Tmp5 = Empf(5)
    
    If Tmp1 > 61 And Tmp1 < 139 Then
       Stmp1 = Tmp1 - 61
       Stmp1 = Stmp1 * 3
    End If
    
    Sempf(1) = Stmp1
    Vielen Dank & Gruß
    Chris

  4. #44
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Also erstmal möchte ich dir frohe Weihnachten wünschen
    Danke, das wünsch' ich Dir auch
    Das finde ich sehr nett, dass du dir soviel Mühe gibst.
    Ist auch ein Thema, das mich interessiert.
    ...aber ich habs mal probeweise eingespielt und da hats nicht funktioniert... Ich werds aber morgen nochmal probieren.
    Da ist's dann interessant wie Du das machst, poste doch mal den entsprechenden Code. Würde dann das Byte Empf(x) vor weiterer Verarbeitung einer temporären Word-Variable zuweisen.
    Hm, das habe ich mir schon gedacht. Aber wenns morgen mit einem Byte doch funktionieren sollte, dann ist das ja nicht mehr soooo schlimm, oder?
    Ist nicht schlimm, da scheinbar kein schädlicher Nebeneffekt auftritt, wenn Highbyte des Words immer 0 ist, gibt's auch kein Problem durch Interruptunterbrechung.
    Du verschwendest halt ein paar Bytes SRam und ein paar Zyklen.
    Also Werte > 255 werden nie im Empf-Array drinstehen.
    Dann kann man die ISR ein wenig kürzer halten, siehe unten.
    Was genau meinst du mit temporären Variablen? So:
    So:
    Code:
    Empf_Tmp = Empf(throttlechannel)
    Sempf_Tmp = Sempf(throttlechannel)
    If Empf_Tmp > 61 And Empf_Tmp < 139 Then                      'don't process values that can't be correct
      Sempf_Tmp = Empf_Tmp - 61
      Sempf_Tmp = Sempf_Tmp * 3                                 '==> values ranging from 3 (stick at bottom) to 228 (full throttle)
        Empf(throttlechannel) = Empf_Tmp
        Sempf(throttlechannel) = Sempf_Tmp
    End If
    Und genauso mit nick, roll und yaw.

    Du hast bemerkt, dass mein vorher geposteter Code dafür gedacht ist, im Simulator zu laufen ?
    So kann ohne großartige Rumprobiererei am lebenden Objekt die ISR auf korrekte Funktion überprüft werden.

    Wenn Probleme beim Vergleich Byte mit Word existieren, dann solltest Du Michaels Ratschlag zum Update nachkommen.

    Hier der Bytearraycode:
    Code:
    Dim Empf(5) As Byte
    ' ...
    Isr_int0:                                                   ' byte-array, cycles in range: 43, out of range: 28
    !PUSH    R16
    !IN      R16,       SREG
    !PUSH    R16
    !LDS     R16,       {channel}
    !INC     R16
    !STS     {channel}, R16
    !SUBI    R16,       2
    !CPI     R16,       5
    !BRCC    NotInRange
    !PUSH    XL
    !PUSH    XH
    LoadAdr Empf(1) , X
    !ADD     XL,        R16
    !CLR     R16
    !ADC     XH,        R16
    !IN      R16,       TCNT0
    !ST      X,         R16
    !POP     XH
    !POP     XL
    !NotInRange:
    !LDI     R16,       6
    !OUT     TCNT0,     R16
    !POP     R16
    !OUT     SREG,      R16
    !POP     R16
    Return
    Geändert von MagicWSmoke (24.12.2011 um 20:36 Uhr)

  5. #45
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Also, ich habs gerade nochmal probiert:
    Code:
    Config Pind.2 = Input
    Portd.2 = 0
    Config Int0 = Rising
    On Int0 Getreceiver Nosave
    Config Timer0 = Timer , Prescale = 256
    On Timer0 Detectrxpause Nosave                              'timer overflow = pause in receiver's signal
    
    Dim Empf(5) As Byte
    
    ...
    
    Getreceiver:                                                'byte-array, cycles in range: 43, out of range: 28
    !PUSH    R16
    !IN      R16,       SREG
    !PUSH    R16
    !LDS     R16,       {channel}
    !INC     R16
    !STS     {channel}, R16
    !SUBI    R16,       2
    !CPI     R16,       5
    !BRCC    NotInRange
    !PUSH    XL
    !PUSH    XH
    LoadAdr Empf(1) , X
    !ADD     XL,        R16
    !CLR     R16
    !ADC     XH,        R16
    !IN      R16,       TCNT0
    !ST      X,         R16
    !POP     XH
    !POP     XL
    !NotInRange:
    !LDI     R16,       6
    !OUT     TCNT0,     R16
    !POP     R16
    !OUT     SREG,      R16
    !POP     R16
    Return                                                   'that means that there are problems with the receiver
    
    
    Detectrxpause:
    !PUSH    R16
    !IN      R16,       SREG
    !PUSH    R16
    !ldi     R16,       0
    !sts     {channel}, R16
    !POP     R16
    !OUT     SREG,      R16
    !POP     R16
    Return
    Es funktioniert doch, anscheinend hatte ich damals irgendwo einen Fehler...
    Habe jetzt auch den Timer0 Interrupt umgeschrieben, wäre nett, wenn du kurz drüberschauen könntest, obs so passt!? Fliegen tut das ganze
    Meinst du, ich solle jetzt noch die Arrays mit den temporären Variablen verändern? Habs gerade mal probiert, mithilfe der Overlay Funktion würde kein zusätzlicher Speicher verbraucht.
    Code:
    Dim Tmp1 As Byte At Empf(1) Overlay
    Dim Tmp2 As Byte At Empf(2) Overlay
    Dim Tmp3 As Byte At Empf(3) Overlay
    Dim Tmp4 As Byte At Empf(4) Overlay
    Dim Tmp5 As Byte At Empf(5) Overlay
    Außerdem würde ich mir dann die Zuweisung tmpx <--> empf(x) sparen?!
    Hältst du das für sinnvoll?

    Gruß
    Chris

    EDIT:
    Hab gerade folgendes eingefügt:
    Code:
    Dim Tmp1 As Byte At Empf(1) Overlay
    Dim Tmp2 As Byte At Empf(2) Overlay
    Dim Tmp3 As Byte At Empf(3) Overlay
    Dim Tmp4 As Byte At Empf(4) Overlay
    Dim Tmp5 As Byte At Empf(5) Overlay
    Dim Stmp1 As Integer At Sempf(1) Overlay
    Dim Stmp2 As Integer At Sempf(2) Overlay
    Dim Stmp3 As Integer At Sempf(3) Overlay
    Dim Stmp4 As Integer At Sempf(4) Overlay
    Dim Stmp5 As Integer At Sempf(5) Overlay
    Der Code funktioniert. Ich werde jetzt mal im Simulator testen, ob der Code dadurch schneller läuft. Melde mich dann wieder

    EDIT2:
    Hab gerade im Simulator folgendes probiert:
    Code:
    If Sempf(1) > -37 And Sempf(1) < 37 Then
       !nop
    End If
    
    If Stmp1 > -37 And Stmp1 < 37 Then
       !nop
    End If
    Beide IF-Abfragen brauchen incl. dem !Nop genau 34 Takte. Habe ich etwas anderes gemacht, als du gemeint hast oder bringts doch keine Besserung?
    Geändert von Che Guevara (24.12.2011 um 22:09 Uhr)

  6. #46
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Es funktioniert doch, anscheinend hatte ich damals irgendwo einen Fehler...
    Schön
    Habe jetzt auch den Timer0 Interrupt umgeschrieben, wäre nett, wenn du kurz drüberschauen könntest, obs so passt!? Fliegen tut das ganze
    Speziell in diesem Fall kannst Du Dir das Sichern des SREGs sparen, denn weder LDI noch STS verändert das SREG. Würdest Du statt dessen !CLR R16 schreiben, wär's etwas anderes.
    Code:
    Detectrxpause:
    !PUSH    R16
    !LDI     R16,       0
    !STS     {channel}, R16
    !POP     R16
    Return
    Habs gerade mal probiert, mithilfe der Overlay Funktion würde kein zusätzlicher Speicher verbraucht.
    Hältst du das für sinnvoll?
    Ich seh' jetzt nicht so recht, wie Du im gezeigten Noise-Filter Code mit Overlay arbeiten willst.

    Wie sieht's den mit der Aufrufrate dieses Noise-Filter Codes aus ? Normalerweise sind solche Filter an ein Timing gebunden. Oder läuft der da so schnell er kann ?
    Müsstest mal den Code extrahieren und alleine laufen lassen, um zu sehen wie viel Rechenleistung der frisst und ob es lohnt da viel Arbeit reinzustecken.

    Edit:
    Das hier kann der Compiler zur Compilezeit auflösen und es ist deshalb genauso schnell wie die Adressierung einer einzelnen Variable.
    Code:
    If Sempf(1) > -37 And Sempf(1) < 37 Then
    Das kann der Compiler nicht vorher auflösen, da er den Wert von "i" nicht kennt, das kostet mehr Code und Ausführungszeit:
    Code:
    If Sempf(i) > -37 And Sempf(i) < 37 Then

  7. #47
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Ok, habs jetzt ohne Sichern des SREG. Danke!

    Nein, beim Noise-Filter-Code verwende ich die Overlays nicht, da hier die Schleife einfach einfacher ist
    Die Overlays werden nur im restlichen Programm verwendet, z.b. bei den darauffolgenden Zeilen:
    Code:
    If Tmp1 > 61 And Tmp1 < 139 Then                            'don't process values that can't be correct
      Stmp1 = Tmp1 - 61
      Stmp1 = Stmp1 * 3                                         '==> values ranging from 3 (stick at bottom) to 228 (full throttle)
    End If
    'Now nick, roll, yaw and idle up switch
    
    If Tmp3 > 61 And Tmp3 < 139 Then                            'don't process values that can't be correct
      Stmp3 = Tmp3 - 100                                        'convert to values ranging from -37 to +37
    End If
    If Tmp2 > 61 And Tmp2 < 139 Then                            'don't process values that can't be correct
      Stmp2 = Tmp2 - 100                                        'convert to values ranging from -37 to +37
    End If
    If Tmp4 > 61 And Tmp4 < 139 Then                            'don't process values that can't be correct
      Stmp4 = Tmp4 - 100                                        'convert to values ranging from -37 to +37
    End If
    If Tmp5 > 61 And Tmp5 < 139 Then                            'don't process values that can't be correct
      Stmp5 = Tmp5 - 100                                        'convert to values ranging from -37 to +37
    End If
    Hm, also der Code wird so schnell wie möglich aufgerufen:
    Code:
    Do
      Acc
      Gyro
      Mixer
      Send_mots
      Led
      Voltage
      Failsave
      Guiconnection
    Loop
    End
    Die Mixer-Sub beinhaltet den Noise-Filter Code. Meinst du den Filter-Code? Das werde ich gleich mal machen.

    Gruß
    Chris

  8. #48
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Die Mixer-Sub beinhaltet den Noise-Filter Code. Meinst du den Filter-Code?
    Ja, weil man dann sieht, wo's sich lohnt zu optimieren und wo nicht.
    Mein Edit hast Du gelesen ?
    Ob Du über Array(1) oder über Overlay Array(1) adressierst bleibt sich gleich. Nur Array(Variable) = Array(Variable) + andere Variable macht einen deutlichen Unterschied.

  9. #49
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Das Edit habe ich gerade eben gelesen. Das leuchtet natürlich ein.
    Was meinst du mit
    Nur Array(Variable) = Array(Variable) + andere Variable macht einen deutlichen Unterschied.
    ?
    Meinst du, dass
    Code:
    Stmp1 = Stmp1 + Tmp1
    schneller als
    Code:
    Sempf(1) = Sempf(1) + Tmp1
    ist?

    Gruß
    Chris

  10. #50
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Meinst du, dass
    Code:
    Stmp1 = Stmp1 + Tmp1
    schneller als
    Code:
    Sempf(1) = Sempf(1) + Tmp1
    ist?
    Nein, gleich schnell.
    Das ist langsamer:
    Code:
     Sempf(i) = Sempf(i) + Tmp1

Seite 5 von 7 ErsteErste ... 34567 LetzteLetzte

Ähnliche Themen

  1. Inline Assembler
    Von Che Guevara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 01.02.2010, 19:25
  2. AVR GCC inline Assembler
    Von chientech im Forum Assembler-Programmierung
    Antworten: 1
    Letzter Beitrag: 26.09.2009, 16:39
  3. Inline Assembler für Anfänger
    Von 1udo1 im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 25.10.2007, 19:53
  4. Inline Assembler - Register
    Von s.o. im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 02.08.2007, 20:26
  5. Parameterübergabe bei Inline-Assembler
    Von ogni42 im Forum C - Programmierung (GCC u.a.)
    Antworten: 21
    Letzter Beitrag: 30.03.2006, 13:32

Berechtigungen

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

LiFePO4 Speicher Test