PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : swstack, hwstack // getadc



wassermann
14.07.2006, 06:02
Hallo zusammen,

ich hätte folgende zwei Anliegen.

1. Kann mir jemand auf sinnvolle, verständliche Weise erklären, wie man die Werte für swstack, hwstack und framesize einstellt. Ich kenn die Hilfe, hab im Wiki nachgelesen ... bin aber noch nicht zufrieden. Ich hab (noch) keine Funktionen drin, noch irgendwas grossartiges (Mega8 mit knapp 8MHz), das einzige ist eine Interruptroutine mit 0,4ms und ein paar Arrays. Es reichten die üblichen 32, 10, 40 (und die Verzweiflung bei mir selbst) nicht aus.

2. Warum sind die Werte in Arrue und Arrie gleich (ist nur Auszug aus Programm)? Und da die Werte gleich sind, sollte hier der Fehler liegen.
Der ADC ist auf ständige Wandlung eingestellt. Stört euch nicht an den Namen der Variablen.

'----------------------
'Interrupt Routines
'----------------------
Tim0_isr:

If Countarrue <= 50 Then
W0 = Getadc(channel0)
Arrue(countarrue) = W0
W1 = Getadc(channel1)
Arrie(countarrue) = W1

Countarrue = Countarrue + 1
End If


Load Timer0 , Reload
Return

PicNick
14.07.2006, 06:52
1 Da haben viele einen "Block". Mal sehen, vielleicht kann ich das anders formulieren.

2

..ständige Wandlung ..
Probier' mal "single"

Ps: 50-er Schleifen in einer ISR sind eigentlich "Pfui"

wassermann
14.07.2006, 08:47
@PicNick
1. Was meinst du mit Block?
2. Probier ich mal aus.
Die Schleife ist deshalb drin, weil ich bei vollem Array dieses auswerte und bei best. Anforderungen zum PC schicke. Deshalb möchte ich nicht, dass mir während der Auswertung, aus welchem Grund auch immer, ein Interrupt das Array bereits neu beschreibt.
Ich werd mal versuchen, den Interrupt zu sperren/freizugeben, wenn ich die Auswertung mache. Ist sicherlich eine schönere Lösung. Danke.

-tomas-
14.07.2006, 10:07
@wassermann
unser Guru PicNick hat hier etwas kryptisch geantwortet...

zum Stack:
Ich habe gute Erfahrungen mit dem Bascom Befehl $DBG und DBG gemacht. Lies mal dazu im Handbuch nach (und auch mal STCHECK)...

Ansonsten kannst Du den Bedarf an Stack selber abschätzen.
Dazu steht im Handbuch:


HW STACK
Most statements need HW stack too.
An interrupt needs 32 bytes!!!!!!
When you use GOSUB or CALL, you are using 2 bytes of HW stack space.
When you nest 2 GOSUB’s you are using 4 bytes (2*2).


SOFT STACK
When you use a LOCAL variable inside a SUB or function. Each local variable will use 2 bytes.
Each variable that is passed to a sub program uses 2 bytes too. So when you have used 10 locals in a SUB and the SUB passes 3 parameters, you need 13 * 2 = 26 bytes.
This space is freed when the routine ends.
But when you call another sub inside the sub, you need more space.


FRAME SPACE
Each local is stored in a space that is named the frame space.
When you have 2 local integers and a string with a length of 10, you
need a frame size of (2*2) + 11 = 15 bytes.

The internal conversion routines used when you use INPUT
num,STR(),VAL() etc, also use the frame. They need a maximum of 16
bytes. So for this example 15+16 = 31 would be a good value.

When ever you use a num<>string conversion routine like:
Print b (where b is a variable)
Bytes will use 4 bytes max (123+0)
Integer will use 7 bytes max (-12345+0)c
Longs will use 16 bytes max
And the single will use 24 bytes max

When you add strings and use the original the value must be remembered by the compiler.
Consider this :
s$ = "abcd" + s$
Here you give s$ a new value. But you append the original value so the original value must
be remembered until the operation has completed. This copy is stored in the frame too.
So when string s$ was dimmed with a length of 20, you need a frame space of 20+1(null
byte)
When you pass a variable by VALUE (BYVAL) then you actually pass a copy of the variable.
When you pass a byte, 1 byte of frame space is used, a long will take 4 bytes.
When you use a LOCAL LONG, you also need 4 bytes of frame space to store the local long.

Meine Tipps für kurzen Bascom-Code mit geringem Stackbedarf:
Beachte die 32Byte SW-Stack in ISR.
Vermeide LOCAL Variable
Vermeide SUB mit Parameterübergabe
Vermeide Bit-Variable
Vermeide a>b, verwende a>=c oder b<a (RISC-Prozessor kennt kein größer als)
Vermeide Single/Long etc. und dazugehörige Matheoperationen (am besten nur Byte und Word)

Frank
14.07.2006, 13:01
Hi -tomas-

du hast da ein paar Bascom Tips so schön kompakt zusammengeschrieben. Ich hoffe du hast nix dagegen das ich es so unverändert ins Wiki übernommen habe. Da ist es an zentraler Stelle noch wertvoller und kann imme rnoch von jederman ergänzt werden.

siehe:
https://www.roboternetz.de/wissen/index.php/Bascom#Tips_und_Tricks

-tomas-
14.07.2006, 18:40
gute Idee, aber ich vergaß Rechenoperationen mit Arrays und und und... :-)

Ich sitze gerade daran, den Butterfly-AVR-Sample-Code von GCC nach Bascom zu übertragen. Schon der C-Code belegt 98% des ROM. Deshalb muss ich jeden Bascom-Schritt im Assembler-Code nachprüfen.
Ich kann ein Lied darüber singen, an welchen Stellen Bascom hemmungslos ROM frisst...
Das Hauptproblem ist das völlige Fehlen der Nutzung von Registern als Zwischenspeicher. Jede Variable wird beim nächsten mal wieder aus dem RAM nachgeladen. Und wenn es ein Array-Wert ist, dann steigt der Aufwand zusätzlich.
Tja und wenn man jetzt denkt, mit internen Variablen wie _temp1 (R24) und _temp2 (R25) könnte man den Compiler austricksen, der irrt...

hier ein Beispiel für _b2 = R21, indem Bascom sogar sein Register R21 nachlädt - na wenn das nicht konsequent ist:

_b2 = 12
0042: E05C LDI R21,0x0C Load immediate

If _b2 >= 10 Then Incr _b2
0043: 27BB CLR R27 Clear Register
0044: E1A5 LDI R26,0x15 Load immediate
0045: 910C LD R16,X Load indirect Register R21 -> R16
0046: E04A LDI R20,0x0A Load immediate
0047: 1704 CP R16,R20 Compare
0048: F410 BRCC PC+0x03 Branch if carry cleared
0049: 940C004C JMP 0x0000004C Jump
004B: 9553 INC R21 Increment



Bascom nutzt leider die Fähigkeiten der RISC-CPU mit den 32 Registern nicht aus (und kennt auch kein RJMP).

wassermann
18.07.2006, 06:01
Hallo zusammen,

danke für die Hilfe bei den Stacks.

Single Mode hilft (so wie's auch in der Hilfe steht).
Doch warum ging's dann mit einem Kanal auch im Free Running Mode?
Geht Free nur mit einem Kanal?

PicNick
18.07.2006, 07:33
Bei "Free" startet er nach jedem ADC gleich nochmal (den gleichen Kanal).
Jetzt willst du aber den Kanal wechseln, hast also nix davon.