Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
microcontrollertechnik:8_temperatur [2022/02/25 21:36] tfischer |
microcontrollertechnik:8_temperatur [2024/04/23 01:23] (aktuell) mexleadmin |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== 8. Temperatur-Messung und Analog-Digital-Wandler ====== | + | ====== 8 Temperatur-Messung und Analog-Digital-Wandler ====== |
- | ===== ADC - wie kommt mehr als nur ein Bit über einen Pin? ===== | ||
<WRAP group> | <WRAP group> | ||
<WRAP column 30%> | <WRAP column 30%> | ||
- | ==== Ziele ==== | + | ===== Ziele ===== |
Nach dieser Lektion sollten Sie: | Nach dieser Lektion sollten Sie: | ||
Zeile 11: | Zeile 10: | ||
- wissen, wie ein ADC genutzt wird | - wissen, wie ein ADC genutzt wird | ||
- | ==== weiterführende Links ==== | + | ===== weiterführende Links ===== |
* Eine [[https:// | * Eine [[https:// | ||
- | </ | + | </ |
- | ==== Video ==== | + | ===== Video ===== |
+ | {{youtube> | ||
+ | |||
+ | <WRAP hide> | ||
{{youtube> | {{youtube> | ||
+ | </ | ||
</ | </ | ||
- | ==== Messsignal-Digitalisierung und Auswertung ==== | + | <WRAP > |
+ | < | ||
+ | </ | ||
+ | {{drawio> | ||
+ | </ | ||
+ | ===== Messsignal-Digitalisierung und Auswertung | ||
<WRAP right> | <WRAP right> | ||
< | < | ||
</ | </ | ||
- | {{drawio> | + | {{drawio> |
</ | </ | ||
Um Sensorwerte in C sinnvoll nutzen zu können sind einige Schritte zwischen dem passiven Sensor über den ADC bis in den Code umzusetzen (siehe <imgref BildNr1> | Um Sensorwerte in C sinnvoll nutzen zu können sind einige Schritte zwischen dem passiven Sensor über den ADC bis in den Code umzusetzen (siehe <imgref BildNr1> | ||
- | - Sensor: $T \rightarrow R_{NTC}$\\ Umwandlung der physikalischen Größe in ein Messsignal \\ \\ | + | - Sensor: $T \rightarrow R_{\rm NTC}$\\ Umwandlung der physikalischen Größe in ein Messsignal \\ \\ |
- | - Sensorschaltung: | + | - Sensorschaltung: |
- | - ADC: $V_{NTC} \rightarrow adcValue$\\ Digitalisierung in ein Zahlenwert im Code \\ \\ | + | - ADC: $V_{\rm NTC} \rightarrow adcValue$\\ Digitalisierung in ein Zahlenwert im Code \\ \\ |
- Aufbereitung im Code $adcValue \rightarrow tValue$ \\ um ein Abbild des Sensorwerts zu erhalten \\ \\ | - Aufbereitung im Code $adcValue \rightarrow tValue$ \\ um ein Abbild des Sensorwerts zu erhalten \\ \\ | ||
Zeile 39: | Zeile 47: | ||
<WRAP group>< | <WRAP group>< | ||
< | < | ||
- | ^Temperatur\\ $T$ ^Widerstandswert $R_{NTC}$^ | + | ^Temperatur\\ $T$ ^Widerstandswert $R_{\rm NTC}$^ |
- | |$5°C$ | + | |$5° \rm C$ |
- | |$10°C$ |$9,34k\Omega$ | + | |$10°\rm C$ |
- | |$15°C$ |$7,37k\Omega$ | + | |$15°\rm C$ |
- | | ... | ... | | + | | ... |
</ | </ | ||
</ | </ | ||
Zeile 49: | Zeile 57: | ||
< | < | ||
^ADC-Wert \\ $adcValue$ ^Temperatur \\ $T$ | ^ADC-Wert \\ $adcValue$ ^Temperatur \\ $T$ | ||
- | |$256$ | + | |$256$ |
- | |$272$ | + | |$272$ |
- | |$288$ | + | |$288$ |
- | | ... | ... | | + | | ... | ... | |
</ | </ | ||
</ | </ | ||
Zeile 65: | Zeile 73: | ||
~~PAGEBREAK~~ ~~CLEARFIX~~ | ~~PAGEBREAK~~ ~~CLEARFIX~~ | ||
- | === 1.a Umwandlung der physikalischen Größe in ein Messsignal (Sensorwert zu Widerstandswert) === | + | ==== 1.a Umwandlung der physikalischen Größe in ein Messsignal (Sensorwert zu Widerstandswert) ==== |
- | ---- | + | |
* Bei vielen passiven Sensoren wird der Sensorwert in eine Widerstandsänderung umgewandelt. Die Relation von Sensorwert zu Widerstandswert ist im Datenblatt des Sensors angegeben. | * Bei vielen passiven Sensoren wird der Sensorwert in eine Widerstandsänderung umgewandelt. Die Relation von Sensorwert zu Widerstandswert ist im Datenblatt des Sensors angegeben. | ||
Zeile 89: | Zeile 96: | ||
</ | </ | ||
- | === 2. + 3. Relation von Widerstandswert zu ADC-Wert === | + | ==== 2. + 3. Relation von Widerstandswert zu ADC-Wert ==== |
- | ---- | + | |
<WRAP right> | <WRAP right> | ||
< | < | ||
</ | </ | ||
- | {{drawio> | + | {{drawio> |
</ | </ | ||
Zeile 104: | Zeile 110: | ||
Die Spannung am ADC lässt sich leicht über den Widerstandswert berechnen: | Die Spannung am ADC lässt sich leicht über den Widerstandswert berechnen: | ||
- | \begin{align} {{V_{NTC}} \over {V_{CC}}} = {{R_{NTC}}\over{R_{NTC} + R_{pullup}}} \tag{8.1} \end{align} | + | \begin{align} {{V_{\rm NTC}} \over {V_{\rm CC}}} = {{R_{\rm NTC}}\over{R_{\rm NTC} + R_{\rm pullup}}} \tag{8.1} \end{align} |
Daraus ergibt sich der digitalisierte Wert zu | Daraus ergibt sich der digitalisierte Wert zu | ||
- | \begin{align} ADCwert = round \left({{V_{NTC}}\over{V_{CC}}} \cdot 1024 \right) \tag{8.2} \end{align} | + | \begin{align} ADCwert = {\rm round} \left({{V_{\rm NTC}}\over{V_{\rm CC}}} \cdot 1024 \right) \tag{8.2} \end{align} |
aus $(8.1)$ und $(8.2)$ ergibt sich | aus $(8.1)$ und $(8.2)$ ergibt sich | ||
- | \begin{align} ADCwert = round \left({{R_{NTC}}\over{R_{NTC} + R_{pullup}}} \cdot 1024 \right) \tag{8.3} \end{align} | + | \begin{align} ADCwert = {\rm round} \left({{R_{\rm NTC}}\over{R_{\rm NTC} + R_{\rm pullup}}} \cdot 1024 \right) \tag{8.3} \end{align} |
Diese Relation muss nun im Analyse-Tool abgebildet werden und wurde in {{microcontrollertechnik: | Diese Relation muss nun im Analyse-Tool abgebildet werden und wurde in {{microcontrollertechnik: | ||
Zeile 119: | Zeile 125: | ||
* Einfügen einer Trendlinie: Für das Diagramm wurde ADCval als x-Werte und $R\_NTC$ als y-Werte verwendet. Für die Trendlinie wurde ein Polynom 4. Grades genutzt. Mit Anzeige der Trendlinien-Formel wird die Relation von Widerstandswert zu ADC-Wert sichtbar. Die Zahl-Eigenschaft der Trendlinienbeschriftung sollte dabei auf '' | * Einfügen einer Trendlinie: Für das Diagramm wurde ADCval als x-Werte und $R\_NTC$ als y-Werte verwendet. Für die Trendlinie wurde ein Polynom 4. Grades genutzt. Mit Anzeige der Trendlinien-Formel wird die Relation von Widerstandswert zu ADC-Wert sichtbar. Die Zahl-Eigenschaft der Trendlinienbeschriftung sollte dabei auf '' | ||
- | === 4. Aufbereitung der des ADC-Werts im Code === | + | ==== 4. Aufbereitung der des ADC-Werts im Code ==== |
- | ---- | + | |
- | Mit den bisherigen Betrachtungen ist zwar klar, wie die Relation von Widerstandswert zu ADC-Wert aussieht, aber diese ist noch nicht im Code umgesetzt. Zunächst sollte der notwendige Wertebereich geklärt werden: In welchem Bereich werden Messwerte erwartet? In diesem Konkreten Fall geht es um die Innenraumtemperatur. Damit wird die Temperatur im Bereich $[-30°C, 50°C]$ sein. | + | Mit den bisherigen Betrachtungen ist zwar klar, wie die Relation von Widerstandswert zu ADC-Wert aussieht, aber diese ist noch nicht im Code umgesetzt. Zunächst sollte der notwendige Wertebereich geklärt werden: In welchem Bereich werden Messwerte erwartet? In diesem Konkreten Fall geht es um die Innenraumtemperatur. Damit wird die Temperatur im Bereich $[-30°\rm C, 50°\rm C]$ sein. |
\\ \\ | \\ \\ | ||
Zeile 154: | Zeile 159: | ||
< | < | ||
</ | </ | ||
- | {{drawio> | + | {{drawio> |
</ | </ | ||
</ | </ | ||
Zeile 161: | Zeile 166: | ||
\\ \\ | \\ \\ | ||
- | == direkte Verwendung der Datenblattwerte mit Interpolation == | + | === direkte Verwendung der Datenblattwerte mit Interpolation |
<WRAP group> | <WRAP group> | ||
Zeile 207: | Zeile 212: | ||
< | < | ||
</ | </ | ||
- | {{drawio> | + | {{drawio> |
</ | </ | ||
</ | </ | ||
Zeile 213: | Zeile 218: | ||
Die Auflösung ist nun sehr genau (vgl. <imgref BildNr3> | Die Auflösung ist nun sehr genau (vgl. <imgref BildNr3> | ||
- | Der float-Wert kann umgangen werden, wenn im gesamten Programm die Temperaturwerte in Zehntel-Grad geschrieben werden. Also 37,5°C $\rightarrow$ 375. Dann kann ein tValue als signed integer geschrieben werden. | + | Der float-Wert kann umgangen werden, wenn im gesamten Programm die Temperaturwerte in Zehntel-Grad geschrieben werden. Also $37,5°\rm C \rightarrow$ 375. Dann kann ein tValue als signed integer geschrieben werden. |
\\ \\ | \\ \\ | ||
- | == Umrechnung der Datenblattwerte == | + | === Umrechnung der Datenblattwerte |
<WRAP group> | <WRAP group> | ||
Zeile 232: | Zeile 237: | ||
< | < | ||
</ | </ | ||
- | {{drawio> | + | {{drawio> |
</ | </ | ||
</ | </ | ||
Zeile 240: | Zeile 245: | ||
~~PAGEBREAK~~ ~~CLEARFIX~~ | ~~PAGEBREAK~~ ~~CLEARFIX~~ | ||
- | ==== Übung ==== | + | ===== Übung |
--> I. Vorarbeiten # | --> I. Vorarbeiten # | ||
- Laden Sie folgenden Dateien herunter: | - Laden Sie folgenden Dateien herunter: | ||
- | - {{microcontrollertechnik: | + | - {{microcontrollertechnik: |
- {{microcontrollertechnik: | - {{microcontrollertechnik: | ||
- {{microcontrollertechnik: | - {{microcontrollertechnik: | ||
+ | |||
+ | \\ \\ | ||
+ | <callout type=" | ||
+ | |||
+ | **Beachten Sie, folgendes** | ||
+ | * Es wird nun ein ATmega328 genutzt, d.h. das Programm ist nicht mehr kompatibel mit dem MiniMEXLE! | ||
+ | * Das Display ist nunan einem anderen Port um den Analog-Digial-Wandler am Port C zu nutzen. \\ Deshalb muss der Treiber '' | ||
+ | * Zeile 26: ''# | ||
+ | * Zeile 39: ''# | ||
+ | * Zeile 40: ''# | ||
+ | * Zeile 44: ''# | ||
+ | * Zeile 46: ''# | ||
+ | |||
+ | </ | ||
+ | \\ \\ | ||
+ | |||
+ | |||
<-- | <-- | ||
Zeile 259: | Zeile 281: | ||
<-- | <-- | ||
- | --> III. Eingabe in Atmel Studio # | + | --> III. Eingabe in Microchip |
+ | |||
<WRAP group>< | <WRAP group>< | ||
/* ---------------------------------------------------------------------------- | /* ---------------------------------------------------------------------------- | ||
- | + | ||
- | | + | |
| | ||
+ | |||
| | ||
+ | | ||
+ | | ||
+ | Prof. G. Gruhler | ||
+ | D. Chilachava | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | AVR-USB-PROGI Ver. 2.0 | ||
- | Autoren : Peter Blinzinger | + | Software: |
- | Prof. G. Gruhler (Hochschule Heilbronn, Fakultaet T1) | + | |
- | D. Chilachava (Georgische Technische Universitaet) | + | |
- | | + | |
- | Datum : 01.05.2020 | + | |
- | | ||
- | |||
- | | ||
- | AVR-USB-PROGI Ver. 2.0 | ||
- | |||
- | | ||
- | C-Compiler: | ||
- | |||
| | ||
- | Maximaltemperatur im Betriebszeitraum in °C mit 1/10 Grad. | + | |
- | Keine Tastenbedienung | + | Keine Tastenbedienung |
- | + | ||
- | | + | |
- | +----------------+ +----------------+ | + | |
- | |- Experiment 8 -| |Temp. | + | |
- | | Temperature | + | |
- | +----------------+ +----------------+ | + | |
- | + | ||
- | | + | |
- | + | ||
- | | + | |
- | + | ||
- | Fuses im uC: CKDIV8: Aus (keine generelle Vorteilung des Takts) | + | Fuses im uC: |
- | + | ||
- | | + | |
- | + | ||
- | | + | |
- | 2) AD-Wandlung (Takt: 100 ms) | + | 2) AD-Wandlung (Takt: 100 ms) |
- | 3) Umrechnung fuer Temperatur | + | 3) Umrechnung fuer Temperatur |
- | 4) Anzeigetreiber (Takt: 1 s) | + | 4) Anzeigetreiber (Takt: 1 s) |
+ | |||
1) Das Modul " | 1) Das Modul " | ||
- | | + | |
- | + | ||
- | Verwendung von Hardware-Timer 0 und T0 Overflow-Interrupt. | + | Verwendung von Hardware-Timer 0 und T0 Overflow-Interrupt. |
- | Frequenzen: Quarzfrequenz | + | Frequenzen: Quarzfrequenz |
- | Timer-Vorteiler / 8 => | + | Timer-Vorteiler |
- | Hardware-Timer | + | Hardware-Timer |
- | Software-Vorteiler | + | Software-Vorteiler |
- | Hundertstel-Zaehler / | + | Hundertstel-Zaehler / 10 => 10 Hz / 100 ms |
- | Zehntel-Zaehler / 10 => | + | Zehntel-Zaehler |
+ | |||
2) Das Modul " | 2) Das Modul " | ||
Der AD-Wandler wird mit einem internen Takt von 96 kHz betrieben. | Der AD-Wandler wird mit einem internen Takt von 96 kHz betrieben. | ||
- | | + | |
Aufloesung gestartet. Dort ist der NTC des Boards mit Vorwiderstand | Aufloesung gestartet. Dort ist der NTC des Boards mit Vorwiderstand | ||
als temperaturabhaengiger Spannungsteiler bzw. Potentiometer angeschlossen. | als temperaturabhaengiger Spannungsteiler bzw. Potentiometer angeschlossen. | ||
Als Referenzspannung wird die 5V-Versorgung verwendet. | Als Referenzspannung wird die 5V-Versorgung verwendet. | ||
Das Ergebnis wird in der globalen Variable tValue gespeichert. | Das Ergebnis wird in der globalen Variable tValue gespeichert. | ||
+ | |||
3) Das Modul " | 3) Das Modul " | ||
Der Ergebniswert des Moduls " | Der Ergebniswert des Moduls " | ||
einen entsprechenden Temperaturwert umgerechnet. In der Tabelle sind | einen entsprechenden Temperaturwert umgerechnet. In der Tabelle sind | ||
Temperaturwerte ueber aequidistante (Abstand = 16) AD-Werte aufgetragen. | Temperaturwerte ueber aequidistante (Abstand = 16) AD-Werte aufgetragen. | ||
- | | + | |
Weiterhin wird im Modul jede aktuelle Temperatur mit der gespeicherten | Weiterhin wird im Modul jede aktuelle Temperatur mit der gespeicherten | ||
- | | + | |
+ | |||
4) Das Modul " | 4) Das Modul " | ||
zu schnelles Umschalten der Anzeigewerte vermieden. Das Modul gibt die | zu schnelles Umschalten der Anzeigewerte vermieden. Das Modul gibt die | ||
Werte der aktuellen und der maximalen Temperatur in 1/10 °C aus. | Werte der aktuellen und der maximalen Temperatur in 1/10 °C aus. | ||
- | | + | |
- | | + | Zwischen AD-Wandlung / Umrechnung und Anzeige kann spaeter noch eine |
- | | + | Mittelwertsbildung mit 10 Werten eingefuegt werden. |
- | + | ||
Die Kopplung der Module wird ueber global definierte Variable realisiert: | Die Kopplung der Module wird ueber global definierte Variable realisiert: | ||
- | + | ||
- | | + | 1-Bit-Variable: |
- | | + | => Umrechnung |
- | Takt | + | Takt |
- | + | ||
- | | + | 16-Bit-Variable: |
- | t-wert Umrechnung => Anzeige | + | t-wert |
- | tmax-wert Umrechnung => Anzeige | + | tmax-wert |
+ | |||
// ----------------------------------------------------------------------------*/ | // ----------------------------------------------------------------------------*/ | ||
+ | |||
// Deklarationen ============================================================== | // Deklarationen ============================================================== | ||
+ | |||
// Festlegung der Quarzfrequenz | // Festlegung der Quarzfrequenz | ||
- | #ifndef F_CPU // optional definieren | + | #ifndef F_CPU |
- | #define F_CPU 12288000UL // MiniMEXLE | + | #define F_CPU 12288000UL |
- | #endif | + | # |
+ | |||
// Include von Header-Dateien | // Include von Header-Dateien | ||
- | #include < | + | #include < |
- | #include < | + | #include < |
- | #include < | + | #include < |
- | #include " | + | #include " |
+ | |||
// Konstanten | // Konstanten | ||
- | # | + | # |
- | # | + | # |
- | # | + | # |
#define ASC_NULL | #define ASC_NULL | ||
#define ASC_FULL_STOP | #define ASC_FULL_STOP | ||
- | + | ||
- | const int TEMP[45] | + | const int |
- | 338, | + | 338, |
- | 193, | + | 193, |
- | 48, | + | 48, |
- | -145, | + | -145, |
- | + | ||
- | // Die Tabellenwerte sind in 1/10 °C angegeben | + | // Die Tabellenwerte sind in 1/10 °C angegeben |
- | // Der erste Tabellenwert entspricht einem AD-Wert | + | // Der erste Tabellenwert entspricht einem AD-Wert |
- | // von 256. Die Abstaende der AD-Werte sind 16 | + | // von 256. Die Abstaende der AD-Werte sind 16 |
+ | |||
// Variable | // Variable | ||
- | unsigned char vorteiler = VORTEILER_WERT; // Zaehlvariable Vorteiler | + | unsigned char softwarePrescaler |
- | unsigned char hundertstel = HUNDERTSTEL_WERT; | + | unsigned char cycle10msCount |
- | unsigned char zehntel | + | unsigned char cycle100msCount |
- | + | ||
- | unsigned int adcValue = 0; // Variable fuer den AD-Wandlungswert | + | unsigned int adcValue |
- | int tValue = 0; // Variable fuer die Temperatur (in 1/10 °C) | + | int |
- | int tValueMax =-300; | + | int |
- | + | ||
- | bool takt10ms; // Bit-Botschaft alle 10 ms | + | bool |
- | bool takt100ms; // Bit-Botschaft alle 100 ms | + | bool |
- | bool takt1s; // Bit-Botschaft alle 1s | + | bool |
+ | |||
// | // | ||
void initTimer0 (void); | void initTimer0 (void); | ||
Zeile 403: | Zeile 428: | ||
void refreshDisplayTemp(int tempValue, char line, char pos); | void refreshDisplayTemp(int tempValue, char line, char pos); | ||
void refreshDisplay (void); | void refreshDisplay (void); | ||
+ | |||
// Hauptprogramm ============================================================== | // Hauptprogramm ============================================================== | ||
int main () | int main () | ||
{ | { | ||
- | initDisplay(); | + | |
- | initTimer0(); | + | initTimer0(); |
- | initAdc(); | + | initAdc(); |
- | + | ||
- | sei(); // generell Interrupts einschalten | + | sei(); |
- | + | | |
- | // Hauptprogrammschleife __________________________________________________ | + | // Hauptprogrammschleife __________________________________________________ |
- | + | ||
- | while(1) // unendliche Warteschleife mit Aufruf der | + | while(1) |
- | // Funktionen abhaengig von Taktbotschaften | + | // Funktionen abhaengig von Taktbotschaften |
- | { | + | { |
- | if(takt100ms) // Durchfuehrung der Funktion einmal pro 100ms | + | if(cycle100msActive) // Durchfuehrung der Funktion einmal pro 100ms |
- | { | + | { |
- | takt100ms | + | |
- | doAdc(); // Ausfuehrung des Modules der A/ | + | doAdc(); |
- | calculateTemp(); | + | calculateTemp(); |
- | } | + | } |
- | + | ||
- | if(takt1s) // Durchfuehrung der Anzeige einmal pro 1s | + | if(cycle1sActive) |
- | { | + | { |
- | takt1s | + | |
- | refreshDisplay(); | + | refreshDisplay(); |
- | } | + | } |
- | } | + | } |
} | } | ||
- | + | ||
+ | |||
// Timer Initialisierung ============================================================== | // Timer Initialisierung ============================================================== | ||
// | // | ||
Zeile 440: | Zeile 465: | ||
void initTimer0() | void initTimer0() | ||
{ | { | ||
- | TCCR0A |= (0<< | + | |
- | | (0<< | + | | (0<< |
- | TCCR0B |= (0<< | + | TCCR0B |
- | | (1<< | + | | (1<< |
- | TIMSK0 |= (1<< | + | TIMSK0 |
} | } | ||
+ | |||
// ADC-Initialisierung ============================================================== | // ADC-Initialisierung ============================================================== | ||
// | // | ||
Zeile 455: | Zeile 480: | ||
void initAdc() | void initAdc() | ||
{ | { | ||
- | ADMUX |= (1<< | + | |
- | + | ||
- | ADCSRA |= (1<< | + | ADCSRA |
- | | (1<< | + | | (1<< |
- | | (1<< | + | | (1<< |
- | | (1<< | + | | (1<< |
- | (void) ADCH; // erster Wert ist " | + | (void) ADCH; // erster Wert ist " |
} | } | ||
- | + | ||
+ | |||
// Timer-Service Routine ============================================================== | // Timer-Service Routine ============================================================== | ||
// | // | ||
Zeile 471: | Zeile 496: | ||
// werden von Timer 0 ausgeloest (Interrupt Nr. 1) | // werden von Timer 0 ausgeloest (Interrupt Nr. 1) | ||
// | // | ||
- | // Veraenderte Variable: | + | // Veraenderte Variable: |
- | // hunderstel | + | // hunderstel |
- | // zehntel | + | // zehntel |
// | // | ||
- | // Ausgangsvariable: | + | // Ausgangsvariable: |
- | // takt100ms | + | // takt100ms |
- | // takt1s | + | // takt1s |
+ | |||
ISR (TIMER0_OVF_vect) | ISR (TIMER0_OVF_vect) | ||
{ | { | ||
- | --vorteiler; // Vorteiler dekrementieren | + | |
- | if (vorteiler==0) // wenn 0 erreicht: 10ms abgelaufen | + | if (softwarePrescaler==0) // wenn 0 erreicht: 10ms abgelaufen |
- | { | + | { |
- | vorteiler | + | |
- | takt10ms | + | |
- | --hundertstel; // Hundertstelzaehler dekrementieren | + | --cycle10msCount; // Hundertstelzaehler dekrementieren |
- | + | ||
- | if (hundertstel==0) // wenn 0 erreicht: 100ms abgelaufen | + | if (cycle10msCount==0) // wenn 0 erreicht: 100ms abgelaufen |
- | { | + | { |
- | hundertstel | + | |
- | takt100ms | + | |
- | --zehntel; | + | --cycle100msCount; |
- | + | ||
- | if (zehntel==0) // Zehntelzaehler dekrementieren | + | if (cycle100msCount==0) |
- | { | + | { |
- | zehntel | + | |
- | takt1s | + | |
- | } | + | } |
- | } | + | } |
- | } | + | } |
} | } | ||
+ | |||
// ADWandlung ============================================================== | // ADWandlung ============================================================== | ||
// | // | ||
Zeile 509: | Zeile 534: | ||
void doAdc() | void doAdc() | ||
{ | { | ||
- | ADCSRA |= (1<< | + | |
- | while (ADCSRA & (1<< | + | while (ADCSRA & (1<< |
- | + | ||
- | adcValue = ADCL + (ADCH<< | + | adcValue = ADCL + (ADCH<< |
// | // | ||
// | // | ||
} | } | ||
+ | |||
// Umrechnung ============================================================== | // Umrechnung ============================================================== | ||
// | // | ||
Zeile 522: | Zeile 547: | ||
void calculateTemp () | void calculateTemp () | ||
{ | { | ||
- | unsigned char index; // Tabellenindex fuer Temperaturtabelle | + | |
- | unsigned char steps; // Abstand zum naechstkleineren Wert | + | unsigned char steps; |
- | // der AD-Werte der Temperaturtabelle | + | // der AD-Werte der Temperaturtabelle |
- | + | | |
- | index = (adcValue-256)/ | + | index |
- | steps = (adcValue-256)%16; | + | steps |
- | + | | |
- | tValue = steps * (TEMP[index+1] - TEMP[index])/ | + | tValue = steps * (TEMP[index+1] - TEMP[index])/ |
- | // Temperaturwert berechnen | + | // Temperaturwert berechnen |
- | + | ||
- | if(tValue> | + | if(tValue> |
- | { | + | { |
- | tValueMax = tValue; // vergleichen und ggf. ersetzen | + | tValueMax = tValue; |
- | } | + | } |
} | } | ||
+ | |||
// Anzeigefunktion ============================================================== | // Anzeigefunktion ============================================================== | ||
// | // | ||
Zeile 543: | Zeile 568: | ||
void refreshDisplay() | void refreshDisplay() | ||
{ | { | ||
- | refreshDisplayTemp(tValue, | + | |
- | refreshDisplayTemp(tValueMax, | + | refreshDisplayTemp(tValueMax, |
} | } | ||
+ | |||
// Anzeigetreiber fuer Temperaturanzeige ============================================================== | // Anzeigetreiber fuer Temperaturanzeige ============================================================== | ||
// | // | ||
Zeile 555: | Zeile 580: | ||
// Hunderter: einfache Integer-Teilung (/100). | // Hunderter: einfache Integer-Teilung (/100). | ||
// Zehner: Modulo-Ermittlung (%100), d.h. Rest bei der Teilung durch 100 | // Zehner: Modulo-Ermittlung (%100), d.h. Rest bei der Teilung durch 100 | ||
- | // dann nochmals Integer-Teilung (/10) dieses Restes. | + | // |
// Einer: | // Einer: | ||
// | // | ||
Zeile 561: | Zeile 586: | ||
void refreshDisplayTemp(int tempValue, char line, char pos) | void refreshDisplayTemp(int tempValue, char line, char pos) | ||
{ | { | ||
- | lcd_gotoxy(line, | + | |
- | if (tempValue> | + | if (tempValue> |
- | { | + | { |
- | lcd_putc(' | + | lcd_putc(' |
- | } | + | } |
- | else | + | else |
- | { | + | { |
- | lcd_putc(' | + | lcd_putc(' |
- | tempValue = -tempValue; | + | tempValue = -tempValue; |
- | } | + | } |
- | lcd_putc | + | lcd_putc |
- | tempValue = tempValue%100; | + | tempValue = tempValue%100; |
- | lcd_putc | + | lcd_putc |
- | lcd_putc | + | lcd_putc |
- | lcd_putc | + | lcd_putc |
} | } | ||
+ | |||
// Initialisierung Display-Anzeige ============================================================== | // Initialisierung Display-Anzeige ============================================================== | ||
// | // | ||
- | void initDisplay() // Start der Funktion | + | void initDisplay() |
{ | { | ||
- | lcd_init(); | + | |
- | + | | |
- | lcd_displayMessage(" | + | lcd_displayMessage(" |
- | lcd_displayMessage(" | + | lcd_displayMessage(" |
- | + | ||
- | _delay_ms(2000); | + | _delay_ms(2000); |
- | + | ||
- | lcd_displayMessage(" | + | lcd_displayMessage(" |
- | lcd_displayMessage(" | + | lcd_displayMessage(" |
- | // " | + | // " |
- | } // Ende der Funktion | + | } |
</ | </ | ||
</ | </ | ||
Zeile 604: | Zeile 628: | ||
- Hier wird wieder geprüft ob die Frequenz des Quarz bereits eingestellt wurde und - falls nicht - dessen Frequenz eingestellt. \\ \\ | - Hier wird wieder geprüft ob die Frequenz des Quarz bereits eingestellt wurde und - falls nicht - dessen Frequenz eingestellt. \\ \\ | ||
- Die Header-Dateien entsprechen denen der letzten Programme. \\ \\ \\ \\ \\ | - Die Header-Dateien entsprechen denen der letzten Programme. \\ \\ \\ \\ \\ | ||
- | - Die Konstanten entsprechen denen der letzten Programme. \\ \\ \\ \\ | + | - Die Konstanten entsprechen denen der letzten Programme. |
- | - Es wird eine zusätzliches Array '' | + | - Es wird eine zusätzliches Array '' |
- | - Bei den Variablen entsprechen einige denen der letzten Programme. | + | - Bei den Variablen entsprechen einige denen der letzten Programme. \\ \\ \\ \\ |
- Die Variable '' | - Die Variable '' | ||
- Die Variable '' | - Die Variable '' | ||
- Die Variable '' | - Die Variable '' | ||
- | - Bei den Funktionsprototypen sind einige bekannte Unterprogramme vorhanden. Details werden weiter unten erklärt. \\ \\ \\ \\ | + | - Bei den Funktionsprototypen sind einige bekannte Unterprogramme vorhanden. Details werden weiter unten erklärt. |
'' | '' | ||
- | - Das Hauptprogramm ähnelt sehr stark dem [[4._up_down_counter|Up/Down Counter]], wobei die Initialisierung des Timers in eine Unterfunktion '' | + | - Das Hauptprogramm ähnelt sehr stark dem [[4_up_down_counter|Up/Down Counter]], wobei die Initialisierung des Timers in eine Unterfunktion '' |
- | - In der Endlosschleife sind auf der ersten Ebene wieder nur If-Abfragen zu den Flags '' | + | - In der Endlosschleife sind auf der ersten Ebene wieder nur If-Abfragen zu den Flags '' |
- | - Alle $100ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm '' | + | - Alle $100~\rm ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm '' |
- | - Alle $1s$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm '' | + | - Alle $1~\rm s$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm '' |
'' | '' | ||
- | - Die Timer Initialisierung ist dem Programm [[4._up_down_counter|Up/Down Counter]] entlehnt und wird hier nicht weiter erklärt. | + | - Die Timer Initialisierung ist dem Programm [[4_up_down_counter|Up/Down Counter]] entlehnt und wird hier nicht weiter erklärt. |
'' | '' | ||
Zeile 630: | Zeile 654: | ||
< | < | ||
</ | </ | ||
- | {{drawio> | + | {{drawio> |
</ | </ | ||
\\ | \\ | ||
'' | '' | ||
- | - Die Timer-Service Routine ist dem Programm [[4._up_down_counter|Up/Down Counter]] entlehnt und wird hier nicht weiter erklärt. \\ \\ | + | - Die Timer-Service Routine ist dem Programm [[4_up_down_counter|Up/Down Counter]] entlehnt und wird hier nicht weiter erklärt. |
'' | '' | ||
Zeile 641: | Zeile 665: | ||
- Das Register '' | - Das Register '' | ||
- immer erst ADCL auslesen, dann ADCH. | - immer erst ADCL auslesen, dann ADCH. | ||
- | - immer auch ADCH auslesen, selbst wenn es nicht benötigt wird. \\ | + | - immer auch ADCH auslesen, selbst wenn es nicht benötigt wird. \\ \\ |
'' | '' | ||
Zeile 648: | Zeile 672: | ||
- '' | - '' | ||
- In '' | - In '' | ||
- | \\ \\ \\ \\ \\ | + | \\ \\ \\ \\ \\ |
'' | '' |