Hallo,
ich habe versucht, ein Programm in BASCOM zu schreiben, das ein
bestimmtes "Farb-Programm" auf einer RG-LED anzeigt. Die LED hängt an
PB3 und PB4 an einem ATTiny25. Funktioniert auch gut mit
Rot-Gelb-Grün-Gelb-Rot...-Wechseln. Jetzt wollte ich eine Farbfolge aus
Data-Zeilen laden und anzeigen. In den Data-Zeilen werden immer einzelne
Farben angegeben, zwischen denen dann langsam übergeblendet wird. Es
sollte auch funktionieren, ich habe alles nochmal auf Programmierfehler
geprüft, doch leider läuft der Stack (laut Simulator) über... M*st.
Selbst 110 Bytes reichen nicht! Mehr als 110 Bytes hab ich aber nicht...
Ich nutze die kompletten 128 Bytes vom ATTiny25 aus. Eigentlich war das
Programm sogar für einen ATTiny13 gedacht.
Kann mir jemand helfen, wie ich den Stack "entlasten" kann?
Der Code ist im Anhang.
Gruß,
Jemand mit Stackoverflow
Hallo,
Assembler hatte ich mir auch schon mal vorgenommen, bin aber sowas wie
BASCOM bereits seit 5 Jahren von der Windows-Programmierung gewöhnt...
Ich hatte ASM auch schon ein Bisschen gelernt, habe dann aber schnell
die Lust verloren, weil die Programme dann so lang werden (das kann aber
auch daran liegen, dass ich es noch nicht so lang benutzt habe). Ich
werde mich in asm wahrscheinlich auch noch einarbeiten, aber nicht
jetzt, weil ich erstmal lernen will, mit BASCOM "smart" zu
programmieren.
Gruß,
Jemand mit Stackoverflow
Die Tabelle ist schon im Flash (Data-Zeilen). Es kann aber sein, dass
Read viel Stack braucht... Ich probiere es jetzt mal mit dem EEPROM.
Vielleicht braucht das weniger Stack zum lesen. Der Stack läuft nämlich
immer dann über, wenn er einen neuen Wert aus dem Flash holt.
Danke für den Tipp mit dem EEPROM!
Gruß,
Jemand mit Stackoverflow
Hallo,
ein Problem bei BASCOM ist es, dass beim Verwenden einer Interrupt-
Routine fast alle internen Register auf den Stack gesichert werden; das
belegt schon mal ca. 30 Byte. Es gibt zwar die Option "Nosave", aber
dann muss man selbst die verwendeten Register sichern (was bei Basic in
der ISR nicht einfach ist).
Ich bevorzuge es, bei BASCOM in der ISR nach Möglichkeit Inline-
Assembler zu verwenden. Dann weiss ich, welche Register ich sichern und
wiederherstellen muss, und wenn grössere Berechnungen anstehen, wird in
der ISR (meist von einem Timer) ein Flag (Bit, Byte) gesetzt, das dann
in der Hauptroutine ausgewertet wird. So bleibt die ISR schön schlank
...
Ein Vorteil ist, dass man bei BASCOM auf dimensionierte Byte-Variablen
im (BASCOM-) Assembler zugreifen lann; so wird das Setzen von Bits in
Variablen oder das Übergeben von Variablen aus der ISR vereinfacht.
Gruss
P.S.: Multiplikationen und vor allem Divisionen haben in einer ISR
nichts verloren; sie brauchen auch einiges vom Stack. Sowas gehört in
die Haupt-Routine; dort werden sie mittels Flag aus der Timer-ISR dann
aufgerufen.
Und Divisionen durch 256 ersetzt man durch Shift-Operation (Shift ... ,
Right, 8); das geht viel schneller und braucht kaum Ressourcen.
Die PWM sieht sehr umständlich aus.
Warum willst Du sie unbedingt zu Fuß machen, nimm doch einfach 2 der
HW-PWMs.
Und dann nimm den anderen Timer für das Tempo und mache alles in der
Main-Loop ohne Interrupts.
Deine SW-PWM dürfte auch heftig flackern bei jedem Interrupt.
Warum dem Bascom die 128 Byte SRAM nicht reichen, verstehe ich auch
nicht.
Peter
@Bascom-User:
Ja, das mit den 32 Bytes weiß ich... Aber es sind nur 32 Bytes der mehr
als 110 Bytes, die da den Stack platzen lassen, deshalb lasse ich es
jetzt erstmal so, die ISR geht ja, bis dann die neue Farbe gelesen wird.
Die Divisionen hatte ich wohl durch das ganze Umprogrammieren wieder
rein getan und dann vergessen... Das werde ich jetzt noch ändern.
Gruß und danke für die Tipps,
Jemand mir Stackoverflow
@Bascom-User:
Danke für den Tipp mit den Flags! Es geht jetzt! Das mit dem Auslagern
in die Main-Loop hat geklappt! ISR + Farbe lesen war dann wohl zu viel
für den Stack. Vielen Dank!
@Peter Dannegger:
Wie könnte ich die PWM besser machen? Ich hab ja schließlich 3 Zustände
der LED: Rot, Grün, Aus. Wie mache ich das am Besten mit einer Hard-PWM?
Ich möchte nämlich auch die Helligkeit steuern können.
Gruß und tausend mal Danke,
Jemand mit (ehemaligem :D) Stackoverflow
Jemand mit Stackoverflow schrieb:> Wie könnte ich die PWM besser machen?
Indem du sie von der Hardware erledigen lässt. Dafür hat dir Atmel extra
beim Timer PWM-Modi eingebaut.
> Ich hab ja schließlich 3 Zustände> der LED: Rot, Grün, Aus.
Hast du nicht.
Du hast konzeptionell 2 LED an 2 Pins. Mit der Hardware PWM bist du
allerdings in der Pin-Wahl nicht mehr frei sondern musst dich nach dem
richten, was dir Atmel vorschreibt.
Dort hast du also 2 LED und für jede LED kannst du mittels Hardware PWM
die Helligkeit von komplett aus bis 100% ein in vielen Abstufungen
einstellen.
> Wie mache ich das am Besten mit einer Hard-PWM?
Indem du die BASCOM Hilfe zum Thema Timer (bei den CONFIG Sachen
studierst)
Warum hast du ausgerechnet den SwStack auf 110 gesetzt und die anderen
auf 0?
Im SoftwareStack werden die Adressen der Parameter von Funktionen oder
Subroutinen gehalten. Hast du beides nicht.
Im Frame werden die Werte der übergebenen Parameter abgelegt. Außerdem
nutzt Bascom 24Byte für Typ Konvertierungen von Zahlen in Strings.
Da du weder Parameter noch Strings in deinem Programm hast, brauchst du
auch keinen Frame.
Dein Problem ist die 0 bei HwStack. Dort werden die Register und die
Rücksprungadresse aus der Interruptroutine gespeichert.
Ergo so:
$HwStack = 32 'reicht
$SwStack = 0
$FrameSize = 0 ' 24 zur Sicherheit, falls du mal ein LCD oder einen
Print Befehl benutzen willst.
Hallo,
ich hatte viel zu tun, deshalb kann ich mich erst jetzt melden.
@mue-c:
Oh, das habe ich noch gar nicht gewusst, dass das mit dem sw- und dem
hw-Stack so ist. Vielen Dank, dass du mir das gesagt hast! Jetzt geht's
auch mit nur 32 Byte Stack. Dann kann ich es ja auch wie geplant auf
einen Tiny13 machen! Danke!
Gruß