-
        

Ergebnis 1 bis 8 von 8

Thema: swstack, hwstack // getadc

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    24.01.2006
    Ort
    Kirchdorf a. Inn
    Alter
    46
    Beiträge
    81

    swstack, hwstack // getadc

    Anzeige

    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

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    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"
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    24.01.2006
    Ort
    Kirchdorf a. Inn
    Alter
    46
    Beiträge
    81
    @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.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.03.2004
    Beiträge
    185
    @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)

  5. #5
    Administrator Robotik Einstein Avatar von Frank
    Registriert seit
    30.10.2003
    Beiträge
    4.990
    Blog-Einträge
    1
    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:
    http://www.roboternetz.de/wissen/ind...ips_und_Tricks

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.03.2004
    Beiträge
    185
    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:
    Code:
      _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).

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    24.01.2006
    Ort
    Kirchdorf a. Inn
    Alter
    46
    Beiträge
    81
    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?

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Bei "Free" startet er nach jedem ADC gleich nochmal (den gleichen Kanal).
    Jetzt willst du aber den Kanal wechseln, hast also nix davon.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •