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.
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
BASCOM-Quellcode
- ' =====================================================================
- ' Double_7_Segment 3
- '
- ' Programmbeispiel zur Ansteuerung von zwei 7-Segmentanzeigen
- ' 7-Segment-LED Anzeigen werden im Multiplexbetrieb angesteuert
- '
- ' Codebeispiel basiert auf einer Lexikon-Veröffentlichung von "Galahat"
- ' im Bascomforum (Lexikoneintrag zum Thema "Lookup"),
- ' siehe https://bascomforum.de/lexicon/index.php?entry/50-lookup/
- '
- ' Codebeispiel basiert weiterhin auf einer Veröffentlichung von "Searcher"
- ' im Roboternetzforum
- ' siehe https://www.roboternetz.de/community/threads/70270-Wie-richtig-mit-Bascom-7-Segmentanzeige-Multiplexen
- ' Der Code ist experimentell und die Benutzung erfolgt auf eigene Gefahr!
- ' Der Sourcecode darf für den Eigenbedarf beliebig geändert werden.
- ' Kontakt: www.bascomforum.de "R2D2 Bastler"
- '
- ' =====================================================================
- ' Autor Robert Link 2022, basierend auf Code von Galahat und Searcher
- ' Bascom 2.0.8.5
- ' Version Testversion
- ' Pinbelegung:
- ' PC0 steuert Einerstelle
- ' PC1 steuert Zehnerstelle
- ' PD0 an Segment a
- ' PD1 an Segment b
- ' PD2 an Segment c
- ' PD3 an Segment d
- ' PD4 an Segment e
- ' PD5 an Segment f
- ' PD6 an Segment g
- ' PD7 an Dezimalpunkt DP
- $Regfile = "M8def.dat"
- $Crystal = 8000000
- $HWStack = 40
- $SWStack = 40
- $Framesize = 30
- ' --------------------------------------------------------
- ' Aliase und Anschlussbelegung
- Digit_1 Alias PortC.0 ' Digit Einerstelle
- Digit_2 Alias PortC.1 ' Digit Zehnerstelle
- Config Digit_1 = Output ' Ausgabepin als Ausgang konfigurieren
- Config Digit_2 = Output ' Ausgabepin als Ausgang konfigurieren
- Config PortD = Output ' Kompletten PortD als Ausgang konfigurieren (Segmente der Anzeige)
- Pin_Dezimalpunkt Alias PortD.7 ' Pin für Dezimalpunkt
- ' --------------------------------------------------------
- ' Variablen
- Dim Ausgabewert as Byte ' Der (zweistellige) Wert dieser Variable soll an die Segmentanzeigen ausgegeben werden
- Dim Einzelziffer(2) as Byte ' Byte-Array für die einzelnen Ziffern anlegen
- Dim Stelle as Byte ' Variable, die angibt, welches Digit beim Multiplexen eingeschaltet werden soll
- Dim Dezimalpunkt(2) as Byte ' Byte-Array dür die Dezimalpunkte anlegen
- Dim Sekunden_Tick as Bit ' Flag, welches zu jeder vollen Sekunde gesetzt wird
- Dim Toggle_Flag as Bit ' Flag, welches nach je einer Sekunde getoggled wird
- ' --------------------------------------------------------
- ' Konstanten
- Const Ausgeschaltet = 0 ' Konstante für Dezimalpunktsteuerung
- Const Eingeschaltet = 1 ' Konstante für Dezimalpunktsteuerung
- Const Blinken = 2 ' Konstante für Dezimalpunktsteuerung
- ' --------------------------------------------------------
- ' Timer 2 konfigurieren (CTC-Mode)
- Config Timer2 = Timer , Prescale = 1024 , Clear_Timer = 1 ' Timerticks 128us
- OCR2 = 78 - 1 ' Vergleichswert für ca 10 ms einstellen (78 Schritte * 128us = 9.984 us)
- On OC2 ISR_Timer2_Multiplex ' OC2-Interrupt konfigurieren
- Enable OC2 ' OC2-Interrupt zulassen
- ' --------------------------------------------------------
- ' Timer 1 konfigurieren (CTC-Mode)
- Config Timer1 = Timer , Prescale = 256 , Clear_Timer = 1 ' Timerticks 32us
- OCR1A = 31250 - 1 ' Vergleichswert für 1 sec einstellen (31250 Schritte * 32us = 1.000.000us)
- On OC1A ISR_Timer1_OC1A ' OC1A-Interrupt konfigurieren
- Enable OC1A ' OC1A-Interrupt zulassen
- Waitms 300
- Enable Interrupts
- ' -----------------------------------------
- ' Hauptprogramm
- ' -----------------------------------------
- Do
- Ausgabewert = 36 ' Diese Zahl soll in der Anzeige erscheinen
- Einzelziffer(2) = Ausgabewert / 10 ' Zehnerstelle isolieren
- Einzelziffer(1) = Ausgabewert Mod 10 ' Einerstelle isolieren
- ' Demo-Code für das Setzen des Dezimalpunktes
- Dezimalpunkt(1) = Eingeschaltet ' Dezimalpunkt der Einerstelle einschalten
- 'Dezimalpunkt(1) = Ausgeschaltet ' Dezimalpunkt der Einerstelle ausschalten
- 'Dezimalpunkt(1) = Blinken ' Dezimalpunkt der Einerstelle im Sekundentakt blinken lassen
- 'Dezimalpunkt(2) = Eingeschaltet ' Dezimalpunkt der Zehnerstelle einschalten
- 'Dezimalpunkt(2) = Ausgeschaltet ' Dezimalpunkt der Zehnerstelle ausschalten
- Dezimalpunkt(2) = Blinken ' Dezimalpunkt der Zehnerstelle im Sekundentakt blinken lassen
- ' Demo-Code für Aktionen, die 1x pro Sekunde ausgeführt werden sollen, z.B. Countdown
- If Sekunden_Tick = 1 then ' Eine weitere Sekunde ist vergangen
- Reset Sekunden_Tick ' Flag zurücksetzen
- ' Hier steht Code, der nur 1x pro sec ausgefürt werden soll
- End If
- Loop
- End
- ' ----------------------------------------------
- ' Diese Timer1 ISR wird alle 1000 ms aufgerufen
- ' ----------------------------------------------
- ISR_Timer1_OC1A:
- Set Sekunden_Tick ' Flag nach je 1 Sekunde setzen
- Toggle Toggle_Flag ' Flag nach je 1 Sekunde togglen
- Return
- ' ----------------------------------------------
- ' Diese Timer2 ISR wird ca alle 10ms aufgerufen
- ' Multiplexen der 7-Segment Anzeigen
- ' Ablauf:
- ' - Alle Digits abschalten
- ' - Die Segmente für die nun anzuzeigende Stelle setzen
- ' - Den Dezimalpunkt gemäß Vorgabe setzen
- ' - Das neue Digit einschalten
- ' ----------------------------------------------
- ISR_Timer2_Multiplex:
- If Stelle < 2 Then Incr Stelle Else Stelle = 1 ' Index weiterschalten zur nächsten Stelle
- Digit_1 = 0 ' Beide Digits abschalten (hier Digit 1)
- Digit_2 = 0 ' Beide Digits abschalten (hier Digit 2)
- PortD = Lookup(Einzelziffer(Stelle) , Ziffer_Muster) ' Lookup holt aus den Daten unter Ziffer_Muster
- ' das Muster, das zur Zahl in Einzelziffer(Stelle) gehört
- ' und setzt damit im PORTD die Segmentportpins
- Select Case Dezimalpunkt(Stelle) ' Prüfen, ob und wie der Dezimalpunkt dargestellt werden soll
- Case Ausgeschaltet : Pin_Dezimalpunkt = 0 ' Dezimalpunkt ständig an
- Case Eingeschaltet : Pin_Dezimalpunkt = 1 ' Dezimalpunkt ständig aus
- Case Blinken : Pin_Dezimalpunkt = Toggle_Flag ' Dezimalpunkt blinkt
- End Select
- Select Case Stelle ' Eine der beiden Stellen wieder unter Strom setzen
- Case 1 : Digit_1 = 1 ' Stelle 1 einschalten
- Case 2 : Digit_2 = 1 ' Stelle 2 einschalten
- Case Else : Digit_1 = 0 : Digit_2 = 0 ' Dieser Fall sollte niemals eintreten, dient nur zum Schutz der Displays bei Programierfehlern!
- End Select
- Return
- ' ----------------------------------------------
- ' Lookup Table für die Zifferndarstellung
- ' Bit: 7 6 5 4 3 2 1 0
- ' Seg: DP g f e d c b a
- ' --A--
- ' | |
- ' F B
- ' | |
- ' --G--
- ' | |
- ' E C
- ' | |
- ' --D-- DP
- ' ----------------------------------------------
- Ziffer_Muster:
- Data &B00111111 ' Ziffer 0
- Data &B00000110 ' Ziffer 1
- Data &B01011011 ' Ziffer 2
- Data &B01001111 ' Ziffer 3
- Data &B01100110 ' Ziffer 4
- Data &B01101101 ' Ziffer 5
- Data &B01111101 ' Ziffer 6
- Data &B00000111 ' Ziffer 7
- Data &B01111111 ' Ziffer 8
- Data &B01101111 ' Ziffer 9
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
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von R2D2 Bastler ()