- Labornetzteil AliExpress         
Ergebnis 1 bis 10 von 65

Thema: Bascom Inline-Assembler

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    dann lese ich die Timer0 Variable WIE ein?
    So:
    Code:
       !IN    r24, TCNT0                                        ' timer0
    Funktioniert dann trotzdem, oder? Hier wird ja, soweit ich das verstanden habe, nur Channel nach links geschiftet, da Empf ein Word ist. Dann wird der entsprechende Empf-Feld-Bereich addresiert und Timer0 wird dort hineingeschrieben!?
    Warum brauchst Du ein Wordarray, wenn Du nur einen 8Bit-Timer hast ? Werden da noch Rechnungen im Array durchgeführt ?
    Warum muss ich überhaupt SREG sichern?
    Weil das SREG Statusflags enthält, die z.B. von INC oder CPI verändert werden.

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    Nein, ich meinte, wie ich die Variable dann ins Array schreibe? So, wie ich gerade eben nochmal gespostet habe?

    Ja, es werden noch Rechnungen durchgeführt und somit benötigt man ein Word. Ich habs e schon mal als Byte deklariert, aber das wollte dann nicht so recht. Deswegen ists ein Word.
    Ok, das verstehe ich.

    Gruß
    Chris

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Nein, ich meinte, wie ich die Variable dann ins Array schreibe? So, wie ich gerade eben nochmal gespostet habe?
    Ja.
    Ja, es werden noch Rechnungen durchgeführt und somit benötigt man ein Word. Ich habs e schon mal als Byte deklariert, aber das wollte dann nicht so recht. Deswegen ists ein Word.
    Werden die Rechnungen innerhalb der Arrayvariable durchgeführt oder in einer extra Variablen ?

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578
    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

  5. #5
    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.

  6. #6
    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

  7. #7
    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)

Ä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
  •  

Labornetzteil AliExpress