- 12V Akku mit 280 Ah bauen         
Seite 6 von 7 ErsteErste ... 4567 LetzteLetzte
Ergebnis 51 bis 60 von 65

Thema: Bascom Inline-Assembler

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

    Powerstation Test
    Oh, na klar! Du hast es ja vorher schon geschrieben...

    Werde jetzt mal das Programm durchforsten und mal schauen, wo noch was zu machen ist. Melde mich dann wieder.

    Gruß
    Chris

    EDIT:
    Hab jetzt mal den Noise-Filter durch den Simulator gejagt. Herausgekommen ist folgendes:
    Code:
    '(  1439
    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
      End If
    Next
    ')
    
    '(  635
    Meanrx(1) = Meanrx(1) * 3
    Meanrx(1) = Meanrx(1) + Empf(1)
    Shift Meanrx(1) , Right , 2
    Aempfh(1) = Meanrx(1) + 17
    Aempfl(1) = Meanrx(1) - 17
    If Empf(1) > Aempfh(1) Or Empf(1) < Aempfl(1) Then
       Empf(1) = Meanrx(1)
    End If
    
    Meanrx(2) = Meanrx(2) * 3
    Meanrx(2) = Meanrx(2) + Empf(2)
    Shift Meanrx(2) , Right , 2
    Aempfh(2) = Meanrx(2) + 17
    Aempfl(2) = Meanrx(2) - 17
    If Empf(2) > Aempfh(2) Or Empf(2) < Aempfl(2) Then
       Empf(2) = Meanrx(2)
    End If
    
    Meanrx(3) = Meanrx(3) * 3
    Meanrx(3) = Meanrx(3) + Empf(3)
    Shift Meanrx(3) , Right , 2
    Aempfh(3) = Meanrx(3) + 17
    Aempfl(3) = Meanrx(3) - 17
    If Empf(3) > Aempfh(3) Or Empf(3) < Aempfl(3) Then
       Empf(3) = Meanrx(3)
    End If
    
    Meanrx(4) = Meanrx(4) * 3
    Meanrx(4) = Meanrx(4) + Empf(4)
    Shift Meanrx(4) , Right , 2
    Aempfh(4) = Meanrx(4) + 17
    Aempfl(4) = Meanrx(4) - 17
    If Empf(4) > Aempfh(4) Or Empf(4) < Aempfl(4) Then
       Empf(4) = Meanrx(4)
    End If
    
    Meanrx(5) = Meanrx(5) * 3
    Meanrx(5) = Meanrx(5) + Empf(5)
    Shift Meanrx(5) , Right , 2
    Aempfh(5) = Meanrx(5) + 17
    Aempfl(5) = Meanrx(5) - 17
    If Empf(5) > Aempfh(5) Or Empf(5) < Aempfl(5) Then
       Empf(5) = Meanrx(5)
    End If
    ')
    Also 635 im Vergleich zu 1439 ist doch schon etwas
    Vielen Dank für den Tipp!

    Gruß
    Chris

    EDIT:
    Mit den Tmpx-Overlay Variablen von Empf(x) kann man ja, wenn ich jetzt keinen Mist erzähle, die ISR nochmal verkürzen?!
    Code:
    'in range: 33
    'out of range: 34
    
    !PUSH    R16
    !IN      R16,       SREG
    !PUSH    R16
    !PUSH    R18
    
    !in r18, tcnt0
    !lds r16, {channel}
    !cpi r16, 1
    !breq channel1
    !cpi r16, 2
    !breq channel2
    !cpi r16, 3
    !breq channel3
    !cpi r16, 4
    !breq channel4
    !cpi r16, 5
    !breq channel5
    !rjmp outofrange
    Channel1:
    !sts {tmp1}, r18
    !rjmp outofrange
    Channel2:
    !sts {tmp2}, r18
    !rjmp outofrange
    Channel3:
    !sts {tmp3}, r18
    !rjmp outofrange
    Channel4:
    !sts {tmp4}, r18
    !rjmp outofrange
    Channel5:
    !sts {tmp5}, r18
    Outofrange:
    !inc r16
    !sts {channel}, r16
    !LDI     R16,       6
    !OUT     TCNT0,     R16
    
    !POP     R18
    !POP     R16
    !OUT     SREG,      R16
    !POP     R16
    Stimmt das soweit oder fällt dir etwas auf?
    Geändert von Che Guevara (25.12.2011 um 00:06 Uhr)

  2. #52
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Mit den Tmpx-Overlay Variablen von Empf(x) kann man ja, wenn ich jetzt keinen Mist erzähle, die ISR nochmal verkürzen?!
    Das was Du machst, nennt sich Code-Unrolling, hilft Dir hier aber nicht viel.

    Ich messe so, dass ich 'nen Haltepunkt auf die Gosub und dann auf dem Gosub nächsten Befehl setze, vorher die Zyklen auf 0 setze und dann beim zweiten Haltepunkt ablese, da kommt bei Deinem ungerollten Code raus:
    41, 36, 38, 40, 42, 42 Takte
    Bei einem out of range und 5 in range sind das Gesamt 239, mein letzter Code war 43 x 5 + 28 = 243. Viel hast Du nicht gewonnen, außer Erfahrung

  3. #53
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hm, ok... Aber Erfahrung ist ja auch sehr viel Wert!
    Und meinen Code verstehe ich wenigstens zu 100%.

    Ich werde jetzt noch alle > durch >= austauschen, das bringt auch noch ein paar Takte
    Fällt dir sonst noch ein BASCOM-typischer Taktfresser ein, den ich vermeiden könnte?

    Gruß
    Chris

  4. #54
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Ich werde jetzt noch alle > durch >= austauschen, das bringt auch noch ein paar Takte
    Hast Du Dir das auch im Disassembler auch mal angesehen ?
    Fällt dir sonst noch ein BASCOM-typischer Taktfresser ein, den ich vermeiden könnte?
    Berechnungen in Schleifen, Multiplikationen, Divisionen. Wenn ich 'nen Blick auf den gesamten Code werfen würde, könnt' ich vielleicht noch etwas sehen. Aber heut nicht mehr, wird jetzt Zeit Schluss zu machen, hab' morgen Einiges zu erledigen.
    In der Zwischenzeit viel Spaß beim Kürzen und vor allem nicht zuviel auf einmal

    Ludwig

  5. #55
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hm nein, habe ich nicht. Aber ich weiß, dass es keinen ASM Befehl für > gibt, nur für >=. Somit sollte doch auch in Bascom ein >= kürzer sein, oder nicht? Ich werds mir mal disassembliert ansehen...

    Berechnungen in Schleifen gibts keine mehr, die einzige war glaube ich der Noise-Filter. Multiplikationen gibts schon einige, die meisten mit Single Variablen. Das ist zu hoch für mich.
    Divisionen sind fast alle durch die Singles vermieden, lediglich ein paar Integer / Word Divisionen gibt es. Aber es sind nicht sehr viele.

    Ja, ist e schon relativ spät. Vielen Dank schonmal für all deine Bemühungen

    Gruß
    Chris

  6. #56
    Neuer Benutzer Öfters hier
    Registriert seit
    13.02.2010
    Beiträge
    5
    Hallo,

    Ich klinke mich mal hier ein,da ich ein ähnliches Problem habe,und hier auf ähnliche Lösungen gestoßen bin ...
    Ich will eine Art Servomischer bauen mit größtmöglicher Auflösung,und dann die Servosignale parallel wieder ausgeben. Mit 8 Mhz habe ich jetzt zum einlesen 140 Schritte und zum ausgeben 1000. Timer0 zum einlesen,Timer1 für die Ausgabe.

    Code:
    '======================================================
    'System-Einstellungen
    '======================================================
    $regfile "m8def.dat"
    $crystal = 8000000
    $framesize = 64
    $swstack = 64
    $hwstack = 64
    $baud = 57600
    
    '======================================================
    'Konfigurationen
    '======================================================
    
    Config Timer1 = Timer , Prescale = 8
    Config Timer0 = Timer , Prescale = 64
    Config Int0 = Falling
    
    Config Portb = Output
    Config Portc.0 = Output
    Config Portd.4 = Output
    Config Portd.5 = Output
    Config Portd.6 = Output
    Config Portd.7 = Output
    Rc_kanal1 Alias Portd.4
    Rc_kanal2 Alias Portb.6
    Rc_kanal3 Alias Portb.7
    Rc_kanal4 Alias Portd.5
    Rc_kanal5 Alias Portd.6
    Rc_kanal6 Alias Portd.7
    Rc_kanal7 Alias Portb.0
    
    
    
    Dim Servo(10) As Word
    Dim Empf(10) As Byte
    Dim Empf_mw(10) As Byte
    Dim Meanrx(10) As Word
    Dim Kanal As Byte
    Dim Channel As Byte
    
    
    Dim Kanal1 As Integer
    Dim Kanal2 As Word
    Dim Kanal3 As Word
    Dim Kanal4 As Word
    Dim Kanal5 As Word
    Dim Kanal6 As Word
    Dim Kanal7 As Word
    
    Dim X As Word
    Dim R As Word
    Dim N As Byte
    Dim I As Byte
    
    '-------------------------------------------------------------------------------
    Enable Interrupts
    Timer1 = 63000
    
    Enable Timer0
    Enable Timer1
    Enable Int0
    Start Timer0
    Start Timer1
    
    On Timer1 Rc
    On Timer0 Sync Nosave
    On Int0 Messen Nosave
    '-------------------------------------------------------------------------------
    
    Do
    
    
    
    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)
    Empf_mw(i) = Meanrx(i)
    Next
    
    
    
    Kanal1 = Empf_mw(1) - 100
    Kanal1 = Kanal1 * 7
    
    Servo(1) = 64000 + Kanal1
    Servo(2) = 63500 + X
    Servo(3) = 64500
    Servo(4) = 64100
    
    
    Waitms 10
    
    
    
    If X = 1000 Then R = 1
    If X = 0 Then R = 0
    
    If R = 1 Then X = X - 5 Else X = X + 5
    
    '(
    
    Print Empf(1) ; " CH1"
    Print Empf(2) ; " CH2"
    Print Empf(3) ; " CH3"
    Print Empf(4) ; " CH4"
    Print Empf(5) ; " CH5"
    Print Empf(6) ; " CH6"
    Print " "
    Waitms 100
    ')
    
    
    Loop
    
    End
    
    
    Messen: 'Timer0 läuft bei jedem Kanal über (Preload 150)
    !PUSH R16
    !IN R16, SREG 'Dadurch höhere Auflösung (100+-70 Schritte -> 140)
    !PUSH R16
    !LDS R16, {channel}
    !INC R16
    !STS {channel}, R16
    !SUBI R16, 2
    !CPI R16, 8
    !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, 0
    !sts {N},r16
    !LDI R16, 150
    !OUT TCNT0, R16
    !POP R16
    !OUT SREG, R16
    !POP R16
    '( So sieht der asm Teil in Basccom aus
    If Channel > 0 And Channel < 8 Then
    Empf(channel) = Timer0
    End If
    
    Timer0 = 150
    Incr Channel
    N = 0
    ')
    
    Return
    
    Sync: 'Synchronimpuls Auswertung
    Push r24
    in r24,sreg
    push r24
    lds r24,{N}
    inc r24
    cpi r24,2 'wennkleiner 2 ist
    BRLO no_sync
    Channel = 0
    No_sync:
    sts {N},r24
    pop r24
    !out sreg,r24
    pop r24
    Return
    
    
    Rc: 'Servosignalausgabe
    
    Incr Kanal
    
    Rc_kanal1 = 0
    Rc_kanal2 = 0
    Rc_kanal3 = 0
    Rc_kanal4 = 0
    
    Timer1 = Servo(kanal)
    
    Select Case Kanal
    Case 1 : Rc_kanal1 = 1
    Case 2 : Rc_kanal2 = 1
    Case 3 : Rc_kanal3 = 1
    Case 4 : Rc_kanal4 = 1
    Case 5 : Timer1 = 50000
    Kanal = 0
    End Select
    
    Return

    So. Und das alles funktioniert dank Inline asm fast Jitterfrei. Jetzt würde ich aber gerne die Servoausgabe auch in asm schreiben - in der Hoffnung das dann die sporadischen Zucker (alle 3-5s) weg sind.

    Code:
    Rc: 'Servosignalausgabe
    
    Incr Kanal
    
    Rc_kanal1 = 0
    Rc_kanal2 = 0
    Rc_kanal3 = 0
    Rc_kanal4 = 0
    
    Timer1 = Servo(kanal)
    
    Select Case Kanal
    Case 1 : Rc_kanal1 = 1
    Case 2 : Rc_kanal2 = 1
    Case 3 : Rc_kanal3 = 1
    Case 4 : Rc_kanal4 = 1
    Case 5 : Timer1 = 50000
    Kanal = 0
    End Select
    
    Return

    Ich habe auch schon eine Idee und würde das mit meinen begrenzten asm Kenntnissen auch irgendwie hinbekommen,nur habe ich bei der Übersetzung folgender Zeile Probleme (Word Array) und weiß nicht wie ich vorgehen soll:


    Code:
    Timer1 = Servo(kanal)
    f. programme bitte "CODE"-Tags verwenden (QUoTE ist für Zitate)PicNick Mod


    Gruß

    Andreas
    Geändert von PicNick (31.01.2012 um 12:40 Uhr)

  7. #57
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    ...,nur habe ich bei der Übersetzung folgender Zeile Probleme (Word Array) und weiß nicht wie ich vorgehen soll:
    Code:
    Timer1 = Servo(kanal)
    Wenn Du Assembler programmierst und den Thread auch durchgelesen hast (wobei's bereits auf der ersten Seite steht), dann sollte sich die Frage gar nicht mehr stellen.

  8. #58
    Neuer Benutzer Öfters hier
    Registriert seit
    13.02.2010
    Beiträge
    5
    Hallo,

    Entschuldige,ich habe den Thread zwar gelesen,aber die Cdes am Anfang nur überflogen. Mit begrenzten asm Kenntnissen meinte ich wirklich begrenzt Also 2 Byte Variablen bekomm ich verglichen und ich kann auch dann entsprechend wohin springen...



    Code:
    !PUSH ZL
    !PUSH ZH
    Loadadr Servo(1) , z    
    !LDS   R18,   {Kanal}
    !LDS   R19,   {Kanal+1}
    !SBIW  ZL,    1                   'Kanal fängt bei 1 an
    !ADD   ZL,    R18
    !ADC   ZH,    R19
    !LD    R16,   Z
    !STS   {Rslt},R16
    !OUT     TCNT1L,     ZL
    !OUT     TCNT1H,     ZH
    Entspricht das ungefähr dem hier? Ich weiß leider nicht so genau in welchem Register dann was und wie reingeladen wird,und wie ich es an den Timer1 übergebe...
    Code:
    Timer1 = Servo(kanal)
    Gruß

    Andreas

  9. #59
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Schau,
    Code:
    !OUT     TCNT1L,     ZL     ' das ist TImer1 (LSB)
    !OUT     TCNT1H,     ZH    ' das ist Timer1 (MSB)
    Wenn du die ganze ISR mit assembler ersetzen willst, darfst du das Sichern und Wiederherstellen aller verwendeten Register (+ SREG) aber nicht vergessen
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  10. #60
    Neuer Benutzer Öfters hier
    Registriert seit
    13.02.2010
    Beiträge
    5
    Hallo und Danke,

    Das mit dem Sichern und Wiederherstellen ist klar.Also sehe ich es richtig, dass der Asm-Teil in meinem letzten Post stimmt und so auch der Wert vom Array in den Timer geladen wird?

    Als Ergänzung : Servo(10) ist ein Word-Array , Kanal wird nicht größer als 10 (Byte)

    Gruß

Seite 6 von 7 ErsteErste ... 4567 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