Hilfe Stufentimer

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Zum Anschluss der Anzeigesteuerung wären da noch die Dezimalpunkte. Diese könnten an, aus oder blinkend geschaltet sein. Die Dezimalpunkte müssen natürlich auch im Multiplexing gesetzt werden, daher erweitern wir die Timer2-ISR um diese Funktion. Das Timing des Blinkens lassen wir durch einen weiteren Timer (Timer1) erledigen. Dieser löst jede Sekunde einen Interrupt aus und bedient damit nicht nur die Dezimalpunkte, sondern kann später auch noch den Countdown Deiner Anzeige timen.

      BASCOM-Quellcode

      1. ' =====================================================================
      2. ' Double_7_Segment 3
      3. '
      4. ' Programmbeispiel zur Ansteuerung von zwei 7-Segmentanzeigen
      5. ' 7-Segment-LED Anzeigen werden im Multiplexbetrieb angesteuert
      6. '
      7. ' Codebeispiel basiert auf einer Lexikon-Veröffentlichung von "Galahat"
      8. ' im Bascomforum (Lexikoneintrag zum Thema "Lookup"),
      9. ' siehe https://bascomforum.de/lexicon/index.php?entry/50-lookup/
      10. '
      11. ' Codebeispiel basiert weiterhin auf einer Veröffentlichung von "Searcher"
      12. ' im Roboternetzforum
      13. ' siehe https://www.roboternetz.de/community/threads/70270-Wie-richtig-mit-Bascom-7-Segmentanzeige-Multiplexen
      14. ' Der Code ist experimentell und die Benutzung erfolgt auf eigene Gefahr!
      15. ' Der Sourcecode darf für den Eigenbedarf beliebig geändert werden.
      16. ' Kontakt: www.bascomforum.de "R2D2 Bastler"
      17. '
      18. ' =====================================================================
      19. ' Autor Robert Link 2022, basierend auf Code von Galahat und Searcher
      20. ' Bascom 2.0.8.5
      21. ' Version Testversion
      22. ' Pinbelegung:
      23. ' PC0 steuert Einerstelle
      24. ' PC1 steuert Zehnerstelle
      25. ' PD0 an Segment a
      26. ' PD1 an Segment b
      27. ' PD2 an Segment c
      28. ' PD3 an Segment d
      29. ' PD4 an Segment e
      30. ' PD5 an Segment f
      31. ' PD6 an Segment g
      32. ' PD7 an Dezimalpunkt DP
      33. $Regfile = "M8def.dat"
      34. $Crystal = 8000000
      35. $HWStack = 40
      36. $SWStack = 40
      37. $Framesize = 30
      38. ' --------------------------------------------------------
      39. ' Aliase und Anschlussbelegung
      40. Digit_1 Alias PortC.0 ' Digit Einerstelle
      41. Digit_2 Alias PortC.1 ' Digit Zehnerstelle
      42. Config Digit_1 = Output ' Ausgabepin als Ausgang konfigurieren
      43. Config Digit_2 = Output ' Ausgabepin als Ausgang konfigurieren
      44. Config PortD = Output ' Kompletten PortD als Ausgang konfigurieren (Segmente der Anzeige)
      45. Pin_Dezimalpunkt Alias PortD.7 ' Pin für Dezimalpunkt
      46. ' --------------------------------------------------------
      47. ' Variablen
      48. Dim Ausgabewert as Byte ' Der (zweistellige) Wert dieser Variable soll an die Segmentanzeigen ausgegeben werden
      49. Dim Einzelziffer(2) as Byte ' Byte-Array für die einzelnen Ziffern anlegen
      50. Dim Stelle as Byte ' Variable, die angibt, welches Digit beim Multiplexen eingeschaltet werden soll
      51. Dim Dezimalpunkt(2) as Byte ' Byte-Array dür die Dezimalpunkte anlegen
      52. Dim Sekunden_Tick as Bit ' Flag, welches zu jeder vollen Sekunde gesetzt wird
      53. Dim Toggle_Flag as Bit ' Flag, welches nach je einer Sekunde getoggled wird
      54. ' --------------------------------------------------------
      55. ' Konstanten
      56. Const Ausgeschaltet = 0 ' Konstante für Dezimalpunktsteuerung
      57. Const Eingeschaltet = 1 ' Konstante für Dezimalpunktsteuerung
      58. Const Blinken = 2 ' Konstante für Dezimalpunktsteuerung
      59. ' --------------------------------------------------------
      60. ' Timer 2 konfigurieren (CTC-Mode)
      61. Config Timer2 = Timer , Prescale = 1024 , Clear_Timer = 1 ' Timerticks 128us
      62. OCR2 = 78 - 1 ' Vergleichswert für ca 10 ms einstellen (78 Schritte * 128us = 9.984 us)
      63. On OC2 ISR_Timer2_Multiplex ' OC2-Interrupt konfigurieren
      64. Enable OC2 ' OC2-Interrupt zulassen
      65. ' --------------------------------------------------------
      66. ' Timer 1 konfigurieren (CTC-Mode)
      67. Config Timer1 = Timer , Prescale = 256 , Clear_Timer = 1 ' Timerticks 32us
      68. OCR1A = 31250 - 1 ' Vergleichswert für 1 sec einstellen (31250 Schritte * 32us = 1.000.000us)
      69. On OC1A ISR_Timer1_OC1A ' OC1A-Interrupt konfigurieren
      70. Enable OC1A ' OC1A-Interrupt zulassen
      71. Waitms 300
      72. Enable Interrupts
      73. ' -----------------------------------------
      74. ' Hauptprogramm
      75. ' -----------------------------------------
      76. Do
      77. Ausgabewert = 36 ' Diese Zahl soll in der Anzeige erscheinen
      78. Einzelziffer(2) = Ausgabewert / 10 ' Zehnerstelle isolieren
      79. Einzelziffer(1) = Ausgabewert Mod 10 ' Einerstelle isolieren
      80. ' Demo-Code für das Setzen des Dezimalpunktes
      81. Dezimalpunkt(1) = Eingeschaltet ' Dezimalpunkt der Einerstelle einschalten
      82. 'Dezimalpunkt(1) = Ausgeschaltet ' Dezimalpunkt der Einerstelle ausschalten
      83. 'Dezimalpunkt(1) = Blinken ' Dezimalpunkt der Einerstelle im Sekundentakt blinken lassen
      84. 'Dezimalpunkt(2) = Eingeschaltet ' Dezimalpunkt der Zehnerstelle einschalten
      85. 'Dezimalpunkt(2) = Ausgeschaltet ' Dezimalpunkt der Zehnerstelle ausschalten
      86. Dezimalpunkt(2) = Blinken ' Dezimalpunkt der Zehnerstelle im Sekundentakt blinken lassen
      87. ' Demo-Code für Aktionen, die 1x pro Sekunde ausgeführt werden sollen, z.B. Countdown
      88. If Sekunden_Tick = 1 then ' Eine weitere Sekunde ist vergangen
      89. Reset Sekunden_Tick ' Flag zurücksetzen
      90. ' Hier steht Code, der nur 1x pro sec ausgefürt werden soll
      91. End If
      92. Loop
      93. End
      94. ' ----------------------------------------------
      95. ' Diese Timer1 ISR wird alle 1000 ms aufgerufen
      96. ' ----------------------------------------------
      97. ISR_Timer1_OC1A:
      98. Set Sekunden_Tick ' Flag nach je 1 Sekunde setzen
      99. Toggle Toggle_Flag ' Flag nach je 1 Sekunde togglen
      100. Return
      101. ' ----------------------------------------------
      102. ' Diese Timer2 ISR wird ca alle 10ms aufgerufen
      103. ' Multiplexen der 7-Segment Anzeigen
      104. ' Ablauf:
      105. ' - Alle Digits abschalten
      106. ' - Die Segmente für die nun anzuzeigende Stelle setzen
      107. ' - Den Dezimalpunkt gemäß Vorgabe setzen
      108. ' - Das neue Digit einschalten
      109. ' ----------------------------------------------
      110. ISR_Timer2_Multiplex:
      111. If Stelle < 2 Then Incr Stelle Else Stelle = 1 ' Index weiterschalten zur nächsten Stelle
      112. Digit_1 = 0 ' Beide Digits abschalten (hier Digit 1)
      113. Digit_2 = 0 ' Beide Digits abschalten (hier Digit 2)
      114. PortD = Lookup(Einzelziffer(Stelle) , Ziffer_Muster) ' Lookup holt aus den Daten unter Ziffer_Muster
      115. ' das Muster, das zur Zahl in Einzelziffer(Stelle) gehört
      116. ' und setzt damit im PORTD die Segmentportpins
      117. Select Case Dezimalpunkt(Stelle) ' Prüfen, ob und wie der Dezimalpunkt dargestellt werden soll
      118. Case Ausgeschaltet : Pin_Dezimalpunkt = 0 ' Dezimalpunkt ständig an
      119. Case Eingeschaltet : Pin_Dezimalpunkt = 1 ' Dezimalpunkt ständig aus
      120. Case Blinken : Pin_Dezimalpunkt = Toggle_Flag ' Dezimalpunkt blinkt
      121. End Select
      122. Select Case Stelle ' Eine der beiden Stellen wieder unter Strom setzen
      123. Case 1 : Digit_1 = 1 ' Stelle 1 einschalten
      124. Case 2 : Digit_2 = 1 ' Stelle 2 einschalten
      125. Case Else : Digit_1 = 0 : Digit_2 = 0 ' Dieser Fall sollte niemals eintreten, dient nur zum Schutz der Displays bei Programierfehlern!
      126. End Select
      127. Return
      128. ' ----------------------------------------------
      129. ' Lookup Table für die Zifferndarstellung
      130. ' Bit: 7 6 5 4 3 2 1 0
      131. ' Seg: DP g f e d c b a
      132. ' --A--
      133. ' | |
      134. ' F B
      135. ' | |
      136. ' --G--
      137. ' | |
      138. ' E C
      139. ' | |
      140. ' --D-- DP
      141. ' ----------------------------------------------
      142. Ziffer_Muster:
      143. Data &B00111111 ' Ziffer 0
      144. Data &B00000110 ' Ziffer 1
      145. Data &B01011011 ' Ziffer 2
      146. Data &B01001111 ' Ziffer 3
      147. Data &B01100110 ' Ziffer 4
      148. Data &B01101101 ' Ziffer 5
      149. Data &B01111101 ' Ziffer 6
      150. Data &B00000111 ' Ziffer 7
      151. Data &B01111111 ' Ziffer 8
      152. Data &B01101111 ' Ziffer 9
      Alles anzeigen

      Es führen viele Weg nach Rom, dieser Code ist nur ein Beispiel dafür.
      Du hast nun eine Grundlage, auf der Du Dein weiteres Programm aufbauen kannst.

      Viel Spaß und schönes Wochende :)


      PS: Seh gerade, Mitch64 arbeitet auch an einem Code, dann hast Du sogar noch mehr Auswahl :thumbsup:

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von R2D2 Bastler ()

    • #R2D2 Bastler
      So hatte ich mir das vorgestellt. Danke für deine Mühe. Ich werde mich jetzt mit dem Code beschäftigen. Leider gibt es ein Problem bei der Darstellung
      des Ausgabewertes. Bei einem Ausgabewert von 36 wird 26, bei 3 wird 02, bei 55 wird EE, bei 13 in der ersten Anzeige Segmente b und e, in der zweiten Anzeige
      2, bei 99 in beiden Anzeigen außer Segmente c alle Segmente an, angezeigt.
    • Also meine Pinbelegung passt. ^^
      Zum Testen der Pinbelegung kannst Du mal folgendes Testprogramm aufspielen. Das Programm ist "extraeinfach" geschrieben, Du wirst ihm problemlos folgen können.
      Die Segmente müssen dabei nacheinander in der Reihenfolge a, b, c, d, e, f, g, Dezimalpunkt aufleuchten.
      So findest Du schnell den Fehler in der Verdrahtung.

      BASCOM-Quellcode

      1. ' =====================================================================
      2. ' Segment Test
      3. '
      4. ' Programmbeispiel zum Testen der Anschlussbelegung von zwei 7-Segmentanzeigen
      5. '
      6. ' Der Code ist experimentell und die Benutzung erfolgt auf eigene Gefahr!
      7. ' Der Sourcecode darf für den Eigenbedarf beliebig geändert werden.
      8. ' Kontakt: www.bascomforum.de "R2D2 Bastler"
      9. ' =====================================================================
      10. ' Autor Robert Link 2022
      11. ' Bascom 2.0.8.5
      12. ' Version Testversion
      13. ' Pinbelegung:
      14. ' PC0 steuert Einerstelle
      15. ' PC1 steuert Zehnerstelle
      16. ' PD0 an Segment a
      17. ' PD1 an Segment b
      18. ' PD2 an Segment c
      19. ' PD3 an Segment d
      20. ' PD4 an Segment e
      21. ' PD5 an Segment f
      22. ' PD6 an Segment g
      23. ' PD7 an Dezimalpunkt DP
      24. $Regfile = "M8def.dat"
      25. $Crystal = 8000000
      26. $HWStack = 40
      27. $SWStack = 40
      28. $Framesize = 30
      29. ' --------------------------------------------------------
      30. ' Aliase und Anschlussbelegung
      31. Digit_1 Alias PortC.0 ' Digit Einerstelle
      32. Digit_2 Alias PortC.1 ' Digit Zehnerstelle
      33. Config Digit_1 = Output ' Ausgabepin als Ausgang konfigurieren
      34. Config Digit_2 = Output ' Ausgabepin als Ausgang konfigurieren
      35. Config PortD = Output ' Kompletten PortD als Ausgang konfigurieren (Segmente der Anzeige)
      36. ' -----------------------------------------
      37. ' Hauptprogramm
      38. ' -----------------------------------------
      39. Do
      40. Digit_2 = 0 ' Digit Zehnerstelle ausschalten
      41. Digit_1 = 1 ' Digit Einerstelle einschalten
      42. PortD = &B00000001 ' Segment a
      43. Wait 1
      44. PortD = &B00000010 ' Segment b
      45. Wait 1
      46. PortD = &B00000100 ' Segment c
      47. Wait 1
      48. PortD = &B00001000 ' Segment d
      49. Wait 1
      50. PortD = &B00010000 ' Segment e
      51. Wait 1
      52. PortD = &B00100000 ' Segment f
      53. Wait 1
      54. PortD = &B01000000 ' Segment g
      55. Wait 1
      56. PortD = &B10000000 ' Segment Dezimalpunkt
      57. Wait 1
      58. Digit_1 = 0 ' Digit Einerstelle ausschalten
      59. Digit_2 = 1 ' Digit Zehnerstelle einschalten
      60. PortD = &B00000001 ' Segment a
      61. Wait 1
      62. PortD = &B00000010 ' Segment b
      63. Wait 1
      64. PortD = &B00000100 ' Segment c
      65. Wait 1
      66. PortD = &B00001000 ' Segment d
      67. Wait 1
      68. PortD = &B00010000 ' Segment e
      69. Wait 1
      70. PortD = &B00100000 ' Segment f
      71. Wait 1
      72. PortD = &B01000000 ' Segment g
      73. Wait 1
      74. PortD = &B10000000 ' Segment Dezimalpunkt
      75. Wait 1
      76. Loop
      77. End
      78. ' Anschluss und Pinbelegung
      79. ' Bit: 7 6 5 4 3 2 1 0
      80. ' Seg: DP g f e d c b a
      81. ' --A--
      82. ' | |
      83. ' F B
      84. ' | |
      85. ' --G--
      86. ' | |
      87. ' E C
      88. ' | |
      89. ' --D-- DP
      Alles anzeigen
    • @Fanpost2010

      Ich bin jetzt soweit mit dem Programm.
      Es ist getestet und es funktioniert auf meinem Steckbrett genau so wie du es haben wolltest - hoffe ich.
      Fehler sind ja immer möglich, hatte ha auch nicht die 7-Segment-Anzeigen wie du.

      Du kannst ja mal die Zip runter laden und in einem Verzeichnis entpacken.

      Bascom starten und im Menü -> Datei -> Projekt -> Open anwählen und in der Dateiauswahl dann die Datei 'Stufentimer.prj' öffnen.

      Lass dich nicht gleich von dem Anblick erschlagen,
      es folgen dann gleich noch ein paar erklärende Worte (nächster Post).
      Dateien
    • Fortsetzung

      Wenn du das Projekt geladen hast, sollten 7 Codefenster (Reiter) in Bascom angezeigt werden.

      Main.bas ist das Hauptprogramm.
      Hier wird typischerweise Controller Takt Stack etc definiert, so auch in Main.bas. Da das Projekt in mehrere Module aufgeteilt ist, werden die einzeln
      nachgeladen (Zeilen 32 bis 35) mit $Include.

      Im Modul Setup.inc werden die Pins für 7-Segment-Anzeige und LED etc. festgelegt.
      Im Abschnitt Kunfiguration kannst du noch Einfluss nehmen (ist aber nicht notwendig) auf die Refresh-Frequenz des Multiplexers und die Entprelldauer der Tasten.

      Im Modul Tasten.inc werden die 4 Tasten (Menu, Plus, Minus, Start) entprellt abgefragt. Mehr macht das Modul nicht.

      Das Modul Anzeige.inc kümmert sich um die MUX-Anzeige. Dort ist ein Buffer angelegt, aus dem die Routine MUX_Display() die anzuzeigenden Daten holt und auf die 7-Sehment-Anzeige ausgibt. Bei jedem Aufruf der MUX_Display wird die logisch nächste Stelle angezeigt mit dem entsprechenden Wert aus dem Buffer.
      Im Buffer liegen aber nicht Byte-Werte 0 bis 9 für die Zuffern, sondern direkt der Ascii-Code (&h30 bis &h39). Dafür ist der Buffer als String mit 2 Zeichen länge ausgelegt. Die MUX_Display() Routine greift aber über das Oberlay Array auf die einzelnen Bytes zu. Die Ascii-Werte werden direkt in der MUX_Display() dekodiert.
      Der Umweg über LookDown entfällt. Die Stringvariante hat noch den Vorteil, dass man z.B. " " für eine blanke Anzeige oder "--" für 2 Minus anzeigen kann. Das ist aber nicht in Stein gemeiselt und lässt sich auf andere Anzeigen erweitern.

      Für den einfachen Zugriff sind in dem Modul Routinen enthalten wie, MUX_SetZahl(wert), um direkt auch Zahlen in den Buffer zu schreiben.
      Mit MUX_SetDot() und MUX_ToggleDot() und MUX_ClearDots() kann auf die Punkte in den Anzeigen zugegriffen werden.

      Da die MUX_Display() aber regelmäßig aufgerufen werden muss (im Code mit 100 Hz), gibt es das Modul Timer.inc.

      Modul Timer.inc generiert das Timing und ruft selbstständig die Routine MUX_Display() auf.
      Weiterhin generiert es einen Takt 2Hz und 1Hz für das Blinken der LED und den Sekundentakt für den Timer. Alle Timings werden mit nur einem Timer (Timer2) erzeugt. Timer 0 und Timer1 ist also für deine Spielereien noch frei verfügbar.

      Damit sind alle Module beschrieben.

      Was feht ist die Steuerung, damit das alles zusammen spielt. Weil ich ein Fan von Statemachine bin, habe ich die Steuerung als Statemachine ausgeführt.
      Das findest du in dem Modul FSM.inc.

      In dem Modul sind 3 Routinen, die den Umgang mit der Steuerung, setzen und Abfragen erleichtern. Diese sind FSM_SetState um einen neuen Zustand zu setzen, FSM_GetState() um den aktuellen Zustand abzufragen und FSM_StateChanged() um abzufragen, ob sich seit letzter Abfrage der Zustand geändert hat.

      Die Steuerung selbst, wie auf Tasten zu reagieren ist, die Bearbeitung der Timer-Zeit etc ist alles übersichtlich in der Routine FSM_Steuerung() untergebracht.
      Diese Routine wird nun einfach vom Hauptprogramm in der Hauptschleife aufgerufen.

      Wie gesagt, es funktioniert bei mir perfekt.

      Solltest jetzt aber nicht einfach den Code in deine Steuerung reinspielen und den Herrgot einen guten Mann sein lassen.
      Besser wäre es, wenn du dir den Cod anschaust und versuchst diesen zu verstehen. Sonst stehst du bald wieder da und fragst nach Code.
      Esperimentiere damit rum und erweitere den Code nach deinen Wünschen und Bedürfnissen.

      Wenn du zum Code Fragen hast, dann her damit!

      Ansonsten kann dir auch R2Ds Baster helfen, er kennt meinen Programmierstil sehr gut.
    • Ich habe es ausprobiert. Da müssten noch kleine Änderungen gemacht werden. Ich werde selber versuchen es zu ändern.

      - Im Einschaltaugenblick sollen keine Striche zu sehen sein, sondern "00" auf Dauer
      - Menüpunkt 5, hier keine 30, sondern der Wert "0"
      - Menüpunkt 6, hier keine Striche sondern "00"
      - Beim Start Schaltausgang PB1 nicht "L" Signal sondern "H" Signal
    • Ich habe die Änderungen vorgenommen und der Timer läuft einwandfrei.
      Was muss alles im Code geändert werden, wenn anstelle Sekunden Stunden geschaltet werden sollen,
      geht das überhaupt? So gut kenne ich mich leider nicht aus.
      Ich könnte noch einen Timer mit 6,12,18 und 24 Std gebrauchen. Mit +- 1Std in Menüpunkt 5.
      Anzeige in Std.
      Ich weiß, es ist von mir unverschämt.