Elektronik-Projekt: Temperatur-Feuchtigkeits-Modul (Version 2)


zurück zu Elektronik, Homepage

Fertiges Temperatur-Feuchtigkeits-Modul (Version 2, in Betrieb)

4. Softwarebeschreibung

Die Aufgabe der Software für den PIC-Mikrocontroller besteht hier hauptsächlich aus der Kommunikation mit dem Sensor und der Kommunikation mit dem LC-Display, sowie mit einem PC via RS232.

Achtung:
Diese Dokumentation beschreibt hier (in diesem Kapitel) nur die Software für den PIC-Mikrocontroller. Kapitel 6 (Datenübertragung mit der RS232-Schnittstelle) erläutert das Protokoll für die RS232-Schnittstelle zur Datenübertragung (hier der Temperatur und der Luftfeuchigkeit) an einen PC oder an einem anderen, so genannten "übergeordneten System". Die Beschreibung einer möglichen Software für einen PC (z.B. für eine grafische Ausgabe der Temperatur und Luftfeuchtigkeit) ist in dieser Dokumentation nicht vorgesehen.

Das Protokoll für die Kommunikation mit dem Temperator und Feuchtigkeitssensor ist ausgiebig im Abschnitt 1.4. Protokoll beschrieben. Die Aufgabe der PIC-Software ist es nun dieses Protokoll umzusetzen. Weiteres die Linearisierung und Temperaturkompensation gemäß Abschnitt 1.6. Linearisierung und Temperaturkompensation. Diese Aufgaben werden von mehreren Unterprogrammen ausgeführt. Diese Unterprogramme werden im Abschnitt 4.4.4. Portdefinitionen, Konstanten, Tabelle und Unterprogramme zur Kommunikation mit dem Feuchtigkeitssensor vom Typ SHTxx und zur Ermittlung der Behaglichkeit.

Eine weitere Aufgabe der PIC-Software ist das "sichtbar machen" der Daten für den Anwender. Dazu wird ein LC-Display mit zwei Zeilen zu je 16 Zeichen verwendet und als zweite Möglichkeit können die Daten via RS232-Schnittstelle gelesen werden. Die für die Ausgabe am LC-Display notwendigen Unterprogramme stellt der bei diesem Projekt verwendete Compiler (mikroC) automatisch zur Verfügung. Die Unterprogramme für die RS232-Datenübertragung sind im Abschnitt 4.4.5. Unterprogramme zur Datenausgabe erläutert.

Manche Unterprogramme müssen zyklisch (also regelmäßig) aufgerufen werden. (Das Messen der Temperatur und der Luftfeuchigkeit erfolgt z.B. alle 10 Sekunden.) Dazu sind mehrere Zeitbasen notwendig. Diese werden mit Hilfe des Timer-Interrupts erzeugt (siehe Hauptprogramm, Abschnitt 4.2. und Interrupt-Service-Routine, Abschnitt 4.3.).

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

4.1. Globale Register, Portdefinitionen, Konstanten und Tabellen

Globale Register:
Für die Erzeugung der zwei Zeitbasen (hier für 100ms und 10 Sekunden) sind die folgenden drei globalen Register notwendig:

Globale Register

Portdefinitionen:
Im Allgemeinen werden bei jeder Anwendung die Ein- und Ausgangspins der diversen Hardwarekomponenten (hier für den Sensor, und das LC-Display) 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 den Sensor:
Die Portdefinition für den Sensor erfolgt in der Datei SHTxx.H. Mehr dazu im Abschnitt 4.4.4. Portdefinitionen, Konstanten, Tabelle und Unterprogramme zur Kommunikation mit dem Feuchtigkeitssensor vom Typ SHTxx und zur Ermittlung der Behaglichkeit.

Portdefinition für das LC-Display: Für die Ansteuerung des LC-Display stellt der C-Compiler fertige Unterprogramme zur Verfügung. Mit dem Unterprogramm Lcd_Custom_Config erfolgt die Definition der Portpins für das LC-Display. Siehe Hauptprogramm, Abschnitt 4.2. .

Portdefinition für das RS232-Hardware-Modul (USART): Für die Kommunikation via RS232 ist keine Portdefinition notwendig, nur die I/O-Pins müssen als Eingang bzw. Ausgang definiert werden. Diese Aufgabe übernimmt unter anderem das Unterprogramm Init. Siehe Abschnitt 4.4.1. Unterprogramm zur Initialisierung des PIC16F87 (Init) .

Konstanten:
Beim Temperatur-Feuchtigkeits-Modul werden einige Konstanten zur Erzeugung der Zeitbasen und für die Kommunikation mit dem Sensor benötigt.

Konstanten für die Zeitbasen:
Die Konstante KONSTZEITBASIS100MS gibt die Anzahl der notwendigen Interrupt-Aufrufe für die 100-ms-Zeitbasis an. Hier, beim Temperatur-Feuchtigkeits-Modul, wird die Interrupt-Service-Routine (ISR) alle 4ms aufgerufen, daher ergibt sich für die Konstante der Wert 25 (25 x 4ms = 100ms).
Die Konstante KONSTZEITBASIS10SEK beinhaltet den Wert 100, da die 10-Sekunden-Zeitbasis mit Hilfe der 100-ms-Zeitbasis erzeugt wird. Siehe auch Abschnitt 4.3. Interrupt-Service-Routine (ISR, Timer 0).

Konstanten zur Erzeugung der Zeitbasen

Konstanten für die Kommunikation mit dem Sensor:
Die Konstanten, die für die Kommunikation mit dem Sensor benötigt werden, werden im Abschnitt 4.4.4. Portdefinitionen, Konstanten, Tabelle und Unterprogramme zur Kommunikation mit dem Feuchtigkeitssensor vom Typ SHTxx und zur Ermittlung der Behaglichkeit behandelt.

Tabellen:
Beim Temperatur-Feuchtigkeits-Modul werden einige Tabellen zur Ermittlung der Behaglichkeit und zur Darstellung von Smileys am LC-Display benötigt.

Tabellen zur Darstellung der Smileys:
Bei einem alphanumerischen LC-Displays können 8 Symbole selbst definiert werden. Bei diesem Projekt werden drei Smileys für die Anzeige der Behaglichkeit verwendet. Diese drei Smileys sind im Standard-Zeichensatz des LC-Displays nicht vorgesehen, so dass sie selbst definiert werden müssen. Dazu müssen die einzelnen Zeilen der Symbole in einen eigenen Datenspeicher des LC-Displays geschrieben werden. Dieser Datenspeicher wird CGRAM genannt. Ein Zeichen besteht üblicherweise aus 8 Zeilen, also aus 8 Byte. Diese 8 Zeilen werden zu einer (kleinen) Tabelle zusammengefasst. Für die drei Smileys werden daher auch drei (kurze) Tabellen benötigt. Abbildung 4.1 zeigt diese drei Smileys und Listing 4.3 die Definition dieser Tabellen im Quellcode.

Darstellung der Smileys am LC-Display
Tabelle zur Erzeugung der Smileys

Siehe auch Abschnitt 4.4.3. Unterprogramm zur Erzeugung eigener Symbole für das LC-Display (Lcd_mySymbols).

Tabelle zur Ermittlung der Behaglichkeit:
Die Tabelle, die für die Ermittlung der Behaglichkeit benötigt wird, wird im Abschnitt 4.4.4. Portdefinitionen, Konstanten, Tabelle und Unterprogramme zur Kommunikation mit dem Feuchtigkeitssensor vom Typ SHTxx und zur Ermittlung der Behaglichkeit behandelt.

nach oben

4.2. Hauptprogramm

Das Hauptprogramm hat beim Temperatur-Feuchtigkeits-Modul folgende Aufgaben: Zuerst müssen der Mikrocontroller, der Sensor und das LC-Display initialisiert werden. Diese Aufgaben werden von den Unterprogrammen Init (Zeile 869), SHTxx_ConnectionReset (Zeile 872) und Lcd_Custom_Config (Zeile 875) ausgeführt. Als nächstes erfolgt das Erzeugen der eigenen Symbole (hier der drei Smileys) im LC-Display mit dem Unterprogramm Lcd_mySymbols (Zeile 888) und der Ausgabe eines "Begrüßungstextes" mit der Version am LC-Display (Zeilen 891 bis 894). Das eigene Register cLogRS232[1] muss gelöscht werden (Zeile 897) und die benötigten Interrupts müssen freigegeben werden (Zeile 900).

Der bei diesem Projekt verwendete PIC-Mikrocontroller (Typ: PIC16F87) besitzt 12 Interruptquellen. Hier wird aber nur der Timer-0-Interrupt benötigt. Für die Freigabe der Interrupts ist das Register INTCON zuständig. Je nach benötigten Interrupts werden die entsprechenden Freigabebits (im Englischen: Enable) gesetzt. Wird ein Interrupt verwendet, so muss zusätzlich zum verwendeten Interrupt auch die globale Interruptfreigabe GIE (General Interrupt Enable) gesetzt werden. Er ist sozusagen der Hauptschalter, der Interrupts ermöglicht. Der Timer-0-Interrupt ist nun eingeschaltet. Er sorgt hier für eine 4-ms-Zeitbasis.

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 4.4 zeigt das Hauptprogramm (Auszug aus feuchtemodul2.c).

Hauptprogramm (Teil 1)
Hauptprogramm (Teil 2)
Hauptprogramm (Teil 3)
nach oben

4.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 ISR wird die Abarbeitung des Programms zwar wieder an der Stelle wo sie war, bevor der Interrupt auftauchte, fortgesetzt, aber mit einem möglicherweise falschen Wert im w-Register (Working- oder Arbeitsregister) bzw. im 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. Diese Kontroll-Flags werden 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 hier nur die Aufgabe eine Zeitbasis für 100ms und eine zweite Zeitbasis für 10 Sekunden zu erzeugen. Damit eine Zeit von 100ms entsteht muss die ISR 25-mal aufgerufen werden (25 x 4ms = 100ms). Bei jedem ISR-Aufruf muss daher ein Zählregister (hier: cZaehlerZeitbasis100ms) um 1 vermindert werden. Besitzt es danach den Wert 0, so ist eine Zeit von 100ms vergangen. Nun wird das Botschaftsflag bFlagZeitbasis100ms im Register cFlagISRHP gesetzt, und das Zählregister muss mit dem Wert 25 neu geladen werden. Der Wert 25 wird hier durch die Konstante KONSTZEITBASIS100MS ersetzt. Das selbe Prinzip wird auch für die Erzeugung der 10-Sekunden-Zeitbasis verwendet.

Anmerkung:
Die 100ms-Zeitbasis wird für das regelmäßige Prüfen des RS232-Empfangsbuffers benötigt, während die 10-Sekunden-Zeitbasis für das Messen der Temperatur und Luftfeuchtigkeit benötigt wird. D.h. eine Messung inkl. Auswertung (Kompensation und Linearisierung) erfolgt alle 10 Sekunden.

Die Zeit von 4ms ergibt sich, weil als Taktquelle ein 4,096-MHz-Quarz (X1) verwendet wird, und weil der Vorteiler (VT) mit dem Wert 1:16 (TMR0 Rate, Zeile 171 im Unterprogramm Init) geladen wird. Für diese Zeit gilt:

Formel für ISR-Aufruf

Listing 4.5 zeigt die kurze Interrupt-Service-Routine (Auszug aus feuchtemodul2.c).

Interrupt-Service-Routine
nach oben

4.4. Unterprogramme

Die insgesamt 16 Unterprogramme lassen sich wie folgt einteilen:

nach oben

4.4.1. Unterprogramm zur Initialisierung des PIC16F87 (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 4ms) 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 4,096MHz eine Zeitbasis von 4ms erzeugt wird, muss das Register OPTION mit dem binären Wert bxxxx0011 geladen werden (Zeile 171). Das Zählregister für diese Zeitbasis (Funktions-Register TMR0) muss gelöscht werden (Zeile 169).

Die beiden Ports (beim PIC16F87 die Ports A und B) müssen gemäß der Beschaltung nach Abbildung 3.1 (siehe Kapitel 3. Schaltungsbeschreibung) entweder als Eingang oder als Ausgang definiert werden (Zeilen 200 und 210).

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

Das PIC-interne Hardwaremodul für die RS232-Kommunikation (UART) initialisieren (Zeilen 253, 281 und 316). Die so genannte Baudrate (also die "Geschwindigkeit" mit der die einzelnen Bits übertragen werden) wird mit dem Register SPBRG bestimmt. Der Wert mit dem dieses Register geladen wird ergibt sich gemäß [Microchip, 2005] mit der folgenden Formel:

Formel Baudrate

Ich verwende sehr gerne eine Baudrate von 19200. Da bei diesem Projekt ein 4.096-MHz-Quarz verwendet wird, ergibt sich für das Register SPBRG der Wert 12. Durch das Abrunden entsteht zwar ein kleiner Fehler, der sich aber nicht negativ auf die Datenübertragung auswirkt.

Zum Abschluss werden noch die globalen Zählregister für die Zeitbasen (100 Millisekunden und 10 Sekunden) initialisiert (Zeilen 321 und 322).

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

Unterprogramm zur Initialisierung des Mikrocontrollers (Teil 1)
Unterprogramm zur Initialisierung des Mikrocontrollers (Teil 2)
Unterprogramm zur Initialisierung des Mikrocontrollers (Teil 3)
nach oben

4.4.2. Unterprogramme für die RS232-Datenkommunikation

Für die Datenkommunikation via RS232 sind zwei Unterprogramme notwendig. Das Unterprogramm RS232Senden dient zum Senden von (8-Bit)-Daten und mit dem Unterprogamm RS232Empfangen können Daten (Werte oder Anweisungen) empfangen werden.

Wichtig:
Der PIC16F87 verfügt über ein so genanntes USART-Hardware-Modul. D.h. Der Mikrocontroller verfügt über diese Schnittstelle, sie muss nur mehr für den jeweiligen Anwendungsfall angepasst werden. Dieses Anpassen erfolgt mit den PIC-internen Registern (SFR = Special Function Register) TXSTA, RCSTA und SPBRG. Weiters müssen auch die beiden Portpins TX als Ausganungspin und RX als Eingangspin konfiguriert werden. Alle diese Einstellungen wurden bereits im Unterprogramm Init durchgeführt (siehe Abschnitt 4.4.1. Unterprogramm zur Initialisierung des PIC16F87 (Init)).

Unterprogramm RS232Senden:
Dieses Unterprogramm sendet 1 Byte (im Übergaberegister cWert) an ein angeschlossenes Gerät. (PC, eine andere Mikrcocontrollereinheit, etc. )

Vorgehensweise:

  1. Warten, bis der Sendebuffer des USART entleert ist (Dies zeigt das Flag TRMT in Register TXSTA an).
  2. Den auszugebenden Wert in das Register TXREG schreiben.
  3. Fertig! - Den Rest übernimmt die Hardware des USART-Moduls.

Listing 4.7 zeigt dieses sehr kurze und einfache Unterprogramm.

Unterprogramm RS232Senden
nach oben

Unterprogramm RS232Empfangen:
Das Unterprogramm zum Empfangen ist etwas länger. Es prüft, ob Daten im Empfangsbuffer des USART vorhanden sind. Das Flag RCIF gibt darüber Auskunft. Befinden sich Daten im Empfangsbuffer, prüfen ob es sich dabei um '*' handelt, denn jedes Kommando oder jede Datenübertragung muss mit dem Symbol '*' beginnen. Je nach Aufgabenstellung auf die weiteren Daten (Bytes) warten und je nach Wert die jeweiligen Aktivitäten durchführen.

Vorgehensweise:
Ist das Flag RCIF gesetzt (Byte befindet sich Empfangsbuffer) die folgenden Aktionen durchführen. Ist das Flag RCIF nicht gesetzt (Empfangsbuffer ist leer) das Unterprogramm verlassen.
Flag RCIF ist gesetzt und es handelt sich im Empfangsbuffer um '*' auf das nächste Byte warten, andernfalls das Unterprogramm verlasssen. Je nach empfangenem Byte die gewünschte Aktion durchführen (Flag setzen oder rücksetzen, Unterprogramm aufrufen etc.). Diese Aktionen sind je nach Projekt unterschiedlich. Hier, beim Temperatur-Feuchtigkeits-Modul handelt es sich um folgende Aktionen:
'?': Anwendungsbezeichnung senden (hier den Text-String: SHT15-Feuchtemodul)
'V': Versionsnummer senden
'S': Datenlogging starten
'R': Datenlogging stoppen

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

Listing 4.8 zeigt die Realisierung von diesem Unterprogramm.

Unterprogramm RS232Empfangen (Teil 1)
Unterprogramm RS232Empfangen (Teil 2)

Siehe auch Kapitel 6. Datenübertragung mit der RS232-Schnittstelle.

nach oben

4.4.3. Unterprogramm zur Erzeugung eigener Symbole für das LC-Display (Lcd_mySymbols)

Beim alphanumerischen LC-Displays können 8 Symbole selbst definiert werden. Bei diesem Projekt werden drei Smileys für die Anzeige der Behaglichkeit verwendet. Diese drei Smilies sind im Standard-Zeichensatz des LC-Displays nicht vorgesehen, so dass sie selbst definiert werden müssen. Die Aufgabe dieses Unterprogrammes ist es daher die eigenen Symbole (hier die drei Smileys) in den Datenspeicher des LC-Displays (CGRAM) zu schreiben, so dass sie dann bei Gebrauch so wie die vordefinierten Buchstaben, Ziffern und Zeichen verwendet werden können. Der Datenspeicher für die eigenen Symbole beginnt ab Adresse 72 und wird CGRAM bezeichnet. Die Daten für die eigene Symbole müssen zeilenweise eingegeben werden, und sind in Tabellen abgelegt (siehe Abschnitt 4.1. Globale Register, Portdefinitionen, Konstanten und Tabellen

Listing 4.9 zeigt die Realisierung von diesem kurzen Unterprogramm.

Unterprogramm Lcd_mySymbols
nach oben

4.4.4. Portdefinitionen, Konstanten, Tabelle und Unterprogramme zur Kommunikation mit dem Feuchtigkeitssensor vom Typ SHTxx und zur Ermittlung der Behaglichkeit

Das Protokoll für die Kommunikation mit dem Temperatur-Feuchtigkeitssensor SHT15 wurde in Kapitel 1. Grundlegendes zum Feuchtesensor vom Typ SHT1x sehr ausführlich beschrieben. Dieser Abschnitt beschreibt nun die softwaretechnische Realisierung im PIC-Mikrocontroller. Dazu sind die Definition der Portpins und einige Konstanten notwendigen. Weiters eine etwas größere Tabelle für die Ermittlung der Behaglichkeit und einige Unterprogramme. All dies befindet sich in den beiden Dateien SHTxx.C und SHTxx.H.

Portdefinitionen:
Für die Kommunikation mit dem Temperatur-Feuchtigkeitssensor SHT15 sind zwei Portleitungen des PIC-Mikrocontrollers notwendig. Diese werden in der Datei SHTxx.H gemäß der Schaltung nach Abbildung 3.1 (Kapitel 3. Schaltungsbeschreibung) definiert.

Wichtig:
Während der Erzeugung des Protokolls muss der Data-Pin mehrmals zwischen Ein- und Ausgang umgeschaltet werden. Dazu wird der Parameter TRIS_DATA benötigt. Wird für DATA der Port A verwendet, so muss für TRIS_DATA das zum Port A zugehörige TRIS-Register definiert werden. (siehe Zeile 15)}.

Listing 4.10 zeigt die Portdefinition für die Kommunikation mit dem Temperatur-Feuchtigkeits-Sensor vom Typ SHT15.

Portdefinition für die Kommunikation mit dem Temperatur-Feuchtigkeits-Sensor vom Typ SHT15

Konstanten:
Die folgenden Konstanten werden für die Kommunikation mit dem Temperatur-Feuchtigkeits-Sensor vom Typ SHT15 verwendet:

Listing 4.11 zeigt die Konstanten für die Kommunikation mit dem Temperatur-Feuchtigkeits-Sensor vom Typ SHT15.

Konstanten für die Kommunikation mit dem Temperatur-Feuchtigkeits-Sensor vom Typ SHT15 (Teil 1)
Konstanten für die Kommunikation mit dem Temperatur-Feuchtigkeits-Sensor vom Typ SHT15 (Teil 2)

Tabelle:
Der Vollständigkeit halber hier noch einmal die Tabelle, die für die Ermittlung der Behaglichkeit verwendet wird (Listing 4.12). Diese Tabelle wurde schon in Kapitel 2. Grundlagen zur Behaglichkeit vorgestellt.

Tabelle für die Ermittlung der Behaglichkeit

Unterprogramme:
Für die Kommunikation mit dem Temperatur-Feuchtigkeits-Sensor vom Typ SHT15 sind folgende Unterprogramme notwendig:

Das Unterprogramm SHTxx_BehaglichkeitsWert berechnet aus der Temperatur und der Feuchtigkeit den Behaglichkeitswert gemäß Kapitel 2. Grundlagen zur Behaglichkeit.

Nun aber zu den einzelnen Unterprogrammen im Detail:

Unterprogramm SHTxx_Start:
Dieses Unterprogramm erzeugt die Startbedingung gemäß Abschnitt 1.4.1. Start-Sequenz. Zur Erinnerung: Jede Kommunikation mit dem Sensor beginnt mit einer so genannten Start-Sequenz. Diese Start-Sequenz ist wie folgt definiert (Abbildung 4.2):

Start-Sequenz
Achtung:
Die Start-Sequenz darf nur von den Unterprogrammen SHTxx_ConnectionReset, SHTxx_StatusRegisterLesen, SHTxx_StatusRegisterSchreiben und SHTxx_Messung aufgerufen werden. Daher befindet sich der zugehörige Funktionsprototyp nicht in der Header-Datei SHTxx.H sondern in der Quelldatei SHTxx.C. Wird dieses Unterprogramm in einem anderen Unterprogramm oder im Hauptprogramm aufgerufen, so sollte der Compiler einen Fehler, oder zumindest eine Warnung ausgeben!

Listing 4.13 zeigt die Realisierung der Startbedingung.

Unterprogramm SHTxx_Start (Teil 1)
Unterprogramm SHTxx_Start (Teil 2)

Unterprogramm SHTxx_ConnectionReset:
Zur Erinnerung (vgl. Abschnitt 1.4.5. Rücksetzen des Sensors.
Wird die Kommunikation mit dem Sensor unterbrochen, so muss mit der folgenden Befehlsfolge (Connection-Reset-Sequenz) die Kommunikation mit dem Sensor neu gestartet werden.
Neun oder mehr Taktimpulse während die Datenleitung (DATA) high ist. Gefolgt von einer Startsequenz entsprechend Abschnitt 1.4.1. Start-Sequenz. Die Abbildung 4.3 zeigt diese Sequenz.

Connection-Reset-Sequenz

Listing 4.14 zeigt die Realisierung die Realisierung dieses Unterprogramms.

Unterprogramm SHTxx_ConnectionReset

Unterprogramm SHTxx_Schreiben:
Dieses Unterprogramm schreibt ein Byte (also eine Anweisung) an den Sensor und empfängt die Bestätigung vom Sensor.

Vorgehensweise:

  1. Fehler-Register (cFehler) löschen
  2. Mit einer Schleife jedes einzelne Bit des zu übergebenden Bytes maskieren und das Ergebnis auf die DATA-Leitung (bSHTxx_Data) geben. Anschließend einen Taktimpuls erzeugen
  3. Nun die Bestätigung (Acknowledge) empfangen:
    1. DATA (bSHTxx_Data) = 1
    2. SCK (bSHTxx_Sck) = 1 (steigende Flanke der Takt-Leitung)
    3. Das TRIS_DATA-Flag (bSHTxx_Data_Tris) muss nun gesetzt werden, da der DATA-Pin (bSHTxx_Data) auf Eingang umgeschaltet werden muss
  4. Nun die DATA-Leitung (bSHTxx_Data) einlesen und im Fehler-Register (cFehler) sichern
    1. SCK (bSHTxx_Sck) = 0 (fallende Flanke der Takt-Leitung)
    2. Das TRIS_DATA-Flag (bSHTxx_Data_Tris) muss wieder gelöscht werden, da der DATA-Pin (bSHTxx_Data) nun wieder als Ausgang dienen soll
Achtung:
Dieses (Hilfs-)Unterprogramm darf nur von den Unterprogrammen SHTxx_StatusRegisterLesen, SHTxx_StatusRegisterSchreiben und SHTxx_Messung aufgerufen werden. Daher befindet sich der zugehörige Funktionsprototyp nicht in der Header-Datei SHTxx.H sondern in der Quelldatei SHTxx.C. Wird dieses Unterprogramm in einem anderen Unterprogramm oder im Hauptprogramm aufgerufen, so sollte der Compiler einen Fehler, oder zumindest eine Warnung ausgeben!

Listing 4.15 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm SHTxx_Schreiben

Unterprogramm SHTxx_Lesen:
Dieses Unterprogramm empfängt ein Byte vom Sensor und sendet eine Bestätigung an den Sensor, wenn ACK (cAck) = 1.

Vorgehensweise:

  1. DATA (bSHTxx_Data) = 1
  2. Das TRIS_DATA-Flag (bSHTxx_Data_Tris) muss gesetzt werden, da der Data-Pin (bSHTxx_Data) auf Eingang umgeschaltet werden muss
  3. Mit einer Schleife das 8-Bit Datenwort bitweise einlesen
  4. Das TRIS_DATA-Flag (bSHTxx_Data_Tris) muss wieder gelöscht werden, da der DATA-Pin (bSHTxx_Data) nun wieder als Ausgang dienen soll
  5. Nun die Bestätigung (Acknowledge) senden
  6. DATA (bSHTxx_Data) = 1
Achtung:
Dieses (Hilfs-)Unterprogramm darf nur von den Unterprogrammen SHTxx_StatusRegisterLesen, SHTxx_StatusRegisterSchreiben und SHTxx_Messung aufgerufen werden. Daher befindet sich der zugehörige Funktionsprototyp nicht in der Header-Datei SHTxx.H sondern in der Quelldatei SHTxx.C. Wird dieses Unterprogramm in einem anderen Unterprogramm oder im Hauptprogramm aufgerufen, so sollte der Compiler einen Fehler, oder zumindest eine Warnung ausgeben!

Listing 4.16 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm SHTxx_Lesen (Teil 1)
Unterprogramm SHTxx_Lesen (Teil 2)

Unterprogramm SHTxx_StatusRegisterLesen:
Dieses Unterprogramm dient zum Lesen des Statusregisters vom Sensor gemäß Abschnitt 1.4.4. (Sensor-Statusregister lesen bzw. beschreiben).

Vorgehensweise:

  1. Startbedingung mit dem Unterprogramm SHTxx_Start() erzeugen
  2. Anweisung zum Lesen des Statusregister (mit dem Unterprogramm SHTxx_Schreiben() und mit dem Parameter (Konstante) STATUS_LESEN (=0x07))
  3. Status-Register mit dem Unterprogramm SHTxx_Lesen() einlesen und im Übergabeparameter *pWert sichern
  4. Checksumme mit dem Unterprogramm SHTxx_Lesen() einlesen (Anmerkung: Wird aber hier noch nicht weiter verwendet!!!)
  5. Falls ein Fehler aufgetreten ist, ist der Rückgabewert ungleich 0

Listing 4.17 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm SHTxx_StatusRegisterLesen

Unterprogramm SHTxx_StatusRegisterSchreiben:
Dieses Unterprogramm dient zum Beschreiben des Statusregisters vom Sensor gemäß Abschnitt 1.4.4. (Sensor-Statusregister lesen bzw. beschreiben).

Vorgehensweise:

  1. Startbedingung mit dem Unterprogramm SHTxx_Start() erzeugen
  2. Anweisung zum Beschreiben des Statusregister (mit dem Unterprogramm SHTxx_Schreiben() und mit dem Parameter (Konstante) STATUS_SCHREIBEN (=0x06))
  3. Den Wert cWert mit dem Unterprogramm SHTxx_Schreiben() in das Statusregister des Sensors schreiben
  4. Falls ein Fehler aufgetreten ist, ist der Rückgabewert ungleich 0

Listing 4.18 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm SHTxx_StatusRegisterSchreiben

Unterprogramm SHTxx_Messung:
Dieses Unterprogramm führt sowohl eine Temperaturmessung als auch eine Feuchtigkeitsmessung durch und berechnet aus den Sensor-Rohdaten die Temperatur und die Feuchtigkeit.

Vorgehensweise:

  1. Temperatur vom Sensor lesen
  2. Feuchtigkeit vom Sensor lesen
  3. Temperatur berechnen und linearisieren
  4. Feuchtigkeitswert linearisieren und mit der Temperatur kompensieren
  5. Temperatur- und Feuchtigkeitswert dem aufrufenden Programm übergeben
  6. Falls ein Fehler aufgetreten ist, ist der Rückgabewert ungleich 0

Listing 4.19 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm SHTxx_Messung (Teil 1)
Unterprogramm SHTxx_Messung (Teil 2)

Unterprogramm SHTxx_Behaglichkeitswert:
Dieses Unterprogramm ermittelt aufgrund der Temperatur und Feuchtigkeit einen Behaglichkeitswert gemäß Kapitel 2. (Grundlagen zur Behaglichkeit), wobei gilt: 1 = unbehaglich, 2 = noch behaglich und 3 = behaglich.

Vorgehensweise:

  1. Für Temperaturen <14.0C und >26.9C gilt: unbehaglich, daher Rückgabewert 1
  2. Für alle anderen Temperaturen erfolgt die Ermittlung der Behaglichkeit mit der Tabelle TabBehaglichkeit, wobei die Aufloesungen 0.5C bzw. 5$% sind. (Daher die Divisionen mit 5!)

Listing 4.20 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm SHTxx_BehaglichkeitsWert
nach oben

4.4.5. Unterprogramme zur Datenausgabe

Die nun folgenden Unterprogramme dienen der Anzeige der Temperatur und der Feuchtigkeit auf dem LC-Display (Unterprogramm AusgabeLCD) sowie der Ausgabe via RS232 (Unterprogramm AusgabeRS232). Dazu müssen aber vorher noch die Temperatur und die Fuechtigkeit in die BCD-"Bestandteile" Vorzeichen, Hunderterstelle, Zehnerstelle usw. zerlegt werden. Diese Aufgabe übernehmen die beiden Unterprogramm BCDTemperatur und BCDFeuchte.

Unterprogramm BCDTemperatur:
Dieses Unterprogramm zerlegt den 16-Bit Temperaturwert in seine BCD-"Bestandteile". Also hier in Vorzeichen, Zehnerstelle, Einerstelle und Zehntelstelle.

Anmerkung:
Die Darstellung des Temperaturwerts (in der Variable iTemperaturWert) erfolgt in Zweierkomplementdarstellung, und ist, da auch noch eine Zehntelstelle vorhanden ist mit 10 multipliziert!

Listing 4.21 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm BCDTemperatur

Unterprogramm BCDFeuchte:
Dieses Unterprogramm zerlegt den 8-Bit Feuchtigkeitswert in seine BCD-"Bestandteile". Hier also in Hunderterstelle, Zehnerstelle und Einerstelle.

Anmerkung:
Die Darstellung des Feuchtigkeitswerts (in der Variable cFeuchteWert) erfolgt im Gegensatz zum Temperaturwert in "normaler Darstellung", da die Feuchtigkeit nur positive Wert enthält.

Listing 4.22 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm BCDFeuchte (Teil 1)
Unterprogramm BCDFeuchte (Teil 2)

Unterprogramm AusgabeLCD:
Dieses Unterprogramm gibt die berechnete Temperatur, Luftfeuchtigkeit und den Wohlfühl-Smiley am LC-Display aus.

Vorgehensweise:

  1. LC-Display löschen
  2. In der ersten Zeile den Text 'Temp: ' und den Temperaturwert ausgeben
  3. In der zweiten Zeile den Text 'Feuchte: ' und den kompensierten Feuchtigkeitswert ausgeben, sowie den Wohlfühl-Smiley.

Anmerkung:
Sämtliche Unterprogramme für die Ansteuerung des LC-Displays werden vom mikroC-Compiler automatisch zur Verfügung gestellt, und müssen daher nicht selbst programmiert werden. (Hier die Unterprogramme die mit Lcd_xxx beginnen, also Lcd_Custom_Cmd, Lcd_Custom_Out_Cp, Lcd_Custom_Chr_Cp und Lcd_Custom_Out).

Listing 4.23 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm AusgabeLCD (Teil 1)
Unterprogramm AusgabeLCD (Teil 2)

Unterprogramm AusgabeRS232:
Dieses Unterprogramm sendet die berechnete Temperatur, Luftfeuchtigkeit und den Wohlfühl-Smiley via RS232 an einen PC oder ein anderes (übergeordnetes) System.

Vorgehensweise:

  1. Kennung (hier '*' und 'D') senden
  2. Temperatur
    1. Kennbuchstabe 'T' und ':'
    2. 16-Bit-Temperaturwert (in Zweierkomplementdarstellung, aufgeteilt auf 2 Byte (Höherwertigeres Byte zuerst)
    3. Temperaturwert in ASCII-Schreibweise (also zuerst Vorzeichen, Zehnerstelle, Einerstelle, Dezimalpunkt und Zehntelstelle)
    4. Einheit ('C')
  3. Feuchtigkeit
    1. Kennbuchstabe 'F'
    2. 8-Bit-Feuchtigkeitswert
    3. Feuchtigkeitswert in ASCII-Schreibweise (also zuerst Hunderterstelle, Zehnerstelle und Einerstelle)
    4. Einheit ('%')
  4. Behaglichkeit
    1. Kennbuchstabe 'B'
    2. Behaglichkeitsswert
    3. Behaglichkeitsswert in ASCII-Schreibweise

Listing 4.24 zeigt die Realisierung dieses Unterprogramms.

Unterprogramm AusgabeRS232 (Teil 1)
Unterprogramm AusgabeRS232 (Teil 2)
nach oben

4.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 Mit dem Register cLogRS232 wird das Logging via RS232 ein- bzw. ausgeschaltet. Zu Beginn ist das Logging ausgeschaltet, daher muss das Register cLogRS232 gelöscht werden. Siehe auch Unterprogramm RS232Empfangen (Abschnitt 4.4.2. Unterprogramme für die RS232-Datenkommunikation)

nach oben


zurück zu Elektronik, Homepage

Autor: Stefan Buchgeher
Erstellt: 23. Februar 2011
Letzte Änderung: