Mit dem Experimentierboard können sie die Raumtemperatur mit Hilfe des DS1621 messen und ausgeben. Erstellen sie ein Programm, das die Temperatur misst und auf der 7-Segment LED ausgibt.
In diesem Projekt werden zwei I²C-Bus-Bausteine verwendet. Da der Zugriff abwechselnd auf die Bausteine erfolgt, muss die I²C-Bus-Adresse immer mitgesetzt werden (siehe Listing 30, ).
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
TemperaturMes |
Test_Temperatur |
TestTemperatur.c |
|
|
..\Library |
I2C_LIB.c, PortConfig.c |
Tabelle 44 Projekt TemperaturMes
|
‚ ‚ ‚
‚ ‚ ‚ ‚
ƒ ƒ
ƒ
|
#include <REG932.H> #include <I2C_LIB.H>
enum enSAASEG {NULL = 0x3F, EINS = 0x06, ZWEI = 0x5B, DREI = 0x4F, VIER = 0x66, FUENF = 0x6D, SECHS = 0x7D, SIEBEN = 0x07, ACHT = 0x7F, NEUN = 0x67, PUNKT = 0x80, Minus = 0x40, BLANK = 0x00};
void uc_ConvVal(unsigned char ucValue) { switch(ucValue) { case 0x00: v_SetNextI2CVal(NULL); break; case 0x01: v_SetNextI2CVal(EINS); break; case 0x02: v_SetNextI2CVal(ZWEI); break; case 0x03: v_SetNextI2CVal(DREI); break; case 0x04: v_SetNextI2CVal(VIER); break; case 0x05: v_SetNextI2CVal(FUENF); break; case 0x06: v_SetNextI2CVal(SECHS); break; case 0x07: v_SetNextI2CVal(SIEBEN); break; case 0x08: v_SetNextI2CVal(ACHT); break; case 0x09: v_SetNextI2CVal(NEUN); break; default: break; } }
void main(void) { char cValue; bit btHalf; unsigned char ucLoop; v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben
Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(0); // Subadresse auf 0 (Control-Byte) v_SetNextI2CVal(0xF7); // dynamic alternating mode v_StartI2CandWait();
Slave.Adr = 0x92; // Adresse DS1621 + WR v_SetNextI2CVal(0xEE); //Command Byte: Start Convert v_StartI2CandWait(); v_SetNextI2CVal(0xAA); //Command Byte:Read Temp v_StartI2CandWait();
while(1) { Slave.Adr = 0x92 + 1; // Adresse DS1621 + RD Slave.DataLen = 2; // zwei Bytes werden empfangen v_StartI2CandWait();
cValue = Slave.Val[0]; if (Slave.Val[1] == 0x80) btHalf = 1; else btHalf = 0;
Slave.DataLen = 0; Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(1); // Subadresse auf 1 (Daten-Byte)
// Ausgabe der gelesenen Temperatur if (cValue < 0) { v_SetNextI2CVal(Minus); cValue = cValue * -1; } else { uc_ConvVal(cValue/100); cValue = cValue % 100; // Rest ermitteln uc_ConvVal(cValue/10); cValue = cValue % 10; // Rest ermitteln uc_ConvVal(cValue); } // Dezimalpunkt setzen Slave.Val[Slave.DataLen-1] |= PUNKT; // Ueberpruefung auf .5 if (btHalf) v_SetNextI2CVal(FUENF); else v_SetNextI2CVal(NULL); v_StartI2CandWait(); } } |
Listing 30 Inhalt von TestTemperatur.c
Die Funktion „main()“ enthält Programmteile zur Initialisierung (siehe Listing 30, , ‚) und die Auswertung der einzelnen I²C-Bus-Bausteine (siehe , ƒ). Diese Programmteile können als eigene Funktionen in einzelne Sourcemodule ausgelagert werden und somit in anderen Projekten wieder verwendet werden.
Erstellen sie das Projekt aus Tabelle 45. Das Sourcemodul DS1621_LIB.c enthält die Funktionen „v_DS1621StartCov() (siehe Listing 31, )“, „v_DS1621SetCMD()“ (siehe ‚) und v_ DS1621ReadTemp()“ (siehe ƒ). Die Funktionsdeklarationen sind im H-File DS1621_LIB.h abgespeichert. Das Sourcemodul SAA1064_LIB.c enthält die Funktionen „v_InitSAA1064()“ und „v_ConvVal()“ (siehe Listing 33). Die Funktionsdeklarationen sowie die Definitionen für die LED-Segmente sind im H-File DS1621_LIB.h enthalten (siehe Listing 32). Das Sourcemodul TestTemperatur.c enthält nur noch die Funktion „main()“ (siehe Listing 35). Diese wiederum enthält nur noch die Initialisierungsaufrufe für die I²C-Bus-Bausteine und die Umwandlung der Temperatur für die 7-Segment- Darstellung. Damit die Funktionen von DS1621 und SAA1064 im Sourcemodul TestTemperatur.c bekannt sind, müssen die H-Files inkludiert werden (siehe Listing 35, ).
|
Projektname |
Verzeichnis |
Verwendete Sourcemodule |
|
Test_TempModular |
Test_DS1621_SAA1064_Lib |
TestTemperatur.c |
|
|
..\Library |
DS1621_LIB.c, I2C_LIB.c, SAA1064_LIB.c, PortConfig.c |
Tabelle 45 Projekt Test_TempModular
|
‚
ƒ
|
#include <I2C_LIB.H> #include <DS1621_LIB.h>
void v_DS1621StartCov(void) { Slave.Adr = 0x92; // Adresse DS1621 + WR v_SetNextI2CVal(0xEE); //Command Byte: Start Convert v_StartI2CandWait(); }
void v_DS1621SetCMD(unsigned char ucCmd) { Slave.Adr = 0x92; // Adresse DS1621 + WR v_SetNextI2CVal(ucCmd); //Command Byte:Read Temp v_StartI2CandWait(); }
void v_DS1621ReadTemp(void) { Slave.Adr = 0x92 + 1; // Adresse DS1621 + RD Slave.DataLen = 2; // zwei Bytes werden empfangen v_StartI2CandWait(); } |
Listing 31 Inhalt von DS1621_LIB.c
|
|
// Definitionen enum enDS161Config {READ_TEMP = 0xAA};
// Funktionsdeklarationen void v_DS1621StartCov(void); void v_DS1621ReadTemp(void); void v_DS1621SetCMD(unsigned char ucCmd); |
Listing 32 Inhalt von DS1621_LIB.h
|
|
#include <I2C_LIB.H> #include <SAA1064_LIB.h>
void v_InitSAA1064(unsigned char ucMode) { Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(0); // Subadresse auf 0 (Control-Byte) v_SetNextI2CVal(ucMode); // Betriebsart setzen v_StartI2CandWait(); }
void v_ConvVal(unsigned char ucValue) { switch(ucValue) { case 0x00: v_SetNextI2CVal(NULL); break; case 0x01: v_SetNextI2CVal(EINS); break; case 0x02: v_SetNextI2CVal(ZWEI); break; case 0x03: v_SetNextI2CVal(DREI); break; case 0x04: v_SetNextI2CVal(VIER); break; case 0x05: v_SetNextI2CVal(FUENF); break; case 0x06: v_SetNextI2CVal(SECHS); break; case 0x07: v_SetNextI2CVal(SIEBEN); break; case 0x08: v_SetNextI2CVal(ACHT); break; case 0x09: v_SetNextI2CVal(NEUN); break; default: break; } } |
Listing 33 Inhalt von SAA1064_LIB.c
|
|
// Definitionen enum enSAASEG {NULL = 0x3F, EINS = 0x06, ZWEI = 0x5B, DREI = 0x4F, VIER = 0x66, FUENF = 0x6D, SECHS = 0x7D, SIEBEN = 0x07, ACHT = 0x7F, NEUN = 0x67, PUNKT = 0x80, Minus = 0x40, BLANK = 0x00}; enum enSAACONFIG {DYNAMIC_MODE = 0xF7};
// Funktionsdeklarationen void v_InitSAA1064(unsigned char ucMode); void v_ConvVal(unsigned char ucValue); |
Listing 34 Inhalt von SAA1064_LIB.h
|
|
#include <REG932.H> #include <I2C_LIB.H> #include <SAA1064_LIB.h> #include <DS1621_LIB.h>
void main(void) { char cValue; bit btHalf; v_InitI2C(); EA = 1; // allgemeine Interruptsperre aufheben v_InitSAA1064(DYNAMIC_MODE); v_DS1621StartCov(); v_DS1621SetCMD(READ_TEMP);
while(1) { v_DS1621ReadTemp(); // Ausgabe der gelesenen Temperatur cValue = Slave.Val[0]; if (Slave.Val[1] == 0x80) btHalf = 1; else btHalf = 0;
Slave.DataLen = 0; Slave.Adr = 0x70; // Adresse SAA1064 v_SetNextI2CVal(1); // Subadresse auf 1 (Daten-Byte) if (cValue < 0) { v_SetNextI2CVal(Minus); cValue = cValue * -1; }
v_ConvVal(cValue/100); cValue = cValue % 100; // Rest ermitteln v_ConvVal(cValue/10); cValue = cValue % 10; // Rest ermitteln v_ConvVal(cValue);
// Dezimalpunkt setzen Slave.Val[Slave.DataLen-1] |= PUNKT; if (btHalf) // Ueberpruefung auf .5 v_SetNextI2CVal(FUENF); else v_SetNextI2CVal(NULL); v_StartI2CandWait(); } } |
Listing 35 Inhalt von TestTemperatur.c
Die Zeichen A – F können auf der 7-Segment LED ausgegeben werden. Die Buchstaben „b“ und „d“ werden dabei als Kleinbuchstaben dargestellt (siehe Abbildung 45).
|
|
|
Abbildung 45 Buchstabendarstellung A–F
Erweitern sie die SAA1064_LIB.c und SAA1064_lib.h um die Buchstabeneinträge. Bei den Definitionen der Buchstaben im Aufzählungstyp enum muss ein Unterstrich davor gesetzt werden, da der Buchstabe B bereits bei den SFR-Definitionen verwendet wurde (siehe Listing 36, ).
|
|
// Definitionen enum enSAASEG {NULL = 0x3F, EINS = 0x06, ZWEI = 0x5B, DREI = 0x4F, VIER = 0x66, FUENF = 0x6D, SECHS = 0x7D, SIEBEN = 0x07, ACHT = 0x7F, NEUN = 0x67, PUNKT = 0x80, MINUS = 0x40, BLANK = 0x00, _A = 0x77, _B = 0x7C, _C = 0x39, _D = 0x5E, _E = 0x79, _F = 0x71 }; enum enSAACONFIG {DYNAMIC_MODE = 0xF7};
// Funktionsdeklarationen void v_InitSAA1064(unsigned char ucMode); void v_ConvVal(unsigned char ucValue); |
Listing 36 Erweiterungen in der SAA1064_LIB.h (enum enSAASEG)
In der Funktion „v_ConvVal()“ muss zudem der switch-case Konstrukt um die Einträge 0x0A bis 0x0F erweitert werden (siehe Listing 37, ).
|
|
void v_ConvVal(unsigned char ucValue) { switch(ucValue) { case 0x00: v_SetNextI2CVal(NULL); break; case 0x01: v_SetNextI2CVal(EINS); break; case 0x02: v_SetNextI2CVal(ZWEI); break; case 0x03: v_SetNextI2CVal(DREI); break; case 0x04: v_SetNextI2CVal(VIER); break; case 0x05: v_SetNextI2CVal(FUENF); break; case 0x06: v_SetNextI2CVal(SECHS); break; case 0x07: v_SetNextI2CVal(SIEBEN); break; case 0x08: v_SetNextI2CVal(ACHT); break; case 0x09: v_SetNextI2CVal(NEUN); break; case 0x0A: v_SetNextI2CVal(_A); break; case 0x0B: v_SetNextI2CVal(_B); break; case 0x0C: v_SetNextI2CVal(_C); break; case 0x0D: v_SetNextI2CVal(_D); break; case 0x0E: v_SetNextI2CVal(_E); break; case 0x0F: v_SetNextI2CVal(_F); break; default: break; } } |
Listing 37 Auszug aus SAA1064_LIB.c (erweitertes switch()-Konstrukt)