Atmega32 hängt sich auf bei Sprung in Subroutine

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Atmega32 hängt sich auf bei Sprung in Subroutine

      Guten Abend!

      Zur Zeit bastel ich an einer Uhr mit elektromechanischen 7-Segment Anzeigen (HH:MM). Zeit wird über DCF77 geholt. Und an sich lief mein Programm auch prima. Seit einiger Hab ich aber das Problem, dass der Controller einfach hängen bleibt. Das Programm wird einfach nicht weiter ausgeführt. Reset funktioniert dann auch nichtmehr. Spannung muss komplett abgeschaltet werden. Nach erneutem zuschalten der Spannungsversorgung geht es dann wieder bis der Fehler erneut auftritt. Und so wie ich das beobachten konnte, setzt der Hänger immer dann ein, wenn in eine der Subroutinen gesprungen wird. Ich nutze die Soubroutinen um die Ziffern auf den einzelnen Stellen zu setzen.

      Hier nochmal der Ablauf, wie der Fehler sich darstellt.

      -Spannungsversorgung wird eingeschaltet
      -Variable "_sec" ist zu beginn = 0 -> If-then Schleife wird aktiviert und Select-Case Abfragen werden abgearbeitet.
      -Variablen "_hour" und "_min" sind zu beginn auch noch = 0 -> Anzeige wird aktualisiert und zeigt "00:00". Da werden also die Subroutinen noch angesprungen und bearbeitet. Und somit werden auch alle Segmente korrekt gesetzt.
      -Nach einer Minute ist "_sec" wieder = 0. Zu diesem Zeitpunkt ist "_hour" noch = 0 und natürlich "_min" = 01
      -Es wird in die Subroutine gesprungen um die erste Stelle zu aktualisieren. In der ersten Stelle werden alle Segmente zurück gesetzt. Und dann Feierabend. Controller streikt.

      Die Subroutine wird also praktisch bis Zeile 39 oder 40 bearbeitet und dann streikt alles.

      Das komplette Programm habe ich in den Anhang verfrachtet. Es würde sonst die maximale Anzahl an Zeichen pro Beitrag sprengen.

      Ich weiß das mein Code unglaublich ineffizient geschrieben ist und das man das ganze mit wesentlich weniger Codeaufwand und viel eleganter machen kann. Leider lassen meine Fähigkeiten das momentan nicht zu. Bitte jagd mich also nicht gleich mit Fackeln und Mistgabeln davon :D

      Noch ein Gedanke. Bei den ganzen Subroutinen die ich verwende. Kann es da zu Problemen mit dem HW Stack kommen, bzw. dem verfügbaren SRAM? Mit den Stackwerten habe ich in allen Variationen rumprobiert. Die Werte die zur Zeit im Programm stehen, sind also eher zufällig. Empfehlungen werden dankend angenommen.

      Auf Seiten der Hardware sollte alles in Ordnung sein, meiner Meinung nach. Es sollte auch kein Problem mit dem Reset Eingang des Controllers sein. Der schaut sauber aus und die Spannung sackt auch nicht irgendwie mal ein.
      Habe auch schon andere Mega32 Controller ausprobiert. Selbes Spiel.

      BASCOM-Quellcode

      1. Sub Dig1char0
      2. 'Lokale Variablen deklarieren
      3. Local Cleardig0hsr As Byte
      4. Local Cleardig0lsc As Byte
      5. Local Setchar0ondig1hsc As Byte
      6. Local Setchar0ondig1lsr As Byte
      7. 'Variableninhalte setzen
      8. Cleardig0hsr = &B10000000
      9. Cleardig0lsc = &B11111111
      10. Setchar0ondig1hsc = &B11111100
      11. Setchar0ondig1lsr = &B10000000
      12. 'Setzen der Treiberausgänge zum löschen der bisher angezeigten Ziffer
      13. Cshsr = 0
      14. Spiout Cleardig0hsr , 1
      15. Cshsr = 1
      16. Cslsc = 0
      17. Spiout Cleardig0lsc , 1
      18. Cslsc = 1
      19. 'Alle zuvor gesetzten Ausgänge wieder abschalten. Anzeige ist bistabil.
      20. 'Ansonsten thermische Zerstörung der Spulen.
      21. Cshsr = 0
      22. Spiout Lowbyte , 1
      23. Cshsr = 1
      24. Cslsc = 0
      25. Spiout Lowbyte , 1
      26. Cslsc = 1
      27. Waitms 10
      28. 'Setzen der Treiberausgänge um neue Ziffer zu setzen. In diesem Fall Ziffer "0" auf der ersten Stelle.
      29. Cslsr = 0
      30. Spiout Setchar0ondig1lsr , 1
      31. Cslsr = 1
      32. Cshsc = 0
      33. Spiout Setchar0ondig1hsc , 1
      34. Cshsc = 1
      35. 'Alle zuvor gesetzten Ausgänge wieder abschalten. Anzeige ist bistabil.
      36. 'Ansonsten thermische Zerstörung der Spulen.
      37. Cslsr = 0
      38. Spiout Lowbyte , 1
      39. Cslsr = 1
      40. Cshsc = 0
      41. Spiout Lowbyte , 1
      42. Cshsc = 1
      43. End Sub
      Alles anzeigen
      Dateien

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von 128er ()

    • Frage: Warum hast du eigentlich für deine Subroutinen Subs deklariert?
      Mach daraus mal "normale" Subroutinen. Also mit

      Labelxyz:

      Return

      Zu deinem Problem

      Hast du schon mal einen anderen AVR getestet?
      Und setze auch mal deine stacks und framesize höher.
      Hätte Ferdinand Braun 1876 gewusst was heute aus seiner Erfindung der LED geworden ist, hätte er sie damals wohl nicht zur Seite gelegt.
    • 128er schrieb:

      Noch ein Gedanke. Bei den ganzen Subroutinen die ich verwende. Kann es da zu Problemen mit dem HW Stack kommen, bzw. dem verfügbaren SRAM? Mit den Stackwerten habe ich in allen Variationen rumprobiert. Die Werte die zur Zeit im Programm stehen, sind also eher zufällig. Empfehlungen werden dankend angenommen.

      Auf Seiten der Hardware sollte alles in Ordnung sein, meiner Meinung nach. Es sollte auch kein Problem mit dem Reset Eingang des Controllers sein. Der schaut sauber aus und die Spannung sackt auch nicht irgendwie mal ein.
      Habe auch schon andere Mega32 Controller ausprobiert. Selbes Spiel.
      Sorry, hatte später noch was dazu editiert. Kann sein das Du das noch nichtt gesehen hattest.

      Zur Zeit sind diese Werte eingetragen:
      $framesize = 100
      $swstack = 100
      $hwstack = 100


      djmsc schrieb:

      Frage: Warum hast du eigentlich für deine Subroutinen Subs deklariert?
      Mach daraus mal "normale" Subroutinen. Also mit

      Labelxyz:

      Return
      Für mich waren das bis jetzt "normale" Subroutinen. Werde es aber ausprobieren. Danke!
    • Declare Sub xyz(byval x as byte) macht man nur wenn man auch Daten an die Sub mit übergeben will.
      Oder einen Rückgabewert haben möchte Declare Function xyz(byval x as byte) as Byte.
      In deinem Fall brauchst du das aber nicht also reicht ein Label mit return.
      Hätte Ferdinand Braun 1876 gewusst was heute aus seiner Erfindung der LED geworden ist, hätte er sie damals wohl nicht zur Seite gelegt.
    • Was heißt 'reset geht nicht'? Wenn du dein Programm mit einem reset nicht neu starten kannst, ist was ganz grobes faul. Bricht deine Stromversorgung zusammen (Kurzschluss), dass der Kontroller nicht genügend Saft abkriegt? Oder ein Fehler im Netzteil? Wenn das früher schon mal ging, dann hat sich die hw verschlechtert. Mal die Verbraucher (Anzeigen) zunächst ab klemmen und schaun, ob das Programm weiter läuft.
      Aktiv bei der Energiewende mit machen, jetzt im Sommer Glühwein trinken (lässt sich mit weniger Energie warm halten) und im Winter gekühltes Bier (lässt sich dann leichter kalt halten).
    • djmsc schrieb:

      Declare Sub xyz(byval x as byte) macht man nur wenn man auch Daten an die Sub mit übergeben will.
      Oder einen Rückgabewert haben möchte Declare Function xyz(byval x as byte) as Byte.
      In deinem Fall brauchst du das aber nicht also reicht ein Label mit return.

      Bei verwendung von:

      Gosub XYZ

      XYZ:

      Return

      Kann ich dooferweise nur meine Lokalen Variablen nichtmehr verwenden, die ich in meinen Subs hatte. Werd es dennoch ausprobieren



      tschoeatsch schrieb:

      Was heißt 'reset geht nicht'? Wenn du dein Programm mit einem reset nicht neu starten kannst, ist was ganz grobes faul. Bricht deine Stromversorgung zusammen (Kurzschluss), dass der Kontroller nicht genügend Saft abkriegt? Oder ein Fehler im Netzteil? Wenn das früher schon mal ging, dann hat sich die hw verschlechtert. Mal die Verbraucher (Anzeigen) zunächst ab klemmen und schaun, ob das Programm weiter läuft.
      Es bedeutet das der Resettaster keine Auswirkung hat, nachdem der Fehler aufgetreten ist. Erst nach ausschalten und Spannungswiederkehr läuft der Controller an. Netzteil funktioniert einwandfrei. 5VDC sind sauber und sehr stabil. Keine Einbrüche messbar. Macht auch kein Unterschied wenn Last (Anzeigen) abgeklemmt sind.
    • Das mit dem reset wundert mich sehr. Kannst du mit einem Oszi prüfen, ob der Takt noch vorhanden ist? Wie schaut deine Beschaltung bezüglich Abblockkondensatoren aus?
      Aktiv bei der Energiewende mit machen, jetzt im Sommer Glühwein trinken (lässt sich mit weniger Energie warm halten) und im Winter gekühltes Bier (lässt sich dann leichter kalt halten).
    • djmsc schrieb:

      @128er Schau mal hier nach bei @tschoeatsch seiner Uhr.
      Vielleicht kannst du dir da was abgucken :)
      Sehr geil! :D

      Hatte ich noch garnicht gesehen. Wirklich schön. Die Anzeigen sind natürlich richtige Kawenzmänner im Vergleich zu meinen!

      Im Anhang mal mein Machwerk und den halb fertigen Plan. Zumindest der "Laststromkreis" ist fertig.

      EDIT: Forum verkleinert wohl den Schaltplan immer. Kann man leider nichts erkennen.
      Dateien
      • 7segsch.png

        (146,97 kB, 27 mal heruntergeladen, zuletzt: )
      • IMG_9453.JPG

        (327,37 kB, 24 mal heruntergeladen, zuletzt: )
      • 7segbrd.png

        (209,37 kB, 18 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von 128er ()

    • tschoeatsch schrieb:

      Das mit dem reset wundert mich sehr. Kannst du mit einem Oszi prüfen, ob der Takt noch vorhanden ist? Wie schaut deine Beschaltung bezüglich Abblockkondensatoren aus?
      Takt ist stabil und ohne Unterbrechung vorhanden. Egal ob Reset oder normaler Betrieb oder während des ominösen Fehlers.

      100nF Sind direkt am Controller. Also auch physisch gesehen nahe dran. Keine riesigen Leiterschleifen. Etwas weiter weg sind noch 47µF an der 5V Schiene. Die MC33880 Treiber sind auch mit Kapazitäten versorgt. 16V Lastschiene auch.
    • @128er woher weißt du eigentlich, das der Kontroller/Programm sich aufhängt? Wenn ich deinen 1. Post lese, dann sollte nach einer Minute die Minutenanzeige auf 1 schnappeln und tut das nicht. Kann die das? In einem Versuch probiert? Hast du die Led mal am Anfang der vermuteten sub ein und vor dem return mal ausschalten lassen?
      Bei deinem spiout bedienst du vorher und danach den chipselect. Brauchst du keinen clockpuls, um die eingeschobenen Daten zum Ausgang zu schalten?
      Aktiv bei der Energiewende mit machen, jetzt im Sommer Glühwein trinken (lässt sich mit weniger Energie warm halten) und im Winter gekühltes Bier (lässt sich dann leichter kalt halten).
    • djmsc schrieb:

      @128er hat aber auch geschrieben dass es schon mal lief und seit einiger Zeit nicht mehr. Ich könnte mir aber auch vorstellen dass sich einer von den Treibern verabschiedet hat und den Mega jetzt blockt.
      Er hat aber auch schon geschrieben, dass es keinen Unterschied macht, ob Verbraucher (Anzeigen) dran hängen oder nicht. Gut, wenn die Treiber dran bleiben, aber wie kann man bei reinen Ausgaben mit der Peripherie den Kontroller blockieren?
      Aktiv bei der Energiewende mit machen, jetzt im Sommer Glühwein trinken (lässt sich mit weniger Energie warm halten) und im Winter gekühltes Bier (lässt sich dann leichter kalt halten).
    • tschoeatsch schrieb:

      aber wie kann man bei reinen Ausgaben mit der Peripherie den Kontroller blockieren?
      Hab ich selbts schon gehabt, allerdings beim Brennen. Bei einiger Hardware die am ISP/SPI dran hängt, lässt sich der AVR nicht brennen (wird dann nicht mehr erkannt) erst wenn die HW weg ist geht es. (aber auch nicht immer, manchmal geht es auch mit HW)
      Er benutzt ja auch den HW-SPI (=ISP), da weiß ich zwar nicht wie es sich im normalen Programm verhält, wenn am SPI etwas nicht korrekt ist.
      Da es aber Hardware-SPI ist kann ich mir das schon vorstellen.
      Hätte Ferdinand Braun 1876 gewusst was heute aus seiner Erfindung der LED geworden ist, hätte er sie damals wohl nicht zur Seite gelegt.
    • 128er schrieb:

      'Setzen der Treiberausgänge zum löschen der bisher angezeigten Ziffer
      Cshsr = 0
      Spiout Cleardig0hsr , 1
      Cshsr = 1


      Cslsc = 0
      Spiout Cleardig0lsc , 1
      Cslsc = 1


      'Alle zuvor gesetzten Ausgänge wieder abschalten. Anzeige ist bistabil.
      'Ansonsten thermische Zerstörung der Spulen.
      Cshsr = 0
      Spiout Lowbyte , 1
      Cshsr = 1

      Cslsc = 0
      Spiout Lowbyte , 1
      Cslsc = 1
      wo lässt du dem display die Zeit zu reagieren? Diese Sequenz geht fei ratzfatz, beim folgenden Setzen der neuen Segmente das Gleiche. Da tut sich einfach nix an der Anzeige, auch wenn die sub durch läuft.
      Aktiv bei der Energiewende mit machen, jetzt im Sommer Glühwein trinken (lässt sich mit weniger Energie warm halten) und im Winter gekühltes Bier (lässt sich dann leichter kalt halten).