Werbung
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:
Also 635 im Vergleich zu 1439 ist doch schon etwasCode:'( 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 ')![]()
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?!
Stimmt das soweit oder fällt dir etwas auf?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
Geändert von Che Guevara (25.12.2011 um 00:06 Uhr)
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![]()
Hast Du Dir das auch im Disassembler auch mal angesehen ?
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.Fällt dir sonst noch ein BASCOM-typischer Taktfresser ein, den ich vermeiden könnte?
In der Zwischenzeit viel Spaß beim Kürzen und vor allem nicht zuviel auf einmal![]()
Ludwig
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
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:
f. programme bitte "CODE"-Tags verwenden (QUoTE ist für Zitate)PicNick ModCode:Timer1 = Servo(kanal)
Gruß
Andreas
Geändert von PicNick (31.01.2012 um 12:40 Uhr)
Lesezeichen