Ok
Aber jetzt ist meine Frage noch offen?!
Ich frage Channel nach >= 1 und < 6 ab. Wenns in dem Bereich ist, dann lese ich die Timer0 Variable WIE ein?
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!?Code:LSL r24 ' * 2 (wordlength) CLR r25 ' clear (r24 kann ja nicht grösser als 8 werden) Loadadr Dummy , X ' addr Empf(0) ADD XL, r24 ' addr Empf + 2*channel ADC XH, r25 !IN r24, TCNT0 ' timer0 ST X+ , r24 ' empf(channel) = timer0 ST X , r25
Muss ich außer den normal verwendeten Registern und SREG sonst noch was sichern? Warum muss ich überhaupt SREG sichern?
Gruß
Chris
So:
Code:!IN r24, TCNT0 ' timer0Warum brauchst Du ein Wordarray, wenn Du nur einen 8Bit-Timer hast ? Werden da noch Rechnungen im Array durchgeführt ?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!?
Weil das SREG Statusflags enthält, die z.B. von INC oder CPI verändert werden.Warum muss ich überhaupt SREG sichern?
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
Hier sind die Berechnungen im Code:
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?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
Gruß
Chris
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 ')Ich sehe nicht ohne Weiteres, wie groß die werden kann.die Variable Meanrx in Empf geschrieben wird
Diese Zugriffe dürften übrigens recht "teuer" sein in Bezug auf die Ausführungszyklen:
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.Code:If Empf(throttlechannel) > 61 And Empf(throttlechannel) < 139 Then 'don't process values that can't be correct Sempf(throttlechannel) = Empf(throttlechannel) - 61
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.
Lesezeichen