Bascom Probleme mit einer Variable

uwe-ftechnik

Mitglied
31. Jan. 2009
71
1
8
Bekum
Sprachen
Habe hier mal versucht ein Programm zu schreiben dort kann man mit einer Taste vordefinierte Werte auswählen die dann mit einem eingang in einserschritten wieder runtergezählt werden sollen. Leider wenn ich aus dem Programmteil zur Auswahl zurückspringe in die Hauptschleife wird mir der ausgewählt Wert wieder auf Null gesetzt! Bin schon fast die ganze Woche bei dem Problem habe schon überall gesucht ob ich einen Fehler gemacht habe aber auch das WWW gibt mir keine Information darüber! Vieleicht kann mal einer der Experten für Bascom da rüber schauen und mir sagen wo der Fehler liegt!
Ich hoffe das ich hier nicht den falschen Berreich für meine Frage erwischt habe, wahr leider sehr lange nicht mehr hier im Forum. Wenn ich doch versehentlich falsch gelandet bin Bitte ich um Nachsicht und wenn möglich um Information wo ich dann richtig währe.
Anzeige mit Zweistelliger 7Segment Anzeige, Funktioniert auch soweit ganz gut inklusive der Abschaltung nur die Vorwahl der Variable "Zahl" wird mir immer wieder auf Null zurückgesetzt was nicht dem Zweck entspricht!
Währe sehr freundlich wenn sich das mal jemand anschaut.


CodeBox BascomAVR
$regfile = "m8Adef.dat"
$crystal = 8000000
'the internal oscillator of 8 Mhz was choosen in the fusebits
Osccal = &HAE

$hwstack = 32  ' default use 32 for the hardware stack
$swstack = 40  ' default use 10 for the SW stack
$framesize = 40
  'An den Ports B.0 , B.1 und B.2 je 10k Ohm Pullup



Config Portc = Output
Config Portd = Output  'Siebensegmentanzeige
Siebensegment_kathoden Alias Portd  ' kathoden
Config Pinb.0 = Input
Config Pinb.1 = Input
Config Pinb.2 = Input  'Siebensegmentanzeige 2 Stellig
Config Pinb.3 = Output
Config Pinb.4 = Output
Config Pinb.5 = Output
Config Pinb.6 = Output
Config Pinb.7 = Output
Config Debounce = 100  ' Debounce absichtlich etwas grösser gewählt


  ' anoden
  ' Timer fuer Multiplex
Config Timer0 = Timer , Prescale = 64
On Timer0 Anzeige
Const Timervorgabe_0 = 131  ' 200 Hz / 4 Anzeigen = 50 Hz pro Anzeige
  ' Timer fuer Sekunden-Takt
Config Timer1 = Timer , Prescale = 1024
On Timer1 Zeittimer
Const Timervorgabe_1 = 3125  ' Teimer passen hier noch nicht genau !!!!

Enable Timer0
Enable Timer1
Enable Interrupts
Speaker Alias Portb.5
Dim Ziffer As Byte
'Ziffer = 0
Dim Zaehler As Byte
'Zaehler = 0
Dim Zahl As Byte
'Zahl = 0
Dim Zahl_temp As Byte
'Zahl_temp = 0
Dim Einer As Byte
'Einer = 0
Dim Zehner As Byte
'Zehner = 0
Dim Stelle As Byte
'Stelle = 0
Dim Anzahl As Byte
'Anzahl = 0
Dim Auswahl As Byte
'Auswahl = 0


Do
Debounce Pinb.0 , 0 , Press  ', Sub  'Springe nach Press: wenn B.0 null ist (Taste1)
Debounce Pinb.1 , 0 , Press2 , Sub  '  'Springe nach Press2: wenn B.1 null ist (Taste2)
Debounce Pinb.2 , 0 , Press3  ', Sub  'Springe nach Press3: wenn B.2 null ist (Taste3)
Loop
End


Press:  ' Vorgesehen für weitere Optionen
Toggle Portc.0
Sound Speaker , 400 , 50

Return

Press2:
Anzahl = Anzahl + 1
Select Case Anzahl
  Case 1 : Auswahl = 8
  Case 2 : Auswahl = 13  'Auswahl der Zahl
  Case 3 : Auswahl = 22
  Case 4 : Auswahl = 45
  Case 5 : Auswahl = 65
  Case 6 : Auswahl = 76
  Case 7 : Auswahl = 82
End Select
Zahl = Auswahl
If Anzahl = 7 Then Anzahl = 0
Toggle Portc.2  ' Toggle Portc.2 zur kontrolle
Sound Speaker , 400 , 25  ' Pipton zur kontrolle
'Wait 2

Return

Press3:
Toggle Portc.1  'Portc.1 Togglen zur kontrolle
Sound Speaker , 400 , 25  'Pipton zur kontrolle
Decr Zahl  'Zahl um 1  Decrementieren
Return

Anzeige:
Timer0 = Timervorgabe_0
Zahl_temp = Zahl  '1234
Einer = Zahl_temp Mod 10  '4

Zahl_temp = Zahl_temp - Einer  '1230
Zahl_temp = Zahl_temp / 10  '123
Zehner = Zahl_temp Mod 10  '3

Zahl_temp = Zahl_temp - Zehner  '120
Zahl_temp = Zahl_temp / 10  '12

If Stelle < 2 Then
  Incr Stelle
Else
  Stelle = 1
End If
If Stelle = 1 Then Ziffer = Einer
If Stelle = 2 Then Ziffer = Zehner

Portb.6 = 0
Portb.7 = 0

Select Case Ziffer
'  gfedcba dp
  Case 0 : Siebensegment_kathoden = &B01000000  ' auswahl des Bitmusters für 7Segment
  Case 1 : Siebensegment_kathoden = &B01111001
  Case 2 : Siebensegment_kathoden = &B00100100
  Case 3 : Siebensegment_kathoden = &B00110000
  Case 4 : Siebensegment_kathoden = &B00011001
  Case 5 : Siebensegment_kathoden = &B00010010
  Case 6 : Siebensegment_kathoden = &B00000010
  Case 7 : Siebensegment_kathoden = &B01111000
  Case 8 : Siebensegment_kathoden = &B00000000
  Case 9 : Siebensegment_kathoden = &B00010000
End Select
If Stelle = 1 Then Portb.6 = 1  ' Auswahl der Stelle
If Stelle = 2 Then Portb.7 = 1
Return

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

Ende:  ' 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


Währe für Hilfe sehr Dankbar !!
;-)
_
TR5
 
Zuletzt bearbeitet:
Dim Zahl As Byte At &H6F Overlay
Warum legst du hier eine feste Speicheradresse fest, und das auch noch als Overlay? Das kann schnell nach hinten los gehen wenn man nicht genau weiß was man tut. Gut möglich dass dein Controller zu klein ist und der Wert durch den Stack überschrieben wird (Bascom hatte ja irgendwie 3 Stacks, oder?)
Das würde dann zu für dich unreproduzierbaren Fehlern führen. Es kann natürlich auch gut gehen.

Das Problem könnte eben sein dass du selber die Speicherposition festlegst. Nicht relativ sondern absolut. Du wirst aber nie wissen ob die wirklich frei ist. Vielleicht verwendet Bascom die bei seiner Bitschubserei. Wer weiß das schon wirklich genau. Und du deklarierst es als Overlay, also sollte die Speicherzelle bereits verwendet werden bekommste weder Fehler noch Warnungen.

Sinnvoll ist das Vorhaben – finde ich – nur als Alias. Wie (Pseudocode):
Dim WortWert As Word
Dim WertHigh As Byte At (WortWert + 1) Overlay
Dim WertLow As Byte At (WortWert + 0) Overlay
halt um auf die einzelnen Bytes einer größeren Variable (word, string, …) zuzugreifen. Die vorher bereits regulär definiert ist!

Einen anderen (potentiellen) Fehler finde ich so auf die Schnelle nicht.
Aber Bascom ist auch schon etwas länger her bei mir.
 
  • Like
Reaktionen: Tschoeatsch
Hier "Dim Zahl As Byte At &H6F Overlay" war nur ein verzweifelter Versuch weil ich nicht mehr wuste was ich machen sollte!
Egal ob ich das als WORT oder BYTE deklariere immer wird die Variable auf Null zurückgesetzt.
Habe das jetzt mal geändert damit das nicht mehr berücksichtigt wird wiel das an der Tatsache nichts ändert!
Speicher vom MEga8 nur zu 15% gefüllt also Platz genug! Getestet mit BASCOM Demo V 2.0.7.3

Bedanke mich aber Trotzdem für die Antworten!:)
 
Zuletzt bearbeitet:
Das was wir beide meinten war auch eher das At ... Overlay ;)
Press2:
Anzahl = Anzahl + 1
Select Case Anzahl
Case 1 : Auswahl = 8
Case 2 : Auswahl = 13 'Auswahl der Zahl
Case 3 : Auswahl = 22
Case 4 : Auswahl = 45
Case 5 : Auswahl = 65
Case 6 : Auswahl = 76
Case 7 : Auswahl = 82
End Select
Zahl = Auswahl
If Anzahl = 7 Then Anzahl = 0
Zahl kann eigentlich nie 0 sein, außer beim ersten Durchlauf, da es immer im Bereich 1..7 gehalten wird. Vorsicht hierbei aber, da Zahl jetzt 7 ist aber Anzahl auf 0 gesetzt wird. Das kann schnell mal zu Flüchtigkeitsfehlern führen.

Auch glaube ich dass das nicht unbedingt dein Vorhaben ist, zumindest wenn ich deinen Code richtig verstehe. Zumindest möchtest du ja mit Zahl später etwas machen (wie Decrementieren und mittels Mod und / anzeigen), wo eine Wertbegrenzung 1..7 etwas kontraproduktiv wäre. Ein Increment habe ich nicht gefunden, auch keine andere Stelle die den Wert verändern könnte. 0 kann die eigentlich nur nach dem Neustart haben, oder sollte Anzahl irgendwann mal auf 8 springen. Läuft der Rest des Programms fehlerfrei? Sonst könnte die 0 vielleicht noch durch einen per Fuses gesetzten Wachhund herrühren der dich beißt und dir dein Programm resettet. Anders kann ich mir die grade nicht erklären. Aber vielleicht weiß ein anderer Spezialist hier mehr der sich mehr mit Bascom auskennt :)
 
Hi, setze mal deinen Zeittimer probehalber außer Funktion. Mit dem 'goto ende' hab' ich grad Bedenken, dass da was nicht passen könnte. Reduziere dein Programm nur auf das nötigste, wenn das geht, dann kannst du die Funktion schrittweise erweitern.
 
Ohne den eigentlichen Code durchzugehen, was meinst Du mit:
...Speicher vom MEga8 nur zu 15% gefüllt also Platz genug!...
??
Der Mega8 hat grob gesagt drei unterschiedliche Speicher.
Erstens der Programmspeicher (Program Flash), der logischerweise das Programm selbst aufnimmt (in dem aber auch Konstanten abgelegt sein können (->Data) (uU kann man auch zur Laufzeit Daten in den Flash schreiben, was hier aber zu weit geht))
Zweitens den SRAM, quasi der Arbeitsspiecher, wo üblicherweise Variablen zur Laufzeit abgelegt werden (Deine, aber auch von Bascom verwaltete Sprungadressen usw).
Drittens den EEPROM, nichtflüchtiger Speicher. Quasi 'ne Festplatte...

Hier gehts um den SRAM. Was macht nun DIM eigentlich? Mit Dim wird BASCOM angewiesen, eine Bestimmte Speicheradresse mit einem konkreten (Variablen-)Namen zu alloziieren. BASCOM (also die IDE) zählt dann intern quasi die Adressen von vorn bis hinten durch - wird ein Byte dimensioniert, wird eine Adresse "verbraucht", bei 'nem Word zwei, bei 'nem String die entsprechende Anzahl der Chars und das Nullbyte usw usw.
(das entspricht etwa der .db- bzw .dw- Assemblerdirektive)
Dim .. At verwendet die konkret angegebene Adresse - wenn die noch nicht verwendet wurde. Sonst die nächste freie.
Dim .. At .. Overlay verwendet auch eine konkrete Adresse (die allerdings durch eine andere vorher definierte Variable angegeben werden kann), die bereits verwendet werden kann (und üblicherweise auch verwendet wird). Ausserdem zählt der "Adressenzähler" von Bascom nicht weiter. Man erzeugt damit nur einen weiteren Namen, der auf dieselbe (<-Overlay) Speicherzelle (<-At) zeigt.

Was (mir) unklar bleibt, sind eventuelle Lücken bei Verwendung von Dim .. At (ohne Overlay). Bleiben die dann, oder füllen spätere Dim's die dann ggf?
Kann man mit Dim .. At .. Overlay auch in den (extended) I/O-Space alloziieren?

Zu den Stacks: (@TommyB )
Bascom verwendet AFAIK 3 Stacks
der HW-Stack entspricht quasi dem Stack in ASM, also für Rücksprungadressen, Registerrettung,...
Der SW-Stack nimmt Adressen von, an Subroutinen/Funktionen übergebenen Daten (=byReference) auf.
Der Frame nimmt direkt an Subroutinen/Funktionen übergebene Daten (=byValue) auf.
(Bei lokal definierten Variablen bin ich mir grad nicht sicher, ob die auch im Frame landen)
Da die alle im SRAM landen (und dort ggf wachsen können sollen), der SRAM aber "linear" ist, müssen vorher bestimmte Bereiche abgesteckt werden, und genau das machen die drei Direktiven im Programmkopf. Die drei Stacks liegen dann "hinten" im SRAM, von "vorn" beginnend werden mit Dim (ohne Overlay, ggf mit At) die "Variablen" festgelegt.
Läuft da irgendwas übereinander, kommts halt zu Problemen, klar.
Bascom verwendet mMn nicht selbst irgendwelche SRAM-Adressen im Hintergrund, solange man nicht irgendwelche Bibliotheken etc einbindet, oder irgendwelche Buffer (serialin etc) konfiguriert.

Der verwendete Mega8A hat 1024Bytes SRAM, von Adresse 0x0060 bis 0x045F
0x006F wäre also die sechzehnte Speicherzelle von 1024.

Das hat jetzt sicher nichts mit dem konkreten Problem zu tun, nützt abr vielleicht dem allgemeinen Verständnis...
 
Ich hätte noch einen Verdacht: könnte es sein, dass der atmega in den reset kommt, weil segment g (Querstrich in der Mitte) einen Kurzen macht, wenn das Multiplex 'drauf kommt' (schlechte Lötstelle)? Um das zu testen, mal einen Displaytest am Anfang machen, indem die Variable 'Zahl' hoch gezählt wird.
Was passiert, wenn du zahl=1 vor der do...loop setzt?
 
Hallo Uwe!

Ich habe mir deinen Code mal zu Gemüte geführt. ;)

Ein Problem habe ich mit folgender Stelle:



CodeBox BascomAVR
Zahl_temp = Zahl  '1234
Einer = Zahl_temp Mod 10  '4

Zahl_temp = Zahl_temp - Einer  '1230
Zahl_temp = Zahl_temp / 10  '123
Zehner = Zahl_temp Mod 10  '3

Zahl_temp = Zahl_temp - Zehner  '120
Zahl_temp = Zahl_temp / 10  '12



Nehmen wir mal an, "Zahl" hat von "Auswahl" den Wert 13 übergeben bekommen.....

Zahl_temp = Zahl
(13 = 13)

Einer = Zahl_temp Mod 10
(3 = 13 Mod 10)

Zahl_temp = Zahl_temp - Einer
(10 = 13 - 3)

Zahl_temp = Zahl_temp / 10
(1 = 10 / 10)

Zehner = Zahl_temp Mod 10
(1 = 1 Mod 10)

Zahl_temp = Zahl_temp - Zehner
(0 = 1 - 1)

Zahl_temp = Zahl_temp / 10
(0 = 0 / 10)



Ich hoffe, du kommst jetzt von alleine drauf wo der Fehler liegt.......
und warum du immer eine Null bekommst. ;)


Viele Grüße,
Cassio
 
Aber "Zehner" und "Einer" werden so korrekt ermittelt (und beim Multiplexing dann auch verwendet)...
Wo übersehe ich die weitere Verwendung von (dem etwas umständlich auf Null gesetzten) "Zahl_temp"?
"Zahl_temp" wird doch bei jedem Aufruf von "Anzeige" (Timerüberlauf) neu aus "Zahl" kopiert (oder ist das called by reference?)
 
Es sind ein paar Schritte zuviel drin, die es auch nicht braucht. zahl_temp mod 10 sind die Einer, fertig. zahl_temp=zahl_temp / 10 und zahl_temp mod 10 sind dann die Zehner. Mehr braucht es nicht. Im oberen Beispiel wird aber weiter gerechnet, das fett gedruckte von cassio, oder 'zahl_temp=zahl_temp - einer'

Aber weiter betrachtet stört das eigentlich nicht, weil die Ergebnisse nicht verfälscht werden. Einer und Zehner werden richtig ausgerechnet, hmmm
 
Moin Leute!

Ich verstehe irgendwie euer geschreibsel nicht....... :dirol:

So schwer ist das doch wohl nicht. :rolleyes:




Neues Beispiel:
Auswahl = 76 ( entspricht Case 6 )

Zahl = Auswahl
76 = 76


Zahl_temp = Zahl
(76 = 76)

Einer = Zahl_temp Mod 10
(6 = 76 Mod 10)

Zahl_temp = Zahl_temp - Einer
(70 = 76 - 6)

Zahl_temp = Zahl_temp / 10
(7 = 70 / 10)

Zehner = Zahl_temp Mod 10
(7 = 7 Mod 10)

Zahl_temp = Zahl_temp - Zehner
(0 = 7 - 7)

Zahl_temp = Zahl_temp / 10
(0 = 0 / 10)



Wird jetzt Licht? :hmmmm:


@Uwe
Mal ganz nebenbei....
Ich würde diese ganze Rechnerei zum Splitten der Zahlen sowieso nicht einsetzen!

Lieber die Zahl ins BCD-Format konvertieren,
dann die ersten 4 Bits in eine Variable nahmens "Einer" speichern,
anschließend die oberen 4 Bits vier mal nach rechts schieben und in einer Variable nahmens "Zehner" speichern.
Fertig! ;)


Grüße,
Cassio
 
Neues Beispiel:
Auswahl = 76 ( entspricht Case 6 )

Zahl = Auswahl
76 = 76


Zahl_temp = Zahl
(76 = 76)

Einer = Zahl_temp Mod 10
(6 = 76 Mod 10)

Zahl_temp = Zahl_temp - Einer
(70 = 76 - 6)

Zahl_temp = Zahl_temp / 10
(7 = 70 / 10)

Zehner = Zahl_temp Mod 10
(7 = 7 Mod 10)


Zahl_temp = Zahl_temp - Zehner
(0 = 7 - 7
)

Zahl_temp = Zahl_temp / 10
(0 = 0 / 10)
Und, was passt da nicht? Die blaue 0 ist doch ohne Belang. Es bleibt dunkel (bei mir jedenfalls)
 
Bezüglich der BCDs (ggf auch gepackte BCDs): macht die Konvertierung nicht genau dasselbe wie die Modulo-Divisionen? Warum nicht gleich (also bereits in den Zeilen 78..84) statt der einen Dezimalen Zahl zwei BCDs (bzw eine gepackte BCD)? Das sind immerhin drei Divisionen weniger.
(also bei Case 2 statt "13" &b00010011 zuweisen - in ASM wäre das leserlich geschrieben zB: "(1<<4)+3", 82 wäre "(8<<4)+2" - in Bascom geht das sicher auch irgendwie)
Aber ich sehe trotzdem den Fehler nicht.
Im Code aus #1 wird in Zeile 103 der Variable "Einer" der korrekte Einerwert zugewiesen,
in Zeile107 der Variable "Zehner" der Zehnerwert.
Eine dieser beiden wird dann für das Multiplexing herangezogen, daß nach dem Bestimmen der beiden Werte die nicht mehr benötigte temporäre Variable "Zahl_temp" auf 0 gesetzt wird (Zeile 108,109) , spielt doch keine Rolle mehr. Kannste dann gern auch noch lustig ein paar mal schieben und so. Das ändert doch die beiden später verwendeten Variablen "Einer" (Zeile 117) oder "Zehner" (Zeile 118) nicht.
Und beim nächsten Timerüberlauf bekommt "Zahl_temp" in Zeile 102 wieder den korrekten Wert zu Modulo-konvertieren zugewiesen...

Ich seh's nicht - ihr seid die Bascom-Profis...
 
Zuletzt bearbeitet:
Ich seh's nicht - ihr seid die Bascom-Profis...

Hallo!

Es geht nicht direkt um BASCOM......
sondern eher um Mathematik! ;)


Ich habe ja nun schon alles zwei mal beispielhaft vorgerechnet.....
und die Fehler sogar FETT geschrieben. :cool:


Ich hoffe, Uwe wird es verstehen und die richtigen Änderungen vornehmen.

Grüße,
Cassio
 
Eben, beim Beispiel aus #12 (76) kommst Du doch selbst auch auf
Einer=76 Modulo 10 = 6
Zehner= ((76-6)/10) Modulo 10= (70/10) Modulo 10 = 7 Modulo 10 =7
Danach(!) wird die temporäre Variable auf 0 gesetzt (bis das nächste mal der Timer überläuft, die Temp wieder mit Zahl beladen wird usw usw)

Einer bleibt aber 6
Zehner bleibt 7
Zahl bleibt 76
Zahl_temp wird 0 (wobei eben komplett Wurst ist, welchen Wert Zahl_temp bis zum nächsten Timerüberlauf hat - und dann bekommt es von Zahl ja wieder den (ggf neuen) korrekten Wert zugewiesen))

Beim Multiplexing wird jetzt entweder (Stelle=1 -> Ziffer = Einer=6) entsprechend Case 6 &bB00000010 auf PortD gelegt ->"6"
oder (Stelle=2 -> Ziffer=Zehner=7) entsprechend Case 7 &bB01111000 auf PortD gelegt ->"7"

stimmt doch soweit.

zwischen zwei Aufrufen der ISR vergehen 132*64=8448 Takte
hmm... vier Byte-Divisionen und einmal Register hin- und herschaufeln...

Grad noch gesehen: Das Verlassen der Zeittimer-ISR mit Goto... sowas verursacht meist ganz üble Fehler
Erfolgt der IRQ, wird automatisch die Rücksprungadresse auf den Stack gepusht (und die Interrupts global gesperrt (I gelöscht)), un der ISR dann die meisten Rechenregister und das SREG hinterher.
Durch das Return (RETI) wird das alles korrekt zurückgepopt (und de Interrupts global freigegeben)
Wird die ISR statt mit Return mit Goto verlassen, verbleibt der Krempel auf dem Stack (und die Interrupts bleiben gesperrt, konkret ist hier also sogar Zeile 149 überflüssig).
Wenn sowas hinreichend oft vorkommt, läuft der Stack irgendwann über (bei Bascom also erstmal in den SWStack, dann in den Frame, dann in den DataSpace und irgendwann in den I/O.)

Hier macht das zwar sehr wahrscheinlich keine Probleme, da die IRQs global unterdrückt sind, und außer Sound nichts mehr ausgeführt wird, danach geht der AVR schlafen bis zum nächsten Reset... aber sauber programmiert ist das nicht...
 
Danke euch LotadaC,Tschoeatsch,TommyB sehr für eure Bemühung ganz besonders Casio der mir früher schon öfters geholfen hat!:D

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. Habe schon Segmentanzeigen die wenig Stromaufnahme haben das ich die ohne Treiber direkt über den Kontroller ansteuern kann. Habe es vorher auch mit einem ATtiny 2313 versucht nur dort ist einfach zu wenig Speicher dort konnte ich schon nicht mehr in das 3. Unterprogramm springen wiel er die Rücksprung-Adresse nicht mehr speichern konnte!
Und mein Huaptproblem liegt ja nicht in der Anzeige die wird ja korrekt angezeigt und ausgewählt solange ich nur in den Unterproramm Press2 springe.
Sobald ich in den Programmteil Springe in dem die Zahl um 1 Decrementirt werden soll (Press3) bekomme ich immer 00 zurück. Es tut mir leid wenn ich mich etwas falsch ausgedrückt habe.


CodeBox BascomAVR
Press3:
Toggle Portc.1  'Portc.1 Togglen zur kontrolle
Sound Speaker , 400 , 25  'Pipton zur kontrolle
Decr Zahl  'Zahl um 1  Decrementieren
Return

LotadaC schrieb "Aber "Zehner" und "Einer" werden so korrekt ermittelt (und beim Multiplexing dann auch verwendet)..." das ist ja auch richtig dort scheint kein Fehler zu sein!
Habe auch schon Versucht Unterprogramm Press3 nur Pipton Ausgabe und Tooglen einer LED und dann wird beim Return zur Hauptprogrammschleife die Variable Zahl schon auf Null zurückgesetzt was mir einfach unverständlich ist! Da ich in Bascom nunmal noch Anfänger bin habe ich nunmal noch sehr viel Problem.

Tschoeatsch schrieb "Verdacht: könnte es sein, dass der atmega in den reset kommt, weil segment g (Querstrich in der Mitte) einen Kurzen macht"
leider ist das nicht der Fall da ja alle zahlen korrekt Angezeigt werden alle sieben auswahlzahlen funktionieren solange ich nicht in einen Anderen Programmteil Springe!
Auch nach wegnahme der Abschaltfunktion und ändern des Watchdog keine änderung des Problems.
TommyB schrieb im Post #5 "Zahl kann eigentlich nie 0 sein, außer beim ersten Durchlauf, da es immer im Bereich 1..7 gehalten wird." ist nicht ganz richtig Variable Zahl hat einen Wert von Case Anweisung, die Variable "Auswahl" hat einen Wert von 1 bis 7.

Casio "Es geht nicht direkt um BASCOM...... sondern eher um Mathematik! ;)" , leider doch weil mir mein einsprung in ein anderes Unterprogramm die Variable Zahl immer verhaut!
 
Zuletzt bearbeitet:
Danke LotadaC 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!
 
Hm…
Warum hast du denn hier:


CodeBox BascomAVR
Debounce Pinb.0 , 0 , Press  ', Sub  'Springe nach Press: wenn B.0 null ist (Taste1)
Debounce Pinb.1 , 0 , Press2 , Sub  '  'Springe nach Press2: wenn B.1 null ist (Taste2)
Debounce Pinb.2 , 0 , Press3  ', Sub  'Springe nach Press3: wenn B.2 null ist (Taste3)

manchmal das Sub weg kommentiert? Wenn ich das richtig verstehe sollte Bascom mit dem Sub ein Call machen, du musst also mit Return zurück springen, ohne Sub wäre es nur ein Jump/GoTo. Wenn man dann trotzdem returnt kann das den Stack durcheinander bringen. Aber dazu kenne ich Bascom jetzt nicht gut genug. Wäre aber etwas wo ich ansetzen würde. Aber da du das extra auskommentiert hast schätze ich mal dass du das schon probiert hattest.
http://bascom-forum.de/mediawiki/index.php/Debounce

Um BCD zu nutzen brauchst du doch kein Platz für extra Hardware. Viel mehr Speicher brauchst du auch nicht. Dezimal kannste halt pro Byte 0..255 speichern, zwingst dem AVR aber viel Rechenarbeit auf. Mit BCD kannst du 0..99 speichern (ja, streng genommen 0..FF), musst nur Maskieren und Swap'pen und kannst den Wert gleich in deine existierende Select Case für die Anzeige füttern. Dafür muss man nur beim Increment/Decrement etwas aufpassen. Aber das hat mit dem Problem nichts zu tun.

TommyB schrieb im Post #5 "Zahl kann eigentlich nie 0 sein, außer beim ersten Durchlauf, da es immer im Bereich 1..7 gehalten wird." ist nicht ganz richtig Variable Zahl hat einen Wert von Case Anweisung, die Variable "Auswahl" hat einen Wert von 1 bis 7.
Whoops, hast recht. Naja, nobody is perfect ;)
0 dürfte er ja aber trotzdem nie sein, oder hab ich noch was übersehen?
 
manchmal das Sub weg kommentiert? Wenn ich das richtig verstehe sollte Bascom mit dem Sub ein Call machen, du musst also mit Return zurück springen, ohne Sub wäre es nur ein Jump/GoTo.
TommyB hat's erkannt. 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. Die ist aber 'uralt' und irgend ein Überbleibsel von was anderem, sodass der Sprung dorthin nix mehr gewünschtes auslöst.
 

Ü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)