- LiFePO4 Speicher Test         
Ergebnis 1 bis 7 von 7

Thema: [gelöst] Variable löscht sich nach Interrupt?

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    28.05.2007
    Ort
    Mannheim
    Alter
    37
    Beiträge
    270

    [gelöst] Variable löscht sich nach Interrupt?

    Anzeige

    Powerstation Test
    Hallo Leute,

    ich habe ein Problem in meinem Quellcode.
    Zunächst mal mein Code in gekürzter Form:
    Code:
    $regfile = "m8def.dat"
    $crystal = 4000000
    
    Ddrb = &B00111100
    Ddrc = &B00001110
    Ddrd = &B10000001
    Portb = &B00000000
    Portc = &B00000000
    Portd = &B00001000
    
    Eingang Alias Pind.3
    Code_hoch Alias "0111011110"
    Code_rechts Alias "1011101101"
    Code_links Alias "0011011110"
    Code_runter Alias "1011001101"
    Code_enter Alias "0111101101"
    Code_frechts Alias "1011011110"
    Code_flinks Alias "0011101100"
    Error_led Alias Portd.7
    
    Dim Statusbit As Byte
    'Bits im Statusbyte:
      Faceauf Alias 0
      Get_data Alias 1
      Menue Alias 2
    
    On Int1 Ir_dataempfang
    
    Enable Int1
    Enable Interrupts
    
    Hauptschleife:
    Do
    
    Loop
    
    Ir_dataempfang:
    'Dieser Teil ist für euch unbedeutend-----
    Set Error_led
    For A = 0 To 71
    Temp(a) = Eingang
    Waitus 902
    Next A
    
    Code = ""
    For A = 49 To 58
    Tmp = Temp(a)
    Code = Code + Str(tmp)
    Next A
    
    '-------------------------------------------
    
    If Code = Code_rechts Then
      If Statusbit.menue = 1 Then
        Menue_cnt = Menue_cnt + 1
        Locate 2 , 1
        If Menue_cnt > 4 Then Menue_cnt = 1
        If Menue_cnt < 1 Then Menue_cnt = 4
    
        If Menue_cnt = 1 Then Lcd "Fahr alleine rum"
        If Menue_cnt = 2 Then Lcd " manuell fahren "
        If Menue_cnt = 3 Then Lcd " Raumtemperatur "
        If Menue_cnt = 4 Then Lcd " Akku Spannung  "
      End If
    End If
    
    If Code = Code_enter Then
      If Statusbit.menue = 0 Then
        Statusbit.menue = 1
        Cls
        Locate 1 , 4
        Lcd "Hauptmenõ"
        Locate 2 , 1
        Lcd "Fahr alleine rum"
        Menue_cnt = 1
      Else
        Cls
        Locate 1 , 2
        Lcd "Menõ verlassen"
        Statusbit.menue = 0
      End If
    End If
    
    Do
    'Warte bis Taste wieder losgelassen wurde
      A = A + 1
      If A > 125 Then
        Goto Losgelassen
      End If
      If Eingang = 0 Then A = 1
      Waitms 1
    Loop
    
    Losgelassen:
    Reset Error_led
    Return
    So, nun zu meinem Problem:
    Das öffnen und schließen des Menüs über die enter-Taste funktioniert einwandfrei.
    Nun habe ich aber ein Problem mit der rechts-Taste:
    Wenn diese betätigt wird springt er in die Entsprechende If-Schleife. Wenn er bei dem Befehl Menue_cnt = Menue_cnt + 1 ankommt ist diese Variable allerdings IMMER 0 und somit springt er an dieser Stelle immer auf 1. (was auf dem Display dann "Fahr alleine rum" entspricht.

    Hoffe irgendjemand versteht was ich meine....

    Irgendwie wird die Variable Menue_cnt nach meinen bisherigen Beobachtungen bei jedem Interrpt-Aufruf auf 0 gesetzt (Habe mir die Variable an verschiedenen Stellen auf dem Display mal anzeigen lassen. Nach auslösen der Interrupts über enter ist sie 1 und beim nächsten Interruptaufruf ist sie schon wieder 0). Woran liegt das?
    Kann sich das jemand erklären? Was kann man dagegen tun? Oder ist doch noch ein Fehler im Quellcode?

    tausend dank schonmal an diejenigen die sich die Mühe machen und versuchen mir zu helfen. Bin für jedne Tipp dankbar.

    Gruß Robodriver

    PS: Einstellungen:
    HW Stack = 64
    Soft Stack = 16
    Framesize = 32

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hallo robodriver,

    eine Interruptroutine sollte so kurz wie möglich sein. Das warten auf eine Taste darf auf keinen Fall in einer ISR stattfinden!
    Grund: Je nach deiner Timer-Frequenz (kenne ich ja nicht) wird die ISR nicht angesprungen, weil sie ja immer noch läuft. In der ISR solltest du nur z.B. den Eingang abfragen und ein Flag setzen. Das wird dann im Hauptprogramm verarbeitet.

    Gruß Dirk

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    28.05.2007
    Ort
    Mannheim
    Alter
    37
    Beiträge
    270
    Hm, okay.

    Dann mal die nächste frage hinterher:
    Da kommen noch einige Tasten mehr dazu. Also die Interruptroutine wird schätzungsweise nochmal um das 4 fache größer.

    Somit wäre es dann auf jeden Fall notwendig das ganze auszulagern.
    Das einlesen des Codes würde ich noch ganz gerne in der Interrupt-Routine machen.
    Aber wo soll ich denn am besten die Daten-Auswertung hin schreiben?
    Die Hauptschleife wird früher oder später auf jeden Fall noch um einiges voller und sehr umfangreich. evtl. werden es sogar 2 oder 3 Hauptschleifen die je nach Betriebsart durchlaufen werden.
    Wie soll ich da dann am günstigsten die Datenauswertung hin schreiben?

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    entweder in eine Subroutine (Sub)
    oder in eine Funktion (Function)
    Hat ausserdem den Vorteil, das Du an beliebigen
    Stellen Deines Programmablaufs dort hin und zurück springen
    kannst, also für Deine x Betriebsmodi beispielsweise
    nur einmal die Anzeigeroutine proggen musst anstatt
    x-mal
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    28.05.2007
    Ort
    Mannheim
    Alter
    37
    Beiträge
    270
    Hm,
    meinst du das so in etwa?:
    Code:
    $regfile = "m8def.dat" 
    $crystal = 4000000 
    
    Ddrb = &B00111100 
    Ddrc = &B00001110 
    Ddrd = &B10000001 
    Portb = &B00000000 
    Portc = &B00000000 
    Portd = &B00001000 
    
    Eingang Alias Pind.3 
    Code_hoch Alias "0111011110" 
    Code_rechts Alias "1011101101" 
    Code_links Alias "0011011110" 
    Code_runter Alias "1011001101" 
    Code_enter Alias "0111101101" 
    Code_frechts Alias "1011011110" 
    Code_flinks Alias "0011101100" 
    Error_led Alias Portd.7 
    
    Dim Statusbit As Byte 
    'Bits im Statusbyte: 
      Faceauf Alias 0 
      Get_data Alias 1 
      Menue Alias 2 
    
    On Int1 Ir_dataempfang 
    
    Enable Int1 
    Enable Interrupts 
    
    Hauptschleife: 
    Do 
    
    Loop 
    
    Ir_dataempfang: 
    'Dieser Teil ist für euch unbedeutend----- 
    Set Error_led 
    For A = 0 To 71 
    Temp(a) = Eingang 
    Waitus 902 
    Next A 
    
    Code = "" 
    For A = 49 To 58 
    Tmp = Temp(a) 
    Code = Code + Str(tmp) 
    Next A 
    
    '------------------------------------------- 
    
    gosub auswertung_code
    
    Do 
    'Warte bis Taste wieder losgelassen wurde 
      A = A + 1 
      If A > 125 Then 
        Goto Losgelassen 
      End If 
      If Eingang = 0 Then A = 1 
      Waitms 1 
    Loop 
    
    Losgelassen: 
    Reset Error_led 
    Return 
    
    'Ende Interruptroutine
    
    
    
    sub auswertung_code
    If Code = Code_rechts Then 
      If Statusbit.menue = 1 Then 
        Menue_cnt = Menue_cnt + 1 
        Locate 2 , 1 
        If Menue_cnt > 4 Then Menue_cnt = 1 
        If Menue_cnt < 1 Then Menue_cnt = 4 
    
        If Menue_cnt = 1 Then Lcd "Fahr alleine rum" 
        If Menue_cnt = 2 Then Lcd " manuell fahren " 
        If Menue_cnt = 3 Then Lcd " Raumtemperatur " 
        If Menue_cnt = 4 Then Lcd " Akku Spannung  " 
      End If 
    End If 
    
    If Code = Code_enter Then 
      If Statusbit.menue = 0 Then 
        Statusbit.menue = 1 
        Cls 
        Locate 1 , 4 
        Lcd "Hauptmenõ" 
        Locate 2 , 1 
        Lcd "Fahr alleine rum" 
        Menue_cnt = 1 
      Else 
        Cls 
        Locate 1 , 2 
        Lcd "Menõ verlassen" 
        Statusbit.menue = 0 
      End If 
    End If 
    return
    end sub
    Dann wird die Auswertung aber doch irgendwie immer noch innerhalb des Interrupts abgearbeitet oder ist das so ein Unterschied weil es im Sub steht?



    PS: generall verstehe ich aber immer noch nicht warum die Variable immer wieder auf Null gesetzt wird. Wo kommt der Befehl denn bloß her?
    Wenn ein Wert im Speicher einmal drinne steht dann steht er doch drinne. Wer Pfucht denn da dann am Speicher und macht aus der 1 wieder eine 0 ?

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    28.05.2007
    Ort
    Mannheim
    Alter
    37
    Beiträge
    270
    Hat denn keiner weiter eine Idee?

    Bin auch offen für neue komplett andere Source-Vorschläge.

    Das ganze ist für meinen Roboter die IR-Fernbedienungs-Fernsteuerung (tolles Wort )
    Folgende Anforderungen müssen erfüllt werden:
    - Sofortige Reaktion auf Tastenereignisse
    - Erfassung von "Key Down" --> Reaktion und "Key Up" --> Reaktion
    - Entscheidend sind die ersten Bits. Diese verraten welche Taste gedrückt wurde. Was danach kommt ist Datentechnisch egal. Key Up wird erkannt wenn eine bestimmte Zeit (etwa 125ms) keine Daten mehr angekommen sind.

    Eine bessere Lösung als alle Auswertungen ins Interrupt zu setzen ist mir noch nicht gekommen.

    PS: Ausgewertet werden müssen Später insgesammt 17 Verschiedene Tasten. Auf manche Tasten (hauptsächlich die Pfeiltasten) müssen je nach aktuellen Betrieszustand (Menü oder Auswahllisten oder Manuelle Steuerung) unterschiedliche Aktionen ausgeführt werden.

    Komm hier echt nicht mehr weiter

    Gruß Robodriver

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    28.05.2007
    Ort
    Mannheim
    Alter
    37
    Beiträge
    270
    Okay, nach seeeeehhhhr langer Suche und viel rum probieren bin ich darauf gestoßen, das sich die variable NICHT mehr zurück setzt wenn ich sie eine Zeile weiter oben deklariere.

    Dann habe ich mir das ganze mal genauer angesehen und den Fehler festgestellt:

    Code:
    Die Variable Temp ist folgender maßen declariert:
    Dim Temp(72)
    
    im code befülle ich den Array wie folgt:
    
    For A = 0 To 71 
    Temp(a) = Eingang 
    Waitus 902 
    Next A
    Und da steckt der fehler....
    Arrays beginnen bei Bascom nicht mit 0 sondern immer bei 1...
    (Das wusste ich nicht, hab es später erst in der Hilfe gelesen)

    Somit wird ein bestimmter Speicherbereich für temp freigehalten. Wenn ich aber auf temp(0) was schreibe, dann wandert dieser Wert eine Variable VOR den freigehaltenen Bereich und überschreibt mir somit jedes mal mein Menue_cnt mit einer 1....

    Ärgerlich, aber zum glück gefunden und beseitig

    Gruß Robodriver

Berechtigungen

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

12V Akku bauen