Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| microcontrollertechnik:8_temperatur [2023/11/12 23:25] – mexleadmin | microcontrollertechnik:8_temperatur [2024/04/23 01:23] (aktuell) – mexleadmin | ||
|---|---|---|---|
| Zeile 13: | Zeile 13: | ||
| * Eine [[https:// | * Eine [[https:// | ||
| - | </ | + | </ |
| ===== Video ===== | ===== Video ===== | ||
| + | {{youtube> | ||
| + | |||
| + | <WRAP hide> | ||
| {{youtube> | {{youtube> | ||
| + | </ | ||
| </ | </ | ||
| + | <WRAP > | ||
| + | < | ||
| + | </ | ||
| + | {{drawio> | ||
| + | </ | ||
| ===== Messsignal-Digitalisierung und Auswertung ===== | ===== Messsignal-Digitalisierung und Auswertung ===== | ||
| Zeile 272: | 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 | + | |
| - | Version : 1.1 | + | Funktion |
| + | Maximaltemperatur im Betriebszeitraum in °C mit 1/10 Grad. | ||
| + | Keine Tastenbedienung | ||
| + | |||
| + | | ||
| + | | ||
| + | |- Experiment 8 -| | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | |||
| + | | ||
| + | |||
| + | Fuses im uC: | ||
| + | |||
| + | | ||
| + | |||
| + | | ||
| + | 2) AD-Wandlung (Takt: 100 ms) | ||
| + | 3) Umrechnung fuer Temperatur | ||
| + | 4) Anzeigetreiber (Takt: | ||
| - | | ||
| - | AVR-USB-PROGI Ver. 2.0 | ||
| - | |||
| - | | ||
| - | C-Compiler: | ||
| - | |||
| - | | ||
| - | Maximaltemperatur im Betriebszeitraum in °C mit 1/10 Grad. | ||
| - | Keine Tastenbedienung | ||
| - | |||
| - | | ||
| - | | ||
| - | |- Experiment 8 -| |Temp. | ||
| - | | ||
| - | | ||
| - | |||
| - | | ||
| - | |||
| - | | ||
| - | |||
| - | Fuses im uC: | ||
| - | |||
| - | | ||
| - | |||
| - | | ||
| - | 2) AD-Wandlung (Takt: 100 ms) | ||
| - | 3) Umrechnung fuer Temperatur | ||
| - | 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: | ||
| + | |||
| + | 1-Bit-Variable: | ||
| + | => Umrechnung | ||
| + | Takt | ||
| + | |||
| + | 16-Bit-Variable: | ||
| + | t-wert | ||
| + | tmax-wert | ||
| - | Die Kopplung der Module wird ueber global definierte Variable realisiert: | ||
| - | |||
| - | | ||
| - | | ||
| - | Takt | ||
| - | |||
| - | 16-Bit-Variable: | ||
| - | t-wert Umrechnung => Anzeige | ||
| - | tmax-wert Umrechnung => Anzeige | ||
| - | |||
| // ----------------------------------------------------------------------------*/ | // ----------------------------------------------------------------------------*/ | ||
| + | |||
| // Deklarationen ============================================================== | // Deklarationen ============================================================== | ||
| + | |||
| // Festlegung der Quarzfrequenz | // Festlegung der Quarzfrequenz | ||
| - | #ifndef F_CPU // optional definieren | + | #ifndef F_CPU |
| - | #define F_CPU 12288000UL // Atmega328 mit 12,288 MHz Quarz | + | #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 418: | 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 455: | Zeile 465: | ||
| void initTimer0() | void initTimer0() | ||
| { | { | ||
| - | TCCR0A |= (0<< | + | |
| - | | (0<< | + | | (0<< |
| - | TCCR0B |= (0<< | + | TCCR0B |
| - | | (1<< | + | | (1<< |
| - | TIMSK0 |= (1<< | + | TIMSK0 |
| } | } | ||
| + | |||
| // ADC-Initialisierung ============================================================== | // ADC-Initialisierung ============================================================== | ||
| // | // | ||
| Zeile 470: | 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 486: | 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 524: | Zeile 534: | ||
| void doAdc() | void doAdc() | ||
| { | { | ||
| - | ADCSRA |= (1<< | + | |
| - | while (ADCSRA & (1<< | + | while (ADCSRA & (1<< |
| - | + | ||
| - | adcValue = ADCL + (ADCH<< | + | adcValue = ADCL + (ADCH<< |
| // | // | ||
| // | // | ||
| } | } | ||
| + | |||
| // Umrechnung ============================================================== | // Umrechnung ============================================================== | ||
| // | // | ||
| Zeile 537: | 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 558: | Zeile 568: | ||
| void refreshDisplay() | void refreshDisplay() | ||
| { | { | ||
| - | refreshDisplayTemp(tValue, | + | |
| - | refreshDisplayTemp(tValueMax, | + | refreshDisplayTemp(tValueMax, |
| } | } | ||
| + | |||
| // Anzeigetreiber fuer Temperaturanzeige ============================================================== | // Anzeigetreiber fuer Temperaturanzeige ============================================================== | ||
| // | // | ||
| Zeile 570: | 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 576: | 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 619: | 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/ | - Das Hauptprogramm ähnelt sehr stark dem [[4_up_down_counter|Up/ | ||
| - | - 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 $100~\rm ms$ (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 $1~\rm s$ (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/ | + | - Die Timer Initialisierung ist dem Programm [[4_up_down_counter|Up/ |
| '' | '' | ||
| Zeile 649: | Zeile 658: | ||
| \\ | \\ | ||
| '' | '' | ||
| - | - Die Timer-Service Routine ist dem Programm [[4_up_down_counter|Up/ | + | - Die Timer-Service Routine ist dem Programm [[4_up_down_counter|Up/ |
| '' | '' | ||
| Zeile 656: | 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 663: | Zeile 672: | ||
| - '' | - '' | ||
| - In '' | - In '' | ||
| - | \\ \\ \\ \\ \\ | + | \\ \\ \\ \\ \\ |
| '' | '' | ||