Netzwerk-Aufbau mit Scalance von Siemens


Google-Suche auf MEINE-SCHALTUNG.de :





Online Rechner

Chronik

Dauerkalender


Temperaturmessung mit PIC12F615

Es gilt ein einfaches Thermometer, das Temperatur mit großzügiger Toleranz von +/- 2°C im Bereich von 10°C bis 50°C misst, aufzubauen. Die aktuell gemessene Temperatur soll mithilfe einer 7-Segmentanzeige sichtbar gemacht werden. Die Messung und notwendige Berechnungen soll der Mikrocontroller PIC 12F615 übernehmen. Zusätzlich soll die dazugehörige Schaltung mit einer Warnleuchte (Leuchtdiode) versehen werden, die signalisiert, dass der Rand des festgelegten Messbereiches unter- oder überschritten wurde.
In der Schaltung geht es vorrangig um die Erfassung eines analogen Wertes und Steuerung eines Schieberegisters mit einem PIC, in diesem Fall PIC12F615. Des Weiteren wird im Programm auf einfache Weise die Parabel, die die Abhängigkeit des Widerstandes des NTC-Widerstandes von Temperatur beschreibt, linearisiert.

PIC12F615

PIC12F615

Die Wahl eines Mikrocontrollers hängt von der gestellten Aufgabe ab. Eine einfache Temperaturmessung wäre sicher auch mit anderen PICs problemlos realisierbar. Soll der Mikrocontroller weitere Aufgaben übernehmen, weitere Signale verarbeiten oder weitere Abnehmer schalten, muss man sich nach einem Mikrocontroller mit größeren Kapazitäten umschauen. Der PIC12F615 mit sechs I/Os ist eher für kleine Aufgaben gedacht.

Schieberegister 74HC595

Schieberegister 74HC595

Der Mikrocontroller PIC12F615 stellt zu wenig „Beinchen“ zur Verfügung, um eine 7-Segmentanzeige direkt anzusteuern, geschweige mehrere. Da in dem Beispiel gleich zwei 7-Segmentanzeigen zum Einsatz kommen, bedeutet das, dass 14 Elemente der Anzeigen angesteuert werden müssen. Eine Lösung des Problems, die hier zur Anwendung kommt, bieten Schieberegister an. Der Schieberegister 74HC595 stellt acht Ausgänge zur Verfügung, womit eine 7-Segmentanzeige problemlos mit Spannung versorgt werden kann. Die Schieberegister lassen sich nacheinander aufschalten (Kaskadenschaltung), wodurch weitere Steuerleitungen eingespart werden können. In der Schaltung werden von dem PIC lediglich drei Pins in Anspruch genommen, um alle 14 Elemente der beiden Anzeigen anzusteuern.

7-Segmentanzeige

7-Segmentanzeige

Eine 7-Segmentanzeige ist nichts anderes als eine Zusammenstellung von sieben Leuchtdioden, die als kurze Balken in einem Gehäuse ausgeführt werden. Die einzelnen Balken sind so zueinander angeordnet, dass eine Darstellung von allen Ziffern 0 bis 9 und einigen Buchstaben sowie Sonderzeichen möglich ist. Die 7-Segmentanzeige 5101AH hat zusätzlich noch einen weiteren Anschluss, mit dem die achte Leuchtdiode, die in der Anzeige als Punkt fungiert, aktiviert werden kann. Diese Erweiterung wird in unserer Schaltung nicht in Anspruch genommen.

7-Segmentanzeige

NTC

NTC

NTC / 10kOhm
NTC ist ein temperaturabhängiger Widerstand. NTC werden sehr oft für Temperaturmessung eingesetzt. NTC hat einen geringeren Widerstand bei höheren Temperaturen.

Die Messung der Temperatur basiert auf dem temperaturabhängigen Widerstand R16, der in Reihe mit dem Widerstand R15 geschaltet ist. Der Widerstandswert von R16 ändert sich abhängig von der Temperatur. In diesem Fall handelt es sich um einen NTC, dessen Widerstand mit steigender Temperatur fällt (Heißleiter). Beide Widerstände, R16 und R15 bilden einen Spannungsteiler. Die Spannung, die zwischen den beiden Widerständen gebildet wird, geht auf den analogen Eingang des PIC-Mikrocontrollers GP0 und wird direkt zur Bestimmung der Temperatur verwendet.
Die Änderung des Widerstandswertes von R16 bei Temperaturänderungen verläuft nach einer Kurve, die auf dem folgenden Bild dargestellt ist:

Temperaturverlauf

Um aus der ermittelten Spannung die Temperatur exakt abzuleiten, müsste die Grundformel eines NTCs angewendet werden:

NTC Formel


NTC - E-Rechner

In dem Beispiel werden wir diese Formel umgehen und auf Berechnungen mit float-Variablen, die viel Speicherplatz beanspruchen, verzichten. Stattdessen teilen wir die Kurve in kleine Intervalle von 10°C Breite und linearisieren sie. Je kleiner die Aufteilung, umso genauer die Ergebnisse. Für jeden Abschnitt kann man dann sagen, dass die Spannung am Spannungsteiler direkt proportional zu der Temperatur ist. Die Temperatur wird dann durch Anwendung der einfachen Dreisatz-Formel berechnet.

Berechnungen



Schaltplan

Schaltplan

Schaltplan


Testschaltung

Testschaltung

Testschaltung

Programm

// *****************************************************************************************
// Temperaturmessung mit PIC12F615
// MPLAB X IDE v6.00
// XC8-Compiler 2.4
// *****************************************************************************************
             
// PIC12F615 Configuration Bit Settings
// CONFIG
#pragma config FOSC = INTOSCIO       // Oscillator Selection bits (INTOSCIO oscillator: I/O 
                                     // function on GP4/OSC2/CLKOUT pin, I/O function on 
                                     // GP5/OSC1/CLKIN)
#pragma config WDTE = OFF            // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF           // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF           // MCLR Pin Function Select bit (MCLR pin function is 
                                     // digital input, MCLR internally tied to VDD)
#pragma config CP = OFF              // Code Protection bit (Program memory code protection 
                                     // is disabled)
#pragma config IOSCFS = 4MHZ         // Internal Oscillator Frequency Select (4 MHz)
#pragma config BOREN = OFF           // Brown-out Reset Selection bits (BOR disabled)

#include <xc.h>                      // Einbindung der Bibliotheken
#include <stdbool.h>

union {                              // Struckt-Konstrukt für späteren Bit-Zugriff
  unsigned char Ziffer;
  struct {
    unsigned b0:1;
    unsigned b1:1;
    unsigned b2:1;
    unsigned b3:1;
    unsigned b4:1;
    unsigned b5:1;
    unsigned b6:1;
    unsigned b7:1;
  };
} byte_u;

#define SH_CP_Pin  GPIObits.GP1      // Schieberegister 74HC595 SH_CP
#define ST_CP_Pin  GPIObits.GP2      // Schieberegister 74HC595 ST_CP
#define DS_Pin  GPIObits.GP4         // Schieberegister 74HC595 DS
#define _XTAL_FREQ 4000000           // Taktfrequenz

int Wert_Analog;                     // Aktueller Wert am Analogeingang
                                     // Linealisierungsintervalle:
int Intervall;                       // Interval-Wert
int Anfangswert, Endwert;            // Interval-Grenzen
int T_Min;                           // Intervall-Grundtemperatur
int Temperatur;                      // Temperaturwert
int Anzeige_Ziffer [2];              // Einzelne Ziffer für 7-Segmentanzeige

// *****************************************************************************************
void Ziffer_Anzeige () {             // Bits Übertragung zum Schieberegister
    
    SH_CP_Pin = false;               // Startvorbereitung
    DS_Pin = byte_u.b0;              // Bitwert
    SH_CP_Pin = true;                // Übernehmen
    
    SH_CP_Pin = false;
    DS_Pin = byte_u.b1;    
    SH_CP_Pin = true;
    
    SH_CP_Pin = false;
    DS_Pin = byte_u.b2;    
    SH_CP_Pin = true;
    
    SH_CP_Pin = false;
    DS_Pin = byte_u.b3;    
    SH_CP_Pin = true;

    SH_CP_Pin = false;
    DS_Pin = byte_u.b4;    
    SH_CP_Pin = true;
    
    SH_CP_Pin = false;
    DS_Pin = byte_u.b5;    
    SH_CP_Pin = true;

    SH_CP_Pin = false;
    DS_Pin = byte_u.b6;    
    SH_CP_Pin = true;
    
    SH_CP_Pin = false;
    DS_Pin = byte_u.b7;    
    SH_CP_Pin = true;   
}

// *****************************************************************************************
void main(void) {

    GPIO  = 0b00000000;       // Alle GPIOs nullen
    TRISIO = 0b00001001;      // 0-Ausgang  1-Eingang
    ANSEL = 0b01010001;       // ADC Frequenz mit Fosc/16 = 0b101
    ADCON0 = 0b10000001;      // GP0 als Analogeingang

    while (true) {                                         // Endlosschleife
        ADCON0bits.GO_DONE = 1;                            // GO_DONE Bit setzen
        while (ADCON0bits.GO_DONE) {                       // Schleife Analogwert lesen
            Wert_Analog = (ADRESH << 8) + ADRESL;          // Variable Wert_Analog beschreiben
        }     
        if (Wert_Analog >= 358) {                          // Intervall 10-20°C             
            Anfangswert = 358;
            Endwert = 460;
            T_Min = 10; }            
        if (Wert_Analog >= 460) {                          // Intervall 20-30°C
            Anfangswert = 460;
            Endwert = 558;
            T_Min = 20; }           
        if (Wert_Analog >= 558) {                          // Intervall 30-40°C
            Anfangswert = 558;
            Endwert = 648; 
            T_Min = 30; } 
        if (Wert_Analog >= 648) {                          // Intervall 40-50°C
            Anfangswert = 648;
            Endwert = 726; 
            T_Min = 40; }        
        
                
        Intervall = Endwert - Anfangswert;                   // Temperatur-Berechnung 
        Temperatur = ((Wert_Analog - Anfangswert) * 10 / Intervall) + T_Min;
             
        GPIObits.GP5 = false;                                  // Warnleuchte AUS
        if ((Temperatur < 10) || (Temperatur > 50)) {          // T außer Messbereich
            GPIObits.GP5 = true; }                             // Warnleuchte EIN
        
        Anzeige_Ziffer [1] = Temperatur / 10;                  // Ziffer für 7-Segmentanzeige
        Anzeige_Ziffer [0] = Temperatur - (Anzeige_Ziffer [1] * 10);

        if (Wert_Analog > 999) {Wert_Analog = 999;}
        
        ST_CP_Pin = false;                                     // Schieberegister ST_CP        
        for (int i=0; i<2; i++)    {                           // For-Schleife für beide Ziffern 
                                                               // der Anzeige
            int a = Anzeige_Ziffer [i];
            switch (a) {
                case 0: byte_u.Ziffer = 0b11111100;            // Bitbelegung für Elemente der 
                                                               // 7-Segmentanzeige
                        Ziffer_Anzeige ();                     // Unterprogramm aufrufen 
                                                               // (Schieberegister))
                        break;
                case 1: byte_u.Ziffer = 0b01100000;            // usw.
                        Ziffer_Anzeige ();
                        break;   
                case 2: byte_u.Ziffer = 0b11011010;
                        Ziffer_Anzeige ();
                        break;
                case 3: byte_u.Ziffer = 0b11110010;
                        Ziffer_Anzeige ();
                        break;
                case 4: byte_u.Ziffer = 0b01100110;
                        Ziffer_Anzeige ();
                        break;
                case 5: byte_u.Ziffer = 0b10110110;
                        Ziffer_Anzeige ();
                        break;
                case 6: byte_u.Ziffer = 0b10111110;
                        Ziffer_Anzeige ();
                        break;
                case 7: byte_u.Ziffer = 0b11100000;
                        Ziffer_Anzeige ();
                        break;
                case 8: byte_u.Ziffer = 0b11111110;
                        Ziffer_Anzeige ();
                        break;
                case 9: byte_u.Ziffer = 0b11110110;
                        Ziffer_Anzeige ();
                        break;                    
            }
        }
        ST_CP_Pin = true;                                // 7-Segmentanzeige aktualisieren                                                         
        __delay_ms(500);                                 // Wartezeit
    }
}

// *****************************************************************************************
        

Kurzvideo zur Schaltung

Kurzvideo


Weitere Themen:


Google-Suche auf MEINE-SCHALTUNG.de :


Home Impressum Datenschutz