- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 6 von 6

Thema: Variable in Funktion übergeben!?

  1. #1
    Moderator Roboter Genie
    Registriert seit
    26.08.2004
    Beiträge
    1.228

    Variable in Funktion übergeben!?

    Anzeige

    E-Bike
    Hallo!
    Ich hab da ein kleines Problem mit einer Function. Ich möchte, je nach dem was über die SPI-Schnittstelle angekommen ist, einen ADC auslesen.
    Da ich 3 Werte des ADC auslesen möchte und einen Mittelwert daraus berechnen will, hab ich mir gedacht das ich dafür eine Funktion benutze (hab ich bisher noch nie gemacht).
    In der Simulation klappt das aber nicht so recht, hier mal ein paar Code-Fetzen:

    Code:
    Declare Function Adcx(byval Adcnummer As Byte) As Byte
    .
    .
    Adcsr = &B10000101 'ADC konfigurieren
    .
    .
    Select Case A 'Je nachdem was über SPI gekommen ist...
       Case 0 : C = Adcx(32) 
       Case 1 : C = Adcx(&B00100001)
    End Select
    .
    .
    Function Adcx(byval Adcnummer As Byte) As Byte
    
    Local B0 As Byte , B1 As Byte , B2 As Byte , B3 As Byte , B4 As Byte
    Local X0 As Byte
    
       Admux = Adcnummer
       X0 = 0
    
       For B4 = 0 To 2
    
       Adcsr.adsc = 1
    
       While Adcsr.adif = 0
       Wend
    
       Select Case B4
          Case 0 : B1 = Adch
          Case 1 : B2 = Adch
          Case 2 : B3 = Adch
       End Select
    
       Next
    
       B0 = B1 + B2
       B0 = B0 + B3
       B0 = B0 / 3
    
       Adcx = B0
    
    
    End Function
    Laut dem Simulator von Bascom wird anstatt der Zahl "32" nur "186" übergeben, und das Bit im Register Adcsr.adsc (also ADC Starten) wird auch nicht gesetzt.
    In folge dessen kommt das Programm auch nicht mehr aus der While...Wend Schleife (wenn der ADC nicht läuft kann das Flat Adif auch nicht gesetzt werden).
    Kann ich überhaupt Zahlen in eine Function übergeben und dort Register ändern?

    MfG
    Basti

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Du wirst setzen müssen

    $SWSTACK = 64 '(schätzwert)
    $FRAMESIZE = 24 '(schätzwert)

    Mit den defaultwerten kommst du da nicht durch


    EDIT: wenn du auch noch Interrupts verwenden willst:
    $HWSTACK = 64 '(schätzwert)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Moderator Roboter Genie
    Registriert seit
    26.08.2004
    Beiträge
    1.228
    Danke, funktioniert...nur sind die 128Byte SRAM (ATTiny26) nicht genug für so viele Variablen.
    Muss wohl ein wenig improvisieren...

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Mach aus deinen "LOCAL" "DIM" , das spart mächtig Platz
    Aber jetzt weißt du, worum's geht. Das kriegst du schon hin
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2004
    Ort
    Hard, Vorarlberg
    Beiträge
    155
    Bei den begrenzten SRAM-Möglichkeiten des ATTiny26 würde ich auf die Verwendung von Functions mit byval Parameter-Übergabe und einigen internen Variablen verzichten und anstatt dessen mit einem GOSUB - RETURN Konstrukt arbeiten.

    Bei der Durchsicht Deines Programmes sind mir einige Dinge aufgefallen:

    Warum verwendest Du nicht die BASCOM-Funktion GETADC(channel)?

    Du stellst den ADC auf linksbündige Ausgabe und verwendest nur das High-Byte der Ausgabe und machst aus einem 10Bit AD-Wandler einen 8-Bit AD-Wandler und verschenkst damit 2 Bit der Auflösung?

    Das High-Byte der linksbündigen ADC Ausgabe kann den höchsten Wert 255 haben. Du zählst 3 solcher Ausgaben in einer Byte Variablen zusammen um daraus einen Mittelwert zu bilden. Sofern die Summe aller 3 Ausgaben größer als 255 wird, hast Du einen Overflow und damit ein falsches Ergebnis?

    Wenn Du zur Mittelwertbildung für die Sample-Anzahl eine 2-Potenz Zahl nimmst wie 2, 4, 8, .... kannst Du die Division durch eine Shift rechts Operation ersetzen. Shift Right,1 ist dividiert durch 2, Shift Right,2 ist dividiert durch 4, Shift Right, 3 ist dividiert durch 8 usw.
    Eine Shift-Operation ist nicht nur wesentlich schneller als eine Division sondern braucht auch weniger Programm-Speicher.

    Schau Dir mal folgender Code an (nicht auf Hardware getestet)

    Code:
    Config Adc = Single , Prescaler = Auto
    
    Start Adc
    
    
    Dim ADCNum as Byte
    Dim wADCWert as Word
    Dim bADCWert as Byte
    Dim bCounter as Byte
    
    ADCNum = 0     ' Kanal setzen
    
    
    Gosub HoleADC
    
    ' End
    
    
    
    HoleADC:
    wADCWert = 0
    ' 4 AD-Werte einlesen und Mittelwert bilden
    For bCounter = 1 to 4
    wADCWert = wADCWert + getADC(ADCNum)
    next
    
    ' Hier könnte man wADCWert als Pseudo-12Bit-Wandlung verwenden
    ' RETURN
    
    
    ' oder in einen 10Bit Wert umwandeln (Mittelwert bilden)
    ' Shift wADCWert, Right, 2
    ' Return
    
    
    ' oder wenn es ein Byte-Wert sein muss (8Bit)
    
    Shift wADCWert, Right, 4
    bADCWert = wADCWert
    
    RETURN
    Viele Grüße
    Josef
    -------------------------------------------------------------------------------------
    DOS-File System für BASCOM-AVR auf http://members.aon.at/voegel

  6. #6
    Moderator Roboter Genie
    Registriert seit
    26.08.2004
    Beiträge
    1.228
    Hallo!
    Also, die GetADC Funktion verwende ich nicht, weil bei einem Testlauf das ganze nicht funktioniert hat (mit der manuellen Eingabe tut's aber, die SPI-Befehle funktionieren auf meinem Tiny26 auch nicht).
    Die 2 Bit verschenke ich, weil das ganze sowieso um 4-5 LSB rauscht (was aber an der aktuellen Betriebsweise über nen 100Ohm "Sicherheitswiderstand" liegt) und das Übertragungsprotokoll über SPI einfacher ist.
    Das mit dem Byte/Word fehler hab ich auch bemerkt und muss ich noch ändern.

    Das mit dem Shift Right wusste ich noch nicht, muss ich mal ausprobieren (hab aber beim Testen meinen Tiny gegrillt)

Berechtigungen

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

12V Akku bauen