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

Dieses Thema im Forum "AVR-Projekte" wurde erstellt von Thorsten_Sch, 2. Juni 2018.

  1. Thorsten_Sch

    Thorsten_Sch Mitglied

    Registriert seit:
    31. Oktober 2010
    Beiträge:
    147
    Zustimmungen:
    0
    Punkte für Erfolge:
    16
    Sprachen:
    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
     
  2. addi

    addi Mitglied

    Registriert seit:
    2. September 2013
    Beiträge:
    105
    Zustimmungen:
    3
    Punkte für Erfolge:
    18
    Sprachen:
    BascomAVR, C, Assembler
    Hmmm....
    Ich würde ganz pragmatisch 99 - akt. Zähler rechnen und diesen Wert ausgeben.
    73 addi
     
  3. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.703
    Zustimmungen:
    57
    Punkte für Erfolge:
    48
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    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.
     
  4. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.979
    Zustimmungen:
    45
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    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...
     
  5. Tschoeatsch

    Tschoeatsch Mitglied

    Registriert seit:
    24. Oktober 2015
    Beiträge:
    101
    Zustimmungen:
    11
    Punkte für Erfolge:
    18
    Sprachen:
    BascomAVR
    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.
     
  6. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.703
    Zustimmungen:
    57
    Punkte für Erfolge:
    48
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    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 ;)
     
  7. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.979
    Zustimmungen:
    45
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    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
     
  8. Thorsten_Sch

    Thorsten_Sch Mitglied

    Registriert seit:
    31. Oktober 2010
    Beiträge:
    147
    Zustimmungen:
    0
    Punkte für Erfolge:
    16
    Sprachen:
    BascomAVR
    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?
     
  9. Thorsten_Sch

    Thorsten_Sch Mitglied

    Registriert seit:
    31. Oktober 2010
    Beiträge:
    147
    Zustimmungen:
    0
    Punkte für Erfolge:
    16
    Sprachen:
    BascomAVR
    Hallo irgendwie hilft mir das nicht hänge oder kapier es nicht gibt es noch andere tipps.

    Ich bitte um rat und HILFE
     
  10. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.979
    Zustimmungen:
    45
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    Was ist denn jetzt das konkrete Problem?
    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

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren und die Seite optimal für dich anzupassen. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden