1.5 Objektorientierte Umsetzung der Meßdaten Übertragung
|
#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