Code Hilfe statt von 0bis99 Zählen andersrum 99-0

Thorsten_Sch

Mitglied
31. Okt. 2010
152
0
16
47
HH
Sprachen
  1. BascomAVR
Hallo Forum melde mich auch mal wieder nach langerzeit

ich brauche mal hilfe, wie macht man das das der 7Segment Zähler statt 0-99Zählt , andersrum
von 99 nach 0?



CodeBox BascomAVR
$regfile = "attiny2313.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32


Config Portb = Output    'Siebensegmentanzeige
Siebensegment_anoden Alias Portb       ' Anoden

Config Portd = Output    'Siebensegmentanzeige 2
Siebensegment_kathoden Alias Portd       ' Kathoden

' Timer fuer Multiplex
Config Timer0 = Timer , Prescale = 256
On Timer0 Anzeige
Const Timervorgabe_0 = 237       ' 200 Hz / 4 Anzeigen = 50 Hz pro Anzeige

' Timer fuer Sekunden-Takt
Config Timer1 = Timer , Prescale = 64
On Timer1 Sekundentimer
Const Timervorgabe_1 = 49911       '1 Hz

Enable Timer0
Enable Timer1
Enable Interrupts


Dim Ziffer As Byte
Dim Dezimalpunkt As Byte

Dim Zahl As Word
Dim Zahl_temp As Word
Dim Einer As Byte
Dim Zehner As Byte
Dim Hunderter As Byte
Dim Tausender As Byte
Dim Stelle As Byte

Do
                                    'Zahl wird durch Timer0 im Sekundenrhytmus gezählt

Loop
End


Anzeige:
Timer0 = Timervorgabe_0
'Zahl zerlegen in Zehner und Einer:                         Beispiel
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
Hunderter = Zahl_temp Mod 10       '2

Zahl_temp = Zahl_temp - Hunderter       '10
Zahl_temp = Zahl_temp / 10       '1
Tausender = Zahl_temp Mod 10       '1


If Stelle < 4 Then
  Incr Stelle
Else
  Stelle = 1
End If
If Stelle = 1 Then Ziffer = Einer
If Stelle = 2 Then Ziffer = Zehner
If Stelle = 3 Then Ziffer = Hunderter
If Stelle = 4 Then Ziffer = Tausender

Siebensegment_kathoden = &B11111111       'Kathoden aus

Select Case Ziffer
  Case 0 : Siebensegment_anoden = &B11101110       '0
  Case 1 : Siebensegment_anoden = &B00000110       '1  hier fängt er an 1
  Case 2 : Siebensegment_anoden = &B10111100       '2  dann hier 2
  Case 3 : Siebensegment_anoden = &B00111110       '3
  Case 4 : Siebensegment_anoden = &B01010110       '4
  Case 5 : Siebensegment_anoden = &B01111010       '5
  Case 6 : Siebensegment_anoden = &B11110010       '6
  Case 7 : Siebensegment_anoden = &B00001110       '7
  Case 8 : Siebensegment_anoden = &B11111110       '8
  Case 9 : Siebensegment_anoden = &B01011110       '9
End Select

If Stelle = 2 And Zahl < 10 Then Siebensegment_anoden = &B00000000       'fuehrende Null dunkel
If Stelle = 3 And Zahl < 100 Then Siebensegment_anoden = &B00000000       'fuehrende Null dunkel
If Stelle = 4 And Zahl < 1000 Then Siebensegment_anoden = &B00000000       'fuehrende Null dunkel

If Dezimalpunkt = Stelle Then Siebensegment_anoden = Siebensegment_anoden Or &B00000001
Portd.stelle = 0
Return


Sekundentimer:
Timer1 = Timervorgabe_1
If Zahl <= 100 Then
  Incr Zahl
Else
  Zahl = 99 >= 0
End If
Return
End


Ich brauch auch die hilfe für das was ich gern möchte
einnen Coundown Zähler von
30Min
20Min
10Min
10 - 0 Sekunden

3x tasten:
taste 1 ( zeit einstelllen )
taste 2 ( Vohr Zählen oder zurück )
taste 3 ( Go )

Ich bitte um Hilfe Bitte
 
Hmmm....
Ich würde ganz pragmatisch 99 - akt. Zähler rechnen und diesen Wert ausgeben.
73 addi
 
Wenn nötig Zahl auf den Startwert setzen und Decr statt Incr nutzen.
Dann halt auf 0 prüfen.

Die Syntax hinter


CodeBox BascomAVR
Zahl = 99 >= 0

erschließt sich mir jetzt nicht...

Alternativ möglich wäre natürlich auch der Weg von @addi.
 
Man könnte statt inkrementieren/dekrementieren auch einfach "1" oder "-1" addieren. Also 'ne Variable definieren, und die durch den Taste 2 auf "1" oder "-1" setzen lassen.
In der Zählschleife wird dann einfach diese Variable zum Zähler addiert. Ist das Ergebnis 100 wird es auf 99 korrigiert, ist es 255 wird es auf 0 korrigiert.

Was mich noch stören würde (einfach aus Ehrgeiz) ist diese Dezimalstellenzerhackerei in den Zeilen 49..63 (Modulo und "\" ist quasi dieselbe Division nur mit anderer Rückgabe - wenn man bei der Division den Rest (der bleibt da nämlich irgendwo(!) übrig) mitverwenden kann, reduziert sich das ganze auf drei Divisionen (und ein paar Zuweisungen). Hatten wir hier schonmal irgendwo...
Hab irgendwie gerade Register24 im Hinterkopf... Hmm...
 
Ich würde mit flags arbeiten. In der sub 'Sekundentimer' wird alle Sekunde ein flag gesetzt. In der main wird mit den Tasten der Startwert eingestellt und mit der Taste 'go' wird in ein Unterprogramm gesprungen. Hier wird dieses Sekundenflag abgefragt. Ist es da, wird der Startwert decrementiert und der Variablen 'Zahl' übergeben, die ja angezeigt wird. Dann muss noch auf 0 überprüft werden, um das Ende des countdowns zu erkennen. Jetzt muss das Sekundenflag natürlich wieder zurück gesetzt werden und man wartet, bis es vom Sekundentimer wieder gesetzt wird.
 
Fiel mir auch auf. Wäre vielleicht sinniger gleich mit BCD zu arbeiten.
Ein paar Funktionen hat Bascom dafür ja schon drin. So würde man sämtliche Divisionen einsparen.

Pseudocode (ungetestet, Prinzip sollte aber klar sein):


CodeBox BascomAVR
Function BCD_Inc(Value As Byte) As Byte
    Value += 1 ' Wert erhöhen
    If Value And 0x0F = 0x0A Then ' Auf Einser Überlauf testen
        Value += 0x05 ' Zehner erhöhen
    End If
    If Value And 0xF0 = 0xA0 Then ' Auf Zehner Überlauf testen
        Value = 0x00 ' Auf BCD 00 zurück setzen
    End If
    Return Value
End Function
Function BCD_Dec(Value As Byte) As Byte
    Value -= 1 ' Wert um 1 verringern
    If Value And 0xF0 = 0xF0 Then ' Auf Zehner Überlauf testen
        Value = 0x99 ' Auf BCD 99 zurück setzen (ggf. hier den Maximalwert nehmen)
    End If
    If Value And 0x0F = 0x0F Then ' Auf Einser Überlauf testen
        Value -= 0x05 ' Zehner auf 9
    End If
    Return Value
End Function

Dies ist jetzt nur für ein Byte, reicht bei Uhrzeit und Daten aber ja aus, tendenziell sind h, m und s ja selten 3stellig anzutreffen ;)
 
Das pollen eines Sekundenflags ist natürlich unabhängig davon ob man eigene Routinen für jede Richtung nimmt, oder eine für beide.
An 'n Zählwerk für jede Stelle hatte ich auch schon gedacht.
Unschön sind noch zwei Sachen:
  1. Die Rechnerei bei jedem Aufruf von "Anzeige" (also im Multiplexing -> da ändert sich ja meist nichts -> kann im Sekundentakt miterledigt werden)
  2. Die Konvertierung der Ziffer in die LED-Darstellung mittels Case-Kostrukt -> das geht mit 'nem Array einfacher
 
So habe es geschaft bissen geändert in diesen code und zählt rückwärts und blink dann 2 mal und fängt wieder an



CodeBox BascomAVR
$regfile = "attiny2313.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32



Config Portd.0 = Input   'PD0 - Ein_1
Portd.0 = 1
Taster Alias Pind.0

Config Portb = Output
Segment_anoden Alias Portb

Dim Ziffer As Byte
Dim Dezimalpunkt As Bit
Dim I As Byte


Do
For Ziffer = 9 To 0 Step -1
'For Ziffer = 0 To 9
  Gosub Anzeige
  Wait 1
Next Ziffer

Segment_anoden = 0
Wait 1

Ziffer = 0               '0
Dezimalpunkt = 1
Gosub Anzeige
Wait 1

Segment_anoden = 0
Dezimalpunkt = 0
Wait 1

Loop
End

Anzeige:
Select Case Ziffer
  Case 0 : Segment_anoden = &B11101110       '0
  Case 1 : Segment_anoden = &B00000110       '1  hier fängt er an 1
  Case 2 : Segment_anoden = &B10111100       '2  dann hier 2
  Case 3 : Segment_anoden = &B00111110       '3
  Case 4 : Segment_anoden = &B01010110       '4
  Case 5 : Segment_anoden = &B01111010       '5
  Case 6 : Segment_anoden = &B11110010       '6
  Case 7 : Segment_anoden = &B00001110       '7
  Case 8 : Segment_anoden = &B11111110       '8
  Case 9 : Segment_anoden = &B01011110       '9
End Select
If Dezimalpunkt = 1 Then Segment_anoden = Segment_anoden Or &B00000001
Return


wie oder was muss geändert werden das der bei 0 stehn bleibt?
 
Hallo irgendwie hilft mir das nicht hänge oder kapier es nicht gibt es noch andere tipps.

Ich bitte um rat und HILFE
 
oder kapier es nicht gibt es noch andere tipps.
Was ist denn jetzt das konkrete Problem?
was muss geändert werden das der bei 0 stehn bleibt?
Du hast 'ne Do-Loop-Endlosschleife von Zeile 21 bis 40.
Darin läßt Du bei jedem Durchlauf:
  1. Den Countdown im Sekundetakt anzeigen (For-Schleife von 22..26)
  2. leeres Display (28,29)
  3. DP anzeigen (31..34)
  4. leeres Display (36..38)
Do..Loop bis in alle Ewigkeit (oder bis der Strom weg ist).
Wenn Du was anderes willst, mußt Du was anderes implementieren.
Und wenn wir Dir dazu Hinweise geben sollen, mußt Du uns erstmal sagen, WAS Du konkret (anders) haben willst.

P.S.: Das End in Zeile 41 ist toter Code. Es wird in eine leere Endlosschleife übersetzt (der Controller würde dort quasi endlos auf der Stellle hüpfen) - Der Bereich wird aber nie vom Programm erreicht.
(eben wegen der vorherigen, nicht leeren Endlosschleife)
Das hat aber nichts mit Deinem (scheinbaren) Problem zu tun - ist nur sinn-/nutzloser Code. Verschenkter Flash.
 

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