Bascom Probleme mit einer Variable

...ist mir wohl soweit bekannt das man das nicht umbedingt so macht, da aber sowieso nur mit einem Reset wieder rausgesprungen wird ist das wie Du schon Sagst kein alzugrosses Problem!
HIER gerade nicht, aber generell sollte man sich sowas gar nicht erst angewöhnen...
Sauberer wäre entweder, den Ende-Code mit in die Timerüberlauf-Subroutine zu nehmen (effizienter aber logischerweise unübersichtlicher), oder den Ende-Code auch als Subroutine gestalten, und den dann aus der Timer-ISR heraus anzuspringen (Gosub). Dann ist das sauber geschachtelt, in Ende könnte man später auch noch ein aufwecken des Controllers einbauen, von wo dann sauber in die Timer-ISR, und von dort in die Main-Loop "return"t werden kann.
Also sauber geschachtelte Subroutinen.
Eine weitere saubere Alternative wäre, in der Timer-ISR stattdessen in Timeoutflag zu setzen, und dieses in der Hauptprogrammschleife abzufragen.Die ISR wird dann vorher sauber verlassen (alle Stacks ordentlich aufgeräumt), im Hauptprogramm kannst Du dann nach "Ende" hopsen.
(Entweder endgültig mit GOTO, oder wenn eine Rückkehr möglich sein soll mit GOSUB (wobei Ende dann logischerweise eine Subroutine sein muß).)

Natürlich kann man von diesen ganzen Konzepten abweichen, der AVR macht jeden Mist mit, den Du ihm sagst. Aber dann mußt Du eben auch wirklich wissen, was Du ihn tun läßt.

Goto springt einfach zur neuen Flash-Adresse.
Gosub auch, legt aber zusätzlich die Rücksprungadresse auf den (HW-)Stack
Call ist Gosub ähnlich, packt aber zusätzlich(!) entsprechend der in declare Subroutine deklarierten Variablen irgendwelchen Kram in den Frame und/oder SW-Stack
Entsprechend müssen beim beenden einer deklarierten Call-Sub die verwendeten Stacks sauber abgeräumt werden -> End Sub bzw Exit Sub
Entsprechend muß beim beenden einer Gosub-Sub der HW-Stack sauber abgeräumt werden -> Return nimmt die oberste Adresse (war ja, wenn man nichts durcheinander gebracht hat die Rücksprungadresse), und hopst dahin.
(Handelt es sich bei einer Gosub-Sub um eine ISR (also mit On Interruptquelle "deklariert"), reaktiviert das erste Return (ausserhalb irgendwelcher IF-Conditions) ausserdem global die Interrupts (RETI statt RET)
Springt man zB aus einer ISR (Interrupt also deaktiviert) mit Gosub in eine andere ISR hinein, werden bei der Rückkehr von dieser in die Erste bereits die IRQs global freigegeben. Stacktechnisch paßt das aber...)
...Bei deinen debounce musst du mit subs arbeiten. Das Programm läuft nach dem decr bis zu return und holt sich eine Adresse aus dem stack...
Nein... oder besser gesagt nicht wegen debounce, sondern weil die Sprungziele (Press, Press2, Press3) eben als Subroutinen mit je einem Return enden, welches erstens die obersten beiden Bytes vom Stack nimmt (da fehlt also jetzt was, außerdem könnte der Stackpointer ins Nirvana laufen (laut Datenblatt hat der volle 16bit (also bis Adresse 0xFFFF), SRAM gibts aber nur bis Adresse 0x045F),
und zweitens diese beiden Bytes als Adresse für den Rücksprung nutzt.

Es wurde ja nicht konkret geschrieben, was geht, und was nicht. Meinem derzeitigen Verständnis nach sillte nur die Voreinstellung korrekt arbeiten (debounce..Press2...).
Wird eine der anderen Tasten gedrückt, geht die Anzeige auf "00", soweit korrekt?
Immer "00"?
Zahl wird ja eigentlich nicht initialisiert, ist also nach dem Programmstart 0.
Der Grund ist in Bascom ziemlich fies versteckt:
Eigentlich hat der SRAM nach einem Powerup eher zufällige Werte, auch nach einem Reset kann da alles mögliche stehen. Daß das immer 'ne 0 sein soll, hatte mich ziemlich verwirrt.
Der Grund ist, das Bascom beim Start des Programmes einfach den gesamten SRAM löscht (=0 setzt), es sei denn, man iunterdrückt das mit der $NORAMCLEAR-Direktive.
Damit wäre das verhalten (meiner Meinung nach(!!))nachvollziehbar.
In der Hauptprogrammschleife ist der HW-Stack leer, der Stackpointer zeigt auf 0x045F (RAMEND). Ein Gosub würde(!) dorthin die Rücksprungadresse PUSHen und danach (Post Decrement) den Stackpointer dekrementieren (jaja, zwei Bytes, zwei PUSHs, die Adresse steht also in 0x045E:0x045F, der SP zeigt auf 0x045D).
Am Ende der SUB wird die Adresse vom Stack gePOPt, wobei eben erst (Pre Increment) der SP Incrementiert wird (auch wieder zwei Bytes, die Inhalte von 0x045E:0x045F sind die Rücksprungadresse, der SP ist wieder 0x045F.
Jetzt wird aber nicht mit Gosub gesprungen, sondern mit Goto. Der Stack bleibt also leer, der SP auf 0x045F.
Am Ende der SUB schlägt dann das Return zu:
es wird zweimal vom Stack gePOPt, also erst der SP PreIncrementiert, und dann von da (0x0460) geladen. Diese Zelle existiert schlichtweg nicht, Zelle 0x0461 beim zweiten POP ebenso.
Meiner Meinung nach liefern beide POPs also jeweils 'ne 0, und genau dahin wird gesprungen:
Flashadresse 0x0000
Das entspricht dem Reseteinsprungpunkt (auch wenn es kein Reset ist, insbesondere also die I/O-Register, der SRAM usw bestehen bleiben).
Aber dort beginnt der Programmcode inklusive den Initialisierungen, die BASCOM so implementiert. Auch inklusive des SRAM-Clears.
Zahl wird also auch 0 gesetzt, die Timer etc... reinitialisiert. Die Vorauswahl mit Debounce..Press2 und die Anzeige geht erstmal wieder (bis zum nächsten Drücken einer der anderen beiden Tasten...

P.S.: mMn sollte der Code übrigens trotzdem so laufen, wenn mit der $NORAMCLEAR-Direktive ein löschen der Variablen (insbesondere Zahl) beim ... äh ... Warmstart unterdrückt wird.
Das wäre dann quasi das Bild mit dem "Analysten" aus dem, von @TommyB hier ...
 
  • Like
Reaktionen: Tschoeatsch
Danke an TommyB und Tschoeatsch das mit SUB ist wirklich der Fehler gewesen !
Danke auch besonders LotadaC für die Ausführliche Erklärung die muss man aber erst Verdauen als Bascom Anfänger oder Bzw. als Programieranfänger ist das alles etwas viel vorallem wenn man schon weit über die 50 ist!
Vieleicht hat noch jemand einen kleinen Tip wie ich die Speaker ausgabe besser gestalten kann da ja durch die ISR alles etwas zerhackt wird !
In der Endrutine ist das ja kein Problem da zu diesem Zeitpunkt die ISR schon ausgeschaltet ist, aber während eines Tastendrucks natürlich nicht!
 
  • Like
Reaktionen: TommyB
Wenn ich das richtig verstanden habe, läßt sound einfach 'ne Zeitlang ein Bein zappeln. Wird das ganze (durch einen IRQ) unterbrochen, gibts entsprechende Aussetzer...

Du könntest das ganze auch an einen PWM-fähigen Timer übergeben. Dann stößt Du den einmal an, und er zappelt bis Du ihn wieder aufhören läßt.
Timer0 scheint das beim Mega8(A) nicht zu können (der ist offensichtlich überhaupt wenig potent), Timer1 nutzt Du bereits für das Timeout - bliebe Timer2.

P.S.: Dein Timeout wäre eigentlich 'ne schöne Aufgabe für den Watchdog - leider gibts beim Mega8(A) keinen Watchdog-IRQ.
Prinzipiell würde das folgendermaßen gehen:
Der Watchdog entsprechend eingestellt/gestartet, und ggf regelmäßig zurückgepfiffen.
Löst er aus, geht der Controller in den Reset (da es ja eben keinen IRQ gibt).
Beim Programmstart (Reset) könnte am Anfang nun die Resetquelle ermittelt werden (Reset-Flag-Register (MCU Control and Statusregister - MCUCSR)) - war der Wachhund der schuldige, wird zum "Ende" gesprungen, sonst wird ganz "normal" gestartet.
Ob man das mit Bascom hinbekommt, weiß ich nicht (also ob Bascom was mit dem MCUCSR macht bevor man da ran kommt).
In Assembler gibts solche Schranken halt nicht...

P.P.S.: Den ganzen Krempel im Hintergrund mußt Du zum Programmieren in Bascom natürlich nicht unbeding wissen, es ist ja gerade die Aufgabe einer Hochsprache, das alles von Dir fernzuhalten, für Dich zu erledigen.
Aber dann mußt Du Dich eben an die Regeln der Sprache halten.
Also daß mit declare deklarierte Subroutinen mit einem End Sub beendet werden müßen, und bei Bedarf zusätzlich(!) mit Exit Sub abgebrochen werden können
(Call lagert Daten auf den Stacks und dem Frame aus, End Sub stellt das alles wieder her und veranlaßt den Rücksprung, Exit Sub ist quasi nur ein Sprung zum entsprechenden End Sub)
Oder daß nicht deklarierte Subroutinen (Gosub, dazu gehört eben auch debounce wenn Sub als Parameter, oder eben die ISRs) mit einem (!) Return verlassen werden. (Gosub & co. packen die Rücksprungadresse auf den Stack, Return nimmt'se wieder runter und hopst...)).

Meine Erläuterungen sind dann eher für diejenigen ide sagen: "Ok ok, ist ja alles schön und gut... Aber WARUM sollte das jetzt so oder so gemacht werden?"
 
Meine Erläuterungen sind dann eher für diejenigen ide sagen: "Ok ok, ist ja alles schön und gut... Aber WARUM sollte das jetzt so oder so gemacht werden?"
Ein bisschen Hintergrundwissen ist niemals verkehrt. Bascom ist ja wie C und LunaAVR nur eine "Zwischensprache". Du sagst der was, die interpretiert das was du geschrieben hast (aber ggf. nicht so meintest) und setzt das in Maschinencode um. Auch wenn man das Hintergrundwissen "nur" zur Kenntnis nimmt und nicht gleich auf ASM umsteigt kann es selbst auch bei Bascom/C/Luna helfen ;)

Aber schön dass es jetzt läuft :)
Zu dem Piepser hatte LotadaC ja schon was gesagt, wenn ich mich richtig erinner läuft es auch genau so ab (einfach ein Pin zappeln lassen, aber Interrupts machen halt genau das wofür sie da sind: sie unterbrechen (kurzzeitig)).
Ich weiß nicht ob es in Bascom vielleicht sogar eine interne Lösung gibt die das Problem nicht hat. Da würde denn bestimmt irgendein Timer verwendet werden. Zur Not könnte man es damit auch per Hand umsetzen.
 
Nimm halt dein Multiplexen. Einfach in der Multiplex-isr eine Abfrage: if piep=1 then toggle portx.y(wo der Lautsprecher hängt) else portx.y=0(kein Ruhestrom durch den Ls). Jetzt setzt du in der main piep=1,wartest bisschen, dann piep=0 und schon knatterts am Lautsprecher. Die Frequenz ist die vom Multiplexaufruf, niedriger geht durch einen Zähler. Musst halt mal rechnen, ob's passen könnte.
 
Grundsätzlich sollte man natürlich mit einem Timer auskommen können.
Habe gerade noch gesehen, daß beim Multiplexing jedesmal diese Modulo-Konversion zum ermitteln der Ziffern durchgeführt wird. Das ist unnötig.Es reicht, Einer und Zehner nur jedesmal dann zu berechnen (wenn man nicht gleich von Anfang an mit getrennten Variablen für jede Stelle arbeitet - > BCDs), wenn sich die Zahl ändern soll, also die Zeilen 103 bis 107 (eigentlich steht das Ergebnis schon in 106, nur in der falschen Variable, der Rest bis 110 ist dann nur ein Klotz am Bein) aus dem Multiplexing (Anzeige) rausnimmt, und stattdessen nach "Press2" bzw "Press1" ausführt. (zB indem man diese Zeilen in einer eigenen Subroutine unterbringt, die dann mit Gosub von "Press2" und "Press3) aus angesprungen wird)
(Aber wie angedeutet: Du kannst auf Zahl auch komplett verzichten und direkt "Zehner" und "Einer" verwenden. im Select..Case in "Press2" weist Du halt nicht eine Konstante an "Zahl" zu, sondern zwei Konstanten an "Zehner" und "einer", in "Press3" dekrementierst Du nicht Zahl, sondern erstmal "Einer". Kommts dabei zu 'nem Überlauf (ähm Unterlauf, also 0->255) setzt Du Einer auf 9 und dekrementierst Zehner (da kanns dann auch'n Unterlauf geben) Zehner und Einer SIND BCDs. Die Rechnerei hinterher entfällt, allerdings hast Du statt Zahl jetzt immer zwei einzelne Ziffern.

Das Multiplexing selbst würde ich (mal wieder - steht hier irgendwo schon mehrfach im Forum) an einen PWM-fähigen Timer übergeben. Zwei Interrupts (Einen der Compares und den Überlauf). Einer fürs Abschalten der beiden Anoden und das auflegen der nächsten Stelle auf die Kathoden, den anderen IRQ zum auflegen einer der Anoden. Mit Hilfe ds Compare-Wertes kann man dann sogar die Helligkeit regeln. Den zweiten Kanal könnte man zur Ausgabe des Rechteckimpulses für den LS nutzen (also den Comparewert auf 50%, schaltet man den CompareOutputMode des Kanals auf zwei oder drei knatterts, schaltet man auf null, gelten die letzten Einstellungen des PORT-Bits. (COM=1 würde mit halber PWM-Frequenz knattern).
Außerdem kann man in einem der beiden IRQs den Timeout-Zähler miteinklinken, sinnigerweise über ein Flag, einen Knoten im Taschentuch an die Hauptprogrammschleife übermittelt (die muß sich dann halt bei jedem Durchlauf die Nase putzen, und reagiert auf den eventuellen Knoten...)

Aber es ist Dein Programm, und es scheint ja so zu gehen - sind meinerseits nur ... Vorschläge, über die man zumindest nachdenken kann...
 
Zuletzt bearbeitet:
Hi,

Casio ich muss ehrlich zugeben das ich Dir hier nicht ganz folgen kann, würde ja auch lieber auf BCD gehen nur das würde bedeuten das ich ein BCD zu 7Segment-Wandler einsetzen muss wo ich leider kein Räumlichen Platz für habe.

da hast du Cassio falsch verstanden. Er benutzt die BCD-Wandlung anders ...

Dezimal 78 = Binär 0100 1110 - - damit kann man wenig anfangen :oops:
Dezimal 78 = BCD 0111 1000 - - Damit kann man was anfangen :D

Wandel mal die einzelnen 4Bit-Gruppen in Dezimal ... 0111 = 7 , 1000 = 8
Du mußt lediglich die beiden 4er-Gruppen in einzelne Byte verfrachten und dann hast du deine Einer und Zehner. Viel einfacher als mit dem ganzen Modulo-Kram.

Gruß
Dino
 
Hallo zusammen!

Ich habe jetzt nicht alle Antworten von euch gelesen.....
aber scheinbar bin ich bei den ganzen Zahl-, Zahl_temp- und Zaehler-Variaben irgendwann im Hirn falsch abgebogen. :confused:

Sorry, war mein Fehler! :adore:
Scheinbar war ich nach zwölf Stunden Arbeit doch nicht mehr so fit im Kopf wie ich dachte. :shout:

Trotzdem würde ich die folgenden Zeilen aus dem Programm entfernen, weil sie einfach keinen Nutzen haben!



CodeBox BascomAVR
Zehner = Zahl_temp Mod 10 
Zahl_temp = Zahl_temp - Zehner 
Zahl_temp = Zahl_temp / 10



Dadurch reicht dann also:


CodeBox BascomAVR
Zahl_temp = Zahl 
Einer = Zahl_temp Mod 10 
Zahl_temp = Zahl_temp - Einer 
Zehner = Zahl_temp / 10 



Wie aber schon angedeutet und wie Dino es auch schon geschrieben hat, wäre folgendes einfacher:


CodeBox BascomAVR
Zahl_temp = Makebcd(Zahl)  'Zahl ins BCD-Format

Einer = Zahl_temp And &B0000_1111  'nur die ersten 4 Bits
Shift Zahl_temp , Right , 4  'hohe 4 Bits zu low schieben
Zehner = Zahl_temp And &B0000_1111  'nur die ersten 4 Bits




Unglücklich ist auch dieser Bereich:



CodeBox BascomAVR
Zeittimer:  ' Soll nach einer Zeit abschalten wenn nichts passiert weil Batteriebetrieb
Incr Zaehler  ' Wert der Abschaltung zum Test nur auf 10 gesetzt!
'If Zahl = 98 Then
If Zaehler = 10 Then
[B]Goto Ende[/B]
End If
Return

[B]Ende: [/B] ' Abschalten aller Ports Interrups und Timer
Disable Interrupts
Stop Timer0
Stop Timer1
Sound Speaker , 1200 , 300  ' Pipton zur Akustischen Wahrnehmung der Abschaltung
Portb = 0  ' rückholung mit absicht nur mit Reset
Portc = 0
Portd = 0
Idle  ' Zur Ennergieersparniss in den Idle-Mod wechseln
End



Per Timer in die Subroutine springen und dann nach einer bestimmten Anzahl Aufrufe via Goto in ein anderes Label springen, ohne die Sub zu beenden.
Durch den Idle-Befehll ist das hier zwar egal, jedoch sollte man es sich nicht angewöhnen.



Da mir sonst kein Fehler mit der "Zahl" aufgefallen ist, würde ich einfach mal die Standardwerte für Stacks und Framesize drastisch erhöhen.
Schließlich ist noch genug Platz vorhanden.
Möglich wäre, dass die Werte vermutlich nicht ausreichend sind, für alle Variablen, Subroutinen, Timer usw.


Grüße,
Cassio
 
Zahl_temp = Zahl_temp - Einer
Das braucht es auch nicht, bei der Division hat er automatisch eine ganze Zahl, was abgezogen wird wäre die Kommastelle. Bei einer 2-stelligen Anzeige mag ja mit Bcd noch elegant erscheinen, bei mehr Stellen finde ich die 'mod 10' Variante schöner, find' ich dann übersichtlicher.
 
Ob du nun 1 Byte (2 Stellen) nimmst oder 2 (für 4). Ich rechne fast ausschließlich in BCD (bei den AVRs). Für mich sind es immer nur Increments, Decrements oder Zuweisungen. Echtes Mathe (also +5, -3, *3, …) ist dafür wesentlich schwerer umzusetzen, aber häufig einfach nicht benötigt. Ist ja auch nicht grundlos dass fast alle RTC's ihre Daten im BCD speichern und ausliefern.

Aber es kommt auf die Umsetzung an. Cassio, nichts gegen dich, aber so wie bei dir würde der Wert ja immer noch dezimal gespeichert und umgerechnet werden. Um es lohnenswert zu machen müsste man das schon konsequent machen. Der Vorschlag von Cassio ist aber trotzdem auf jeden Fall besser als mit /10 und %10.


Ich nehme jetzt mal einfaches BCD als Beispiel statt gepacktes, sprich 1 Byte pro Stelle. Lässt sich aber schnell auf gepacktes BCD ummünzen.

Du möchtest eine Zahl haben, also 0..9
Du wirst die eh nur zuweisen (keine Operation), hoch oder runter zählen.
Hoch zählen ist ein einfaches Increment und eine Überprüfung ob der Wert 10 (0x0A) ist. Wenn dann auf 0 setzen und die nächste Stelle hoch zählen (bei gepacktem BCD einfach +5).
Runter zählen ist eine Abfrage ob der Wert bereits 0 ist. Wenn ja auf 9 setzen und die nächste Stelle um 1 reduzieren.
Es sind weit weniger als 10 (Maschinen-)Befehle.

Um aber von Dezimal in BCD – oder an die einzelnen Stellen einer Ziffer zu kommen braucht es mehr.
Temporären Speicher. Der Wert muss zwischengespeichert werden.
Dann vergleichen ob der Wert kleiner als 10 ist. Dann Einer = Wert und raus. Sonst Wert - 10, Zehner + 1, und das Ganze von Vorne.
Division und Modulo ist noch mal um ein vielfaches komplizierter (für den Controller) da die Dinger einfach nicht dividieren können. Klar, /2, /4, /8, ... erreicht man durch Bitschubserei, aber ob Bascom dahingehend auch genug Möglichkeiten hat zu optimieren? Oder muss die Zahl (mehrfach) durch ein per Software umgesetzten Fließkommaalgorythmus durch? Dann kommste bestimmt an die 1000 Taktzyklen. Statt 10.

Kennt man jetzt nur Bascom/C/LunaAVR dann weiß man das nicht, es interessiert einen vermutlich auch nicht. Es läuft ja.
Höchstens fällt es auf dass durch ein geschriebenes / oder Mod der Flash wesentlich größer wird, eben weil die Software für die Division und Fließkomma integriert werden muss. Wenn man soweit geht wird es auch der Stromverbrauch zeigen, da ja mehr gerechnet werden muss und somit Idle/Sleep/PowerDown etc. nicht mehr greifen können.


Aber das sind Details die für manche garantiert interessant sind, manche vielleicht sogar beherzigen, manche aber einfach ignorieren da es ja jetzt läuft. Wie auch immer, muss jeder selber wissen wie er es umsetzt. Nur in manchen fällen muss man eben auf sowas achten. Grade bei Batteriebetrieb oder extrem zeitkritischen Anwendungen.
 
Bei Division und Modulo werden drei Register nach links geschoben/-rollt, ein Compare, ein bedingter Sprung, ggf eine Subtraktion und eine Addition.
Das ganze in einer Schleife achtmal (bei 8Bit).
Benötigt 4 Register (Divident, Divisor, Quotient und ein Arbeitsregister).
Nach der Division enthält das Arbeitsregister immer den Rest.
Bei Modulo kann ein Schieben und die Addition raus, ansonsten ist das genau dasselbe. Ob Bascom dafür denselben Code nutzt, weiß ich nicht.

P.S.: Multiplizieren ist (ohne MUL) übrigens sehr ähnlich...
 
@LotadaC du bist ja auch eine hochqualifizierte Bitschubse.
Ich erinnere mich noch an meine Bascom Zeiten vor x Jahren. Eine Division im (5zeiler) Test Code drin, zack, fast 2KB Flash belegt, also schon kurz vor Ende des Trial Limits.

Man weiß halt nie wie es umgesetzt wird, außer man macht es selber.

Aber das ist bei der PC Entwicklung genau so, nur dass man da fast garnicht mehr auf den ASM Level kommt. Da heißt es denn ausprobieren. Viele Wege führen nach Rom. Tendenziell wäre der gen Süden intelligent, aber nicht zwangsweise der Erste den man geht.
 
Das da oben ist schon der reguläre Aufwand der ganzzahligen(!) Division, Bascom wird das auch nicht anders machen. Eigentlich nichts anderes als die schriftliche Division, die man in der Schule hatte, nur einfacher, da binär...

Wird im Code dividiert, baut Bascom die Routine mit ein. Ob die kürzere (und schnellere) spezielle Modulo-Variante zusätzlich reingepackt wird, wenn im Code Modulo vorkommt, oder ob dann eben auch Dividiert wird, und das Rest-Register zurückgegeben wird, weiß ich nicht. Würde dann halt mehr Flash kosten aber (etwas) schneller sein. Das meinte ich oben.

Solche Sachen mit explodierendem Code wegen 'nem Fünfzeiler hast Du eher, wennst unnötig komplizierte Variablen nimmst (und dann mal dividierst oder so) -> Fließkomma etc...
Ich hatte auch mal irgendwas, was mit einfach-genauen Zahlen nicht ging, und man doppelt genaue nehmen mußte. Also nicht wegen der Genauigkeit, sondern weil Das sonst nicht wie gewünscht in BCD oder 'n String oder so konvertiert werden konnte (irgendsowas jedenfalls)

Hmm... man könnte natürlich auch versuchen herauszubekommen in welchem Register Bascom die Division abarbeitet, wo der Rest "abfällt", und dieses direkt nach der Division Auslesen. Möglicherweise muß man drumrum die IRQs global unterdrücken.

Leider bekomme ich das mit dem Reassemblieren seit irgend'nem AVRStudio- und/oder BASCOM-Update nicht mehr hin, sonst könnte man das mal "durchleuchten"
 
Danke euch allen erstmal recht Herzlich für so viele Antworten und Informationen!!:bounce:
Es ist leider schon sehr Spät (Früh) habe im Moment nicht mehr die Möglichkeit mir alles durch zu Lesen .
Versuche abere am Sonntag mir alles in Ruhe durchzulesen, habe aber beim überfliegen auch feststellen müssen das alles ein bischen zu viel ist was man da als Anfänger verdauen muss, gebe mir aber die grösste mühe das Verspreche ich!:kap:
Danke auf jeden Fall.:good::good:
 
Ach so kompliziert ist das alles garnicht. Wir waren nur etwas ausführlich.
Das Problem ist ja jetzt behoben, es ging hier jetzt nur noch um das Warum und um Optimierungen wie du es besser umsetzen könntest + den Hintergründen dazu (nicht als Kritik verstehen!). Grade weil du sagtest dass – wie ich dich verstanden hatte – du BCD nicht nutzen magst da du keinen Platz mehr für Hardware auf der Platine hast. Es gibt zwar ICs für BCD, aber das kann der AVR schon selber :)

Anfängern rate ich auch immer noch an den Code vernünftig einzurücken. Also z. B. statt


CodeBox BascomAVR
Zeittimer:  ' Soll nach einer Zeit abschalten wenn nichts passiert weil Batteriebetrieb
Incr Zaehler  ' Wert der Abschaltung zum Test nur auf 10 gesetzt!
'If Zahl = 98 Then
If Zaehler = 10 Then
Goto Ende
End If
Return

lieber:


CodeBox BascomAVR
Zeittimer:  ' Soll nach einer Zeit abschalten wenn nichts passiert weil Batteriebetrieb
    Incr Zaehler  ' Wert der Abschaltung zum Test nur auf 10 gesetzt!
    'If Zahl = 98 Then
    If Zaehler = 10 Then
        Goto Ende
    End If
Return

Das macht es einfach übersichtlicher und dir selber leichter. Bei manchen Sprachen (Python z. B.) ist das sogar zwingend erforderlich.
So fällt hier z. B. auch eher auf dass dieses GoTo innerhalb einer Sub steckt die das Sprungziel nicht beinhaltet (potentiell böse).

Wir wollen ja helfen. Aber echte Hilfe ist eben die Hilfe zur Selbsthilfe. ;)
Nur ein "nimm das ' vor dem Sub weg" hätte dein Programm zwar lauffähig gemacht, dir aber nicht geholfen. Weil irgendwann stehst du möglicherweise wieder vor dem selben Problem.
 
Naja, ist letztlich auch recht :offtopic: geworden...
Grob gesagt ist festzuhalten, daß Divisionen die AVR generell belasten - den Flash-Verbrauch (Platz) zumindest etwas, die Laufzeit deutlich. Solange das akzeptabel ist ... -> ok.
Bei der Multiplikation ist das eigentlich genauso, allerdings können die Megas gegenüber den Tinies in Hardware multiplizieren.

Richtig aufwändig ist, mit Fließkomma zu rechnen (Bascom bietet natürlich entsprechende Bibliotheken/ bindet das bei Bedarf ein).
Deswegen ist es halt einfach, sowas zu nutzen - die andere Seite ist, daß man das dann ggf nicht unbedingt mitbekommt, und sich wundert, warum der Flash schon voll ist, oder der Controller vermeintlich zu langsam...
Weil das teilweise so leicht genutzt werden kann, lernt man gar nicht zu entscheiden, welche Variablentypen für ein Problem sinnig (effizient) eingesetzt werden könnten.
Solange man dabei nicht an irgendwelche Grenzen des Controllers stößt, interessiert einen das natürlich nicht wirklich...

Das wird alles auch ein wenig verständlicher, wenn man sich mit dem eigentlchen Controller, seinem Aufbau/Arbeitsweise usw etwas auseinandersetzt.
Das muß man natürlich nicht - für mich war das anfangs unter Bascom auch sowas wie'n "Zauberwürfel", den man durch Bascom "magisch" ansteuern konnte -> ohne wissen zu müssen, was der Controller da wirklich tut, es geht halt einfach. Aber mir(!) war das irgendwann nicht mehr genug.

Laß Dich nicht aus der Ruhe bringen...
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)