kramann.info
© Guido Kramann

Login: Passwort:










1.5 Objektorientierte Umsetzung der Meßdaten Übertragung

  • Im folgenden Programm wurde der Programmteil, der den A/D-Wandler verwendet in einer Klasse gekapselt.
  • Das Hauptprogramm wird dadurch kürzer und auch leichter zu lesen.
  • Die Konfiguration und Start des A/D-Wandlers findet hier beim Aufruf des Konstruktors statt.
  • Die Methode waehlePin(unsigned char nr) dient dazu, den Pin auszuwählen von dem der Analogwert aufgezeichnet werden soll.
  • Die alternative Methode waehlePinHigh(unsigned char nr) macht das gleiche, sorgt aber für eine Art der Ablage der 12Bit in die Aufzeichnungsregister, die ein Lesen des höherwertigen Bytes leichter macht.
#include<avr/io.h>
#include "ADwandler.h"

int main(void)
{
    ADwandler adw;

    DDRC = 0b11111111; //PORTC alle Bits als Ausgang
    DDRD = 0b00000000; //PORTD alle Bits als Eingang

    adw.waehlePinHigh(40);

    while(true)
    {
        PORTC = adw.holeGemitteltenWertHigh();
    }
    return 0;
} 

Code 1.5-1: File muecb.c ist das C++ Hauptprogramm für objektorientierte Variante der Aufzeichnung der Sensordaten.

class ADwandler
{
    public:
        ADwandler()
        {
	        ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);

            //ADEN
	        //  1   AD-Wandler eingeschaltet
	        //ADSC
	        //  1   Konvertierung starten
	        //ADATE
	        //  0   Auto-Trigger aus
            //ADIF (Interrupt-Flag)
	        //ADIE
	        //  0   Interrupt ausgeschaltet
	        //ADPS 2 1 0 Vorteilung der Taktrate (sollte zwischen 50..200kHz liegen, also bei 9,216MHz Teilung=92 ~ 128)
	        //ADPS 2 1 0 Vorteilung der Taktrate (sollte zwischen 50..200kHz liegen, also bei 9,216MHz 144kHz Teilung=64)
	        //     0 0 0    2  
	        //     0 0 1    2  
	        //     0 1 0    4  
	        //     0 1 1    8  
	        //     1 0 0   16  
	        //     1 0 1   32  
	        //     1 1 0   64 (ausgewählt)  
	        //     1 1 1  128  

            //Freilaufmode auswählen:
	        SFIOR &= 255 - ((1<<ADTS2) | (1<<ADTS1) | (1<<ADTS0));

        }


        void waehlePin(unsigned char nr) //40:AD0,39:AD1,38:AD2,37:AD3,36:AD4,35:AD5,34:AD6,33:AD7
        {
            //ACHTUNG: verwendete Pins von PORTA als Eingang wählen!
            //AD-Wandler einstellen und aktivieren:
            //PA0,1,2,3 als Eingänge (DDRA=0b11110000)

            //REFS1 REFS0 
            //  0     0     externe Referenzspannung
            //ADLAR
            //  0           Ergebnis in ADCH und ADCL rechts ausgerichtet (so kann man leicht die höhren 8 Bits lesen)
            //MUX 4 3 2 1 0
            //    0 0 0 0 0 ADC0
            //    0 0 0 0 1 ADC1
            //    0 0 0 1 0 ADC2
            //    0 0 0 1 1 ADC3  //hier ausgewählt (linker Motor)
            //    0 0 1 0 0 ADC4
            //    0 0 1 0 1 ADC5
            //    0 0 1 1 0 ADC6
            //    0 0 1 1 1 ADC7

            switch(nr)
            {
			    case 40:  //ADC0
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0);
				break;
			    case 39:  //ADC1
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0);
				break;
			    case 38:  //ADC2
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0);
				break;
			    case 37:  //ADC3
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0);
				break;
			    case 36:  //ADC4
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (0<<MUX0);
				break;
			    case 35:  //ADC5
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (1<<MUX0);
				break;
			    case 34:  //ADC6
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
				break;
			    case 33:  //ADC7
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0);
				break;

        }

        //AD-Wandler einschwingen lassen:
        for(i=0;i<5000;i++)
        {
            akku = ADCH; //muss erst ausgelesen werden, damit ADCL verfügbar ist.
            akku = ADCL;
        }
        return;
    }

    void waehlePinHigh(unsigned char nr) //40:AD0,39:AD1,38:AD2,37:AD3,36:AD4,35:AD5,34:AD6,33:AD7
    {
        //ACHTUNG: verwendete Pins von PORTA als Eingang wählen!
        //AD-Wandler einstellen und aktivieren:
        //PA0,1,2,3 als Eingänge (DDRA=0b11110000)
    
        //ADMUX = (0<<REFS1) | (0<<REFS0) | (0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0);
        //REFS1 REFS0 
        //  0     0     externe Referenzspannung
        //ADLAR
        //  0           Ergebnis in ADCH und ADCL rechts ausgerichtet (so kann man leicht die höhren 8 Bits lesen)
        //MUX 4 3 2 1 0
        //    0 0 0 0 0 ADC0
        //    0 0 0 0 1 ADC1
        //    0 0 0 1 0 ADC2
        //    0 0 0 1 1 ADC3  //hier ausgewählt (linker Motor)
        //    0 0 1 0 0 ADC4
        //    0 0 1 0 1 ADC5
        //    0 0 1 1 0 ADC6
        //    0 0 1 1 1 ADC7

        switch(nr)
        {
			    case 40:  //ADC0
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0);
				break;
			    case 39:  //ADC1
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0);
				break;
			    case 38:  //ADC2
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0);
				break;
			    case 37:  //ADC3
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0);
				break;
			    case 36:  //ADC4
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (0<<MUX0);
				break;
			    case 35:  //ADC5
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (1<<MUX0);
				break;
			    case 34:  //ADC6
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
				break;
			    case 33:  //ADC7
	                ADMUX = (0<<REFS1) | (0<<REFS0) | (1<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0);
				break;

        }

        //AD-Wandler einschwingen lassen:
	for(i=0;i<1000;i++)
        {
            akku = ADCH; //muss erst ausgelesen werden, damit ADCL verfügbar ist.
            akku = ADCL;
        }
	return;
    }


    unsigned char holeWert()
    {
        akku = ADCH; //muss erst ausgelesen werden, damit ADCL verfügbar ist.
        akku = ADCL;
        return akku;		    
    }
		
    unsigned char holeWertHigh()
    {
        akku2 = ADCH; //muss erst ausgelesen werden, damit ADCL verfügbar ist.
        akku = ADCL;
        return akku2;		    
    }


    long int holeDoppeltenGemitteltenPeakwert()
    {
        x = 0;
        for(i=0;i<10;i++)
        {
            y=0;
            for(p=0;p<100;p++)
            {
                y+=holeWert();
                for(k=0;k<10;k++);
            }
            y/=50;

            if(y>x)
                x=y;
        }
        return x;
    }

    unsigned char holeGemitteltenWert()
    {
        x = 0;
        for(i=0;i<100;i++)
        {
            x+=holeWert();
            for(k=0;k<100;k++);
        }
        x/=100;
        return (unsigned char)x;
    }

    unsigned char holeGemitteltenWertHigh()
    { 
        x = 0;
        for(i=0;i<100;i++)
        {
            x+=holeWertHigh();
            for(k=0;k<100;k++);
        }
        x/=100;
        return (unsigned char)x;
    }

    private:
        unsigned char akku,akku2;
        int i,k,p;
        long int x,y;
};
 

Code 1.5-2: File ADwandler.h ist die C++ Klasse für objektorientierte Variante der Aufzeichnung der Sensordaten, in der der A/D-Wandler konfiguriert und eingesetzt wird.

sensor_oop.zip AVR-Studio-Projekt herunterladen