Elektronik-Projekt: Elektronischer Adventkranz


zurück zu Elektronik, Homepage

Adventkranz im Betrieb

3. Softwarebeschreibung

Die Aufgabe der Software für den PIC-Mikrocontroller besteht beim elektronischen Adventkranz hauptsächlich in der Erzeugung sehr vieler Flackerlichter (52 mal für jede Leuchtdiode, die den Kranz bilden, und vier für die vier Flammen der Kerzen) die in einem Array (Vektor, Abbildung 3.1) abgelegt sind, und in der Erzeugung eines seriellen Datenstromes für Ausgabe dieses Arrays (Vektors) durch die Schieberegister IC2 bis IC9 (vgl. Abschnitt Abschnitt 2 (Schaltungsbeschreibung).).

Die Abbildung 3.1 zeigt wie das Array Flackerlichter[] aufgebaut ist.

Array Flackerlichter
Wichtig:
Die Zuordnung der Bits im Array für die vier Kerzen (bestehend aus je einem Bit für die Flamme und einem Bit für das Wachs) und für den Kranz muss der Beschaltung der Schieberegister gemäß der Schaltung in Abbildung 2.2 entsprechen.

Daher ist in Abbildung 3.1 zu jedem Arrayelement auch das zugehörige Schieberegister angegeben. Zur Besseren Übersicht sind die Bits, die den Leuchtdioden entsprechen in deren Farben dargestellt (gelb: Flamme, rot: Wachs und grün: Kranz).

Der Kranz flackert sofort nach dem Einschalten, während eine Kerze erst nach einer Betätigung der zur Kerze zugehörigen Tasters eingeschaltet und durch einen weiteren Tastendruck wieder ausgeschaltet wird. Eine wichtige Aufgabe der Software ist daher auch das Erkennen ob, und welche Taste gedrückt wurde. Diese Aufgabe muss regelmäßig durchgeführt werden und erfolgt mit dem Unterprogramm TastenRoutine. Siehe Abschnitt 3.4.2. (Unterprogramm zur Tastenabfrage).

Manche Unterprogramme müssen zyklisch (also regelmäßig) aufgerufen werden. Dazu sind mehrere Zeitbasen notwendig. Diese werden mit Hilfe des Timer-Interrupts erzeugt (siehe Abschnitt 3.2. Hauptprogramm und Abschnitt 3.3. Interrupt-Service-Routine (ISR, Timer 0).

Die in der Schaltung vorgesehenen Jumper (JP1 und JP2) sind für zukünftige Optionen und Erweiterungen vorgesehen. In dieser Version werden diese nicht benötigt.

Zur besseren Übersicht ist der Quellcode in mehrere Dateien aufgeteilt:

Als Programmiersprache wurde hier C, und als Compiler mikroC von [mikroElektronika 2009] verwendet.

nach oben

3.1. Globale Register, Portdefinitionen, Konstanten und Tabellen

Globale Register:
Für die Erzeugung der zwei Zeitbasen (hier für 409.6µs und 10ms) sind die folgenden zwei globalen Register notwendig:

Globale Register

Weitere globale Register werden auch für die Erzeugung der Flackerlichter benötigt (siehe Abschnitt 3.4.3. Konstanten, globale Variablen, Tabellen und Unterprogramme zur Erzeugung der Flackerlichter).

Portdefinitionen:
Im Allgemeinen werden bei jeder Anwendung die Ein- und Ausgangspins der diversen Hardwarekomponenten (hier Jumper, Taster und die Schieberegister) an einem anderen Portpin verwendet. Damit dies in der Software nur an einer Stelle berücksichtigt werden muss, befindet sich in der Software eine Portdefinition.

Portdefinition für die Jumper:
Die Jumper (JP1 und JP2) werden zwar hier noch nicht verwendet, eine Portdefinition ist aber schon vorgesehen (Zeilen 49 und 50).

Portdefinition für die Taster und Schieberegister:
Für die Taster ist keine Portdefinitionen notwendig. Die Portdefinition für die Steuerleitungen zur Ansteuerung der Schieberegister befindet sich in der Datei SR_74XX595.H (siehe Abschnitt 3.4.4. Portdefinitionen und Unterprogramme zur seriellen Datenausgabe mit den Schieberegistern vom Typ 74xx595).

Portdefinitionen

Konstanten:
Die Konstante KONSTZEITBASIS10MS gibt die Anzahl der notwendigen Interrupt-Aufrufe für die 10-ms-Zeitbasis an. Hier, beim elektronischen Adventkranz, wird die Interrupt-Service-Routine (ISR) alle 409.6$\mu$s aufgerufen, daher ergibt sich für die Konstante der Wert 24 (24 x 409.6µs = 9.83ms = ca. 10ms).

Konstanten

Konstanten werden auch für die Erzeugung der Flackerlichter benötigt (siehe Abschnitt 3.4.3. Konstanten, globale Variablen, Tabellen und Unterprogramme zur Erzeugung der Flackerlichter).

Tabellen:
Tabellen werden nur für die Erzeugung der Flackerlichter benötigt. Mehr dazu im Abschnitt 3.4.3. Konstanten, globale Variablen, Tabellen und Unterprogramme zur Erzeugung der Flackerlichter.

nach oben

3.2. Hauptprogramm

Zuerst müssen der Mikrocontroller und die (globalen) Register für die Erzeugung der Flackerlichter initialisiert werden. Diese Aufgaben werden von den Unterprogrammen Init (Zeile 323) und Init_Flackerlichter (Zeile 326) ausgeführt.

Nun befindet sich das Hauptprogramm in einer Endlosschleife. Diese Schleife besitzt die Aufgabe ständig die so genannten Botschaftsflags abzufragen. Ist eines dieser Botschaftsflags gesetzt, so muss vom Hauptprogramm eine bestimmte Aufgabe ausgeführt werden. Diese Aufgaben sind in Form von Unterprogrammen vorhanden.

Hier die Tätigkeiten in der Endlosschleife, welche durch die Botschaftsflags ausgelöst werden:

Achtung:
Die Botschaftsflags müssen nach der Ausführung der Aufgaben wieder gelöscht werden, da diese Aufgaben sonst ununterbrochen wiederholt werden!

Listing 3.4 zeigt das Hauptprogramm (Auszug aus Adventkranz.c).

Hauptprogramm
nach oben

3.3. Interrupt-Service-Routine (ISR, Timer 0)

Eine Interrupt-Service-Routine (kurz: ISR) ist im Prinzip ein Unterprogramm, welches aber im Gegensatz zu normalen Unterprogrammen "unvorhergesehen" aufgerufen wird. Hier, beim Timer-0-Interrupt jedes Mal wenn der Timer 0 überläuft, also von 255 auf 0 wechselt. Würde zum Beispiel ein RB-Interrupt verwendet werden, so würde bei jeder Pegeländerung von RB4 bis RB7 ein Interrupt auftreten und die entsprechende ISR wird ausgeführt. Eine ISR sollte so kurz wie möglich sein.

Ein wichtiger Punkt bei einer ISR ist, dass das w-Register (Working- oder Arbeitsregister) und das STATUS-Register in andere Register zwischengespeichert werden müssen, falls diese Register in der ISR ihre Registerinhalte verändern. Der Grund dafür ist, dass eine ISR eben unvorhergesehen aufgerufen wird, und die angesprochenen Register unter Umständen zu diesen Zeitpunkten gerade benötigte Werte enthalten. Nach Ausführung der ISR springt diese zwar wieder genau an die Stelle zurück, wo sie war, bevor der Interrupt auftauchte, aber mit einem möglicherweise falschen Wert im w-Register (bzw. STATUS-Register). Das Zwischenspeichern des w-Register bzw. des STATUS-Registers wird häufig auch als PUSH bezeichnet. Das Wiederherstellen von w-Register und STATUS-Register nennt man POP. Diese Aufgaben werden vom mikroC-Compiler automatisch erledigt, so dass sich der Programmierer darüber keine Gedanken machen muss.

Woher weiß das Programm, dass ein Interrupt aufgerufen werden muss? Dazu gibt es für jede Interruptquelle ein Kontroll-Flag. Dies wird vom Controller gesetzt wenn dieser Interrupt auftritt. (Vorausgesetzt, dass diese Interruptquelle freigegeben wurde). Damit aber die ISR nicht ständig aufgerufen wird, muss dieses Bit in der ISR wieder gelöscht werden.

Nun aber zur projektspezifischen Timer 0-ISR. Diese hat lediglich die Aufgabe eine Zeitbasis für 409.6µs und eine zweite für ca. 10ms zu erzeugen. Damit eine Zeit von 10ms entsteht muss die ISR 24-mal aufgerufen werden (24 x 409.6µs = 9.83ms). Bei jedem ISR-Aufruf muss daher ein Zählregister (hier: ZaehlerZeitbasis10ms) um 1 vermindert werden. Besitzt es danach den Wert 0, so ist eine Zeit von ca. 10ms vergangen. Nun wird das Botschaftsflag FlagZeitbasis10ms im Register FlagISRHP gesetzt, und das Zählregister muss mit dem Wert 24 neu geladen werden. Der Wert 24 wird hier durch die Konstante KONSTZEITBASIS10MS ersetzt.

Anmerkung:
Die 10ms-Zeitbasis wird für das regelmäßige Abfragen der Taster benötigt, während die 409.6$µs für das erzeugen von Flackerlicht benötigt wird.

Die Zeit von 409.6µs ergibt sich, weil als Taktquelle ein 20-MHz-Quarz (X1) verwendet wird, und weil der Vorteiler (VT) mit dem Wert 1:8 (TMR0 Rate, Zeile 120 im Unterprogramm Init) geladen wird. Für diese Zeit gilt:

Formel ISR

Listing 3.5 zeigt die kurze Interrupt-Service-Routine (Auszug aus Adventkranz.c).

Interrupt-Service-Routine
nach oben

3.4. Unterprogramme

Die insgesamt 10 Unterprogramme lassen sich wie folgt einteilen:

nach oben

3.4.1. Unterprogramm zur Initialisierung des PIC (Init)

Das Unterprogramm Init dient zur Initialisierung des Mikrocontroller und muss daher am Beginn des Hauptprogramms aufgerufen werden.

Da die Interrupt-Service-Routine (ISR) zyklisch (alle 409.6µs) aufgerufen wird, ist eine entsprechende Zeitbasis notwendig. Diese wird mit Hilfe eines Timer-Interrupts erzeugt. Für die Definition der Zeitbasis ist hier das mikrocontrollerinterne Funktions-Register OPTION zuständig. Damit bei einer PIC-Taktfrequenz von 20MHz eine Zeitbasis von 409.6µs erzeugt wird, muss das Register OPTION mit dem binären Wert bxxxx0010 geladen werden (Zeile 126). Das Zählregister für diese Zeitbasis (Funktions-Register TMR0) muss gelöscht werden (Zeile 124).

Die beiden Ports (beim PIC16F87 die Ports A und B) müssen gemäß der Beschaltung nach Abbildung 2.1 entweder als Eingang oder als Ausgang definiert werden (Zeilen 155 und 165).

Achtung:
Der PIC16F87 verfügt über analoge Komparatoren. Diese werden bei diesem Projekt nicht verwendet und müssen daher deaktiviert werden (Zeilen 177 und 178).

Das Zählregister für die 10ms-Zeitbasis muss initialisiert werden (Zeile 181).

Zum Schluss werden der Timer0-Interrupt und der globale Interrupt freigegeben (Zeile 184) [1]. Für das Freigeben der Interrupts ist hier das Register INTCON zuständig. Je nach benötigten Interrupts müssen die Freigabebits (im Englischen: Enable) gesetzt werden. (Hier das Freigabebit T0IE (Bit 5) für den Timer 0.) Zusätzlich muss auch die globale Interruptfreigabe GIE (General Interrupt Enable, Bit 7) gesetzt werden. Er ist sozusagen der Hauptschalter, der Interrupts ermöglicht. Der Timer-0-Interrupt ist nun eingeschaltet und sorgt hier für eine 409.6-µs-Zeitbasis.

Listing 3.6 zeigt das Unterprogramm zur Initialisierung des PIC16F87 (Auszug aus der Datei Adventkranz.c).

Init (Teil 1)
Init (Teil 2)
nach oben

3.4.2. Unterprogramm zur Tastenabfrage (TastenRoutine)

Das Unterprogramm TastenRoutine hat die Aufgabe regelmäßig zu prüfen, ob und welche Taste gedrückt wurde. Wurde eine Taste gedrückt die dazugehörige Kerze ein- bzw. ausschalten. Dieses Unterprogramm wird daher zyklisch (ca. alle 10ms) vom Hauptprogramm aufgerufen.

Die Taster sind nach Abbildung 2.1 an den folgenden Portpins angeschlossen:

Vorgehensweise:

  1. Port B einlesen und im Register temp1 sichern
  2. Dieses Register invertieren und in temp2 sichern (temp1 wird später noch einmal benötigt und darf daher nicht überschrieben werden!)
  3. Das Register TastenAlt gibt beim Aufruf (dieses Unterprogramms) den Zustand der Tasten an, der beim vorhergehenden Aufruf dieses Unterprogramms am Port B herrschte. Also den Zustand am Port B vor ca. 10 ms.
  4. Mit Hilfe der beiden Register temp2 und TastenAlt lässt sich somit ermitteln, ob eine bestimmte Taste zwischen dem vorhergehenden Aufruf dieses Unterprogramms und den gerade bearbeitenden Aufruf gedrückt wurde. Dies erfolgt mit einer bitweisen logischen-UND-Verknüpfung. Das Ergebnis dieser UND-Verknüpfung im Register TastenStatus sichern. Mit diesem Verfahren wird auch gleichzeitig das so genannte Tastenprellen überbrückt, da dieses Tastenprellen in der Regel weit weniger als 10ms dauert.
  5. Je nachdem welche Taste nun gedrückt wurde, das entsprechende Bit im Register TastenStatus ist gesetzt, diese Kerze ein bzw. ausschalten (also invertieren).
  6. Register TastenAlt mit dem Inhalt von temp1 für den nächsten Unterprogrammaufruf laden.

Der Rückgabewert dieses Unterprogramms beinhaltet nun für jede Kerze den Status ob die Kerze eingeschaltet oder ausgeschaltet ist.

Anmerkungen:

Listing 3.7 zeigt das Unterprogramm zur Tastenabfrage (Auszug aus Adventkranz.c).

Tastenroutine (Teil 1)
Tastenroutine (Teil 2)
nach oben

3.4.3. Konstanten, globale Variablen, Tabellen und Unterprogramme zur Erzeugung der Flackerlichter

Das Prinzip zur Erzeugung von Flackerlicht ist im Abschnitt 1 (Grundlegendes zur Erzeugung von Flackerlicht) sehr ausführlich erklärt. Hier erfolgen nun die Besonderheiten bei diesem Projekt.

Ein wichtiger Punkt bei der Erzeugung mehrerer Flackerlichter ist, dass der Eindruck entsteht, dass die Leuchtdioden unabhängig voneinander flackern. Dies wird erreicht, indem für jede Leuchtdiode eine eigene Zählvariablen verwendet wird. Diese Zählvariable muss hier als globale Variable ausgeführt werden.

Sämtlicher Quellcode, der für die Erzeugung der Flackerlichter notwendig ist (also Konstanten, globale Variablen, Tabellen und Unterprogramme) befindet sich in einer eigenen Datei Namens Flackerlicht.C (Quellcode) bzw. Flackerlicht.H (Header).

Konstanten:
Gemäß Abschnitt 1 sind für die Erzeugung der Flackerlichter die beiden Konstanten KONST_PWM_OBERGRENZE (beinhaltet den Wert 32) und KONST_GLEICHHEIT (beinhaltet den Wert 5) notwendig. Diese werden in der Header-Datei Flackerlicht.H definiert (Listing 3.8):

Konstanten fuer Flackerlichter

Globale Variablen:
Damit die vielen Leuchtdioden unabhängig voneinander flackern sind für jede Leuchtdiode zwei globale Variablen notwendig (Listing 3.9). Diese Variablen sind hier als Array definiert und entsprechen den Registern TabFlackerlicht und PWM_LED aus Abschnitt 1.

Globale Variablen fuer Flackerlichter

Tabellen:
Für die Erzeugung der vielen Flackerlichter sind eine Reihe von Tabellen (Listing 3.10) notwendig. Die erste Tabelle (TabFlackerlicht, Zeilen 27 bis 45) beinhaltet die Werte für die Puls-Weiten-Modulation. Diese Tabelle wurde bereits im Abschnitt 1 ausführlich diskutiert.

Die weiteren Tabellen sind notwendig damit die Flackerlichter für die vier Kerzen und für den Kranz mit Hilfe von Schleifen schnell und einfach ausgeführt werden können.
Die Tabellen TabKerzeTabstart (Zeilen 49 bis 52) und TabKranzTabstart (Zeilen 54 bis 60) geben für jede Leuchtdiode den Startwert für die Tabelle TabFlackerlicht an. Dadurch erscheint der Eindruck, dass die Leuchtdioden unabhängig voneinander flackern. In Wirklichkeit ist der Flackerzyklus für jede Leuchtdiode gleich, sie sind nur zeitlich verschoben.
Die Tabelle TabKerzeInLEDZustand (Zeilen 64 bis 67) gibt an, in welchem Array-Elemet (vom Array Flackerlichter) sich die Kerze mit dem Index i befindet. Dies ist notwendig, weil die Flackerlichter für die Kerzen mit Hilfe einer Schleife erfolgt. Da die Bit-Nummern für die vier Kerzen gleich sind [2] ist für die Bitinformation keine Tabelle notwendig. (Siehe auch Unterprogramm FlackerlichtKerzen, Listing 3.12.
Die Tabellen TabKranzInLEDZustand (Zeilen 69 bis 75) und TabKranzInLEDZustandBit (Zeilen 77 bis 83) geben an, welches Array-Element und welches Bit der Leuchtdioden für den Kranz mit dem Index i entspricht.

Tabellen fuer Flackerlichter (Teil 1)
Tabellen fuer Flackerlichter (Teil 2)

Unterprogramme:
Für die Erzeugung der Flackerlichter sind drei Unterprogramme notwendig, wobei ein Unterprogramm die Flackerlichter für die vier Kerzen erzeugt, während die Flackerlichter für den Kranz von einem anderen Unterprogramm erzeugt werden. Dies ist auch sinnvoll, da der Kranz von Beginn an flackert, während das Flackern der Kerzen davon abhängt, ob die Kerze ein- oder ausgeschaltet ist.
Ein weiteres Unterprogramm initialisiert die globalen Variablen, die für die Erzeugung der Flackerlichter notwendig sind.

Unterprogramm Init_Flackerlichter:
Dieses kurze Unterprogramm hat nur die Aufgabe die Zählregister mit den Anfangspositionen zu initialisieren. Listing 3.11 zeigt dieses kurze Unterprogramm.

Anmerkung:
Dieses Unterprogramm wird im Hauptprogramm nach dem Initialisieren des Mikrocontrollers aufgerufen (Siehe Hauptprogramm, Listing 3.4, Zeile 326).

Unterprogramm Init_Flackerlicht

Unterprogramm Flackerlicht_Kerzen:
Dieses Unterprogramm erzeugt das Flackern (Puls-Weiten-Modulation, PWM) für die Kerzen, indem es die Bits 0 (Flamme) und 1 (Wachs) im übergebenen Array mit Hilfe der Tabelle TabKerzeInLEDZustand setzt oder zurücksetzt.
Es entspricht vom Prinzip her dem Listing aus Abschnitt 1 (Grundlegendes zur Erzeugung von Flackerlicht).

Die wesentlichen Unterschiede gegenüber Abschnitt 1 sind:

  1. Dieses Unterprogramm erzeugt gleichzeitig vier Flackerlichter (daher die Verwendung von Schleifen).
  2. Das Setzen der Bits für die Flamme und für das Wachs erfolgt nur wenn die Kerze aktiviert (eingeschaltet) ist.

Dieses Unterprogramm benötigt als Übergabeparameter einen Zeiger auf das Array und ein Register, welches angibt welche Kerze ein- bzw. ausgeschaltet ist. (Anmerkung: Dieses Register entspricht dem Rückgabewert vom Unterprogramm TastenRoutine.)

Wichtig:
Dieses Unterprogramm muss im Hauptprogramm regelmäßig (zyklisch) aufgerufen werden (Siehe Hauptprogramm, Listing 3.4, Zeile 333).

Listing 3.12 zeigt die Realisierung von diesem Unterprogramm.

Unterprogramm Flackerlicht_Kerzen (Teil 1)
Unterprogramm Flackerlicht_Kerzen (Teil 2)

Unterprogramm Flackerlicht_Kranz:
Dieses Unterprogramm erzeugt das Flackern (Puls-Weiten-Modulation) für den Kranz, indem es die Bits im übergebenen Array mit Hilfe der Tabellen TabKranzInLEDZustand und TabKranzInLEDZustandBit setzt oder rücksetzt.

Auch dieses Unterprogramm entspricht vom Prinzip her dem Listing aus Abschnitt 1 (Grundlegendes zur Erzeugung von Flackerlicht). Der wesentliche Unterschied gegenüber Abschnitt 1 ist nur, dass dieses Unterprogramm "gleichzeitig" 52 Flackerlichter erzeugt. Daher die Verwendung von Schleifen.

Als Übergabeparameter ist hier nur ein Zeiger auf das Array notwendig.

Wichtig:
Auch dieses Unterprogramm muss im Hauptprogramm regelmäßig (zyklisch) aufgerufen werden (Siehe Hauptprogramm, Listing 3.4, Zeile 334).

Listing 3.13 zeigt die Realisierung von diesem Unterprogramm.

Unterprogramm Flackerlicht_Kranz
nach oben

3.4.4. Portdefinitionen und Unterprogramme zur seriellen Datenausgabe mit den Schieberegistern vom Typ 74xx595

Die Ansteuerung der Leuchtdioden erfolgt bei diesem Projekt mit Hilfe von Schieberegistern. Die softwaretechnische Ansteuerung der Schieberegister erfolgt mit Hilfe von zwei Unterprogrammen, die in einer eigenen Datei (hier SR_74XX595.C) vorhanden sind.

Protokoll zur Kommunikation mit den Schieberegistern:
Die Abbildung 3.2 zeigt das sehr einfache Protokoll zur Kommunikation mit den Schieberegistern vom Typ 74xx595, und die Reihenfolge, in welcher die Array-Elemente in die Schieberegister geschoben werden müssen, damit die "richtigen" Leuchtdioden angesteuert werden.

Serielle Datenausgabe

Beim Übertragen der einzelnen Bits muss die Steuerleitung Port_Enable low sein. Erst nachdem alle Bits gesendet wurden muss ein kurzer High-Impuls (Ladeimpuls) erfolgen. Erst bei diesem Ladeimpuls übernehmen die Schieberegister die Daten.

Wichtig:
Das 8-Bit-Datenregister welches für das Schieberegister, dass vom Mikrocontroller am "weitesten entfernt" ist, zuständig ist (hier IC9), muss als erstes gesendet werden. Hier muss daher das Array-Element mit dem Index 7 (für IC9) als erstes gesendet werden.

Portdefinitionen:
Für die Kommunikation mit den Schieberegistern sind drei Portleitungen des Mikrocontrollers notwendig. Diese werden in der Datei SR_74XX595.H gemäß der Schaltung nach Abbildung 2.1 definiert.

Listing 3.14 zeigt die Portdefinitionen für die Kommunikation mit den Schieberegistern.

Portdefinition Schieberegister

Unterprogramme:
Die Kommunikation mit den Schieberegistern erfolgt mit den beiden Unterprogrammen SR_74xx595_SendData und SR_74xx595_SendByte.

Unterprogramm SR_74xx595_SendData:
Dieses Unterprogramm erzeugt dass Protokoll gemäß Abbildung 3.2. Zunächst muss die Steuerleitung Port_Enable gelöscht werden, dann nacheinander die Datenbits (im Array SendArray[]) mit dem Unterprogramm SR_74xx595_SendByte in die Schieberegister schieben. Nach dem letzten Datenbit einen Ladeimpuls für die Übernahme in die Schieberegister erzeugen.

Die Übergabeparameter sind das zu "schiebende" Daten-Array (SendArray[]) und die Größe des Daten-Array (AnzahlDaten).

Listing 3.15 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm SR_74xx595_SendData

Hilfs-Unterprogramm SR_74xx595_SendByte:
Dieses Hilfs-Unterprogramm gibt mit Hilfe einer Schleife das MSB (Bit 7) am Datenausgang aus, erzeugt einen Takt und schiebt alle Bits um eine Stelle weiter.

Achtung:
Dieses Hilfsprogramm darf nur vom Unterprogramm SR_74xx595_SendData aufgerufen werden. Daher befindet sich der zugehörige Funktionsprototyp nicht in der Header-Datei SR_74XX595.H sondern in der Quelldatei SR_74XX595.C. Wird dieses Unterprogramm in einem anderen Unterprogramm oder im Hauptprogramm aufgerufen, so sollte der Compiler einen Fehler, oder zumindest eine Warnung ausgeben!

Listing 3.16 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm SR_74xx595_SendByte
nach oben

3.4.5. Hilfs-Unterprogramme zur Bitmanipulation

Zum Schluss noch drei kurze Unterprogramme, die für das Setzen (SetBit, Listing 3.17) bzw. für das Löschen (ClrBit, Listing 3.18) und für das Prüfen von Bits in Registern (isBitSet, Listing 3.19) zuständig sind. Diese drei Unterprogramme sind notwendig, da auf einzelne Bits nicht mit Registern zugegriffen werden kann. Diese sind hier aber durch die Verwendung von Schleifen notwendig.

Eine weitere Erläuterung zu diesen Unterprogrammen ist hier nicht notwendig.

Diese drei Unterprogramme befinden sich in der Datei myBitOperationenV2.C.

Unterprogramm SetBit Unterprogramm ClrBit Unterprogramm isBitSet
nach oben

3.5. Hinweise zu den Konfigurationsbits

Ein kleiner Nachteil beim mikroC-Compiler ist, dass die Konfigurationsbits in der IDE gesetzt werden müssen. Ich persönlich würde sie lieber im Quellcode mit einer geeigneten Anweisung setzen.

Hier sind die notwendigen Einstellungen für den PIC16F87 für dieses Projekt:

nach oben

1 Der PIC16F87 besitzt 12 Interruptquellen. Bei diesem Projekt wird aber nur der Timer-0-Interrupt benötigt.

2 Bit 0: Flamme, Bit 1: Wachs, siehe Abbildung 3.1

nach oben


zurück zu Elektronik, Homepage

Autor: Stefan Buchgeher
Erstellt: 24. Januar 2010
Letzte Änderung: