1 | void initialisiere_ADC(void)
|
2 | { setze_ADC_auf_Standardeinstellungen();
|
3 | kalibriere_ADCA();
|
4 | }
|
5 |
|
6 | void setze_ADC_auf_Standardeinstellungen(void)
|
7 | { ADCA.CTRLB = 0b00010010; // Auflösung auf 12 Bit, signed Modus, selbstlaufend/freerun == Bit 3, Ergebnis hat mehr als 12Bit (Bit2:1, S.365)
|
8 | ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm | ADC_TEMPREF_bm;
|
9 | // Bandgap einschalten, Referenz auf interne 1-Volt-Quelle, Temperaturreferenzspannung einschalten
|
10 | ADCA.PRESCALER = ADC_PRESCALER_DIV512_gc; // ADC maximal 2 Megasample pro Sek. => 32MHz /512 = 62 KHz
|
11 | ADCA.CTRLA = ADC_ENABLE_bm; // ADC einschalten 0b00000001
|
12 |
|
13 | if (DIP_Schalter & 0b00010000) // 16-fache Verstärkung mit Spgsteiler 1 : 1,6 => 10-fach Verstärkung
|
14 | { ADCA.CH0.CTRL = 0b00010011; // Diff. Signal, Verstärkung = 16x, MUXNEG für Pinne 4,5,6,7 + GND
|
15 | ADCA.CH0.MUXCTRL= 0b00111010; } // Bits6:3(MUXPOS) == ADC7(PA7) | Bits2:0(MUXNEG) == ADC6(PA6)
|
16 | else // 1-fache Verstärkung
|
17 | { ADCA.CH0.CTRL = 0b00000011; // Diff. Signal, Verstärkung = 1x, MUXNEG für Pinne 4,5,6,7 + GND
|
18 | ADCA.CH0.MUXCTRL= 0b01000010; } // Bits6:3(MUXPOS) == ADC8(PD0) | Bits2:0(MUXNEG) == ADC6(PA6)
|
19 |
|
20 | //ADCA.CH0.AVGCTRL = 0b00100010; // Achfaches Akkumulieren und nach rechts schieben
|
21 | // Kann die Bereichsgrenzen nicht als Max und Min darstellen, bricht in neg. Bereich ein
|
22 | }
|
23 |
|
24 | void kalibriere_ADCA(void) // Nach Anleitung ATXMEGA E Handbuch Seite 357
|
25 | { int16_t Summe;
|
26 | uint32_t Summe2;
|
27 | uint16_t Verstaerkung;
|
28 |
|
29 | ADCA.CALL = lese_Kalibrierungsbyte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0));
|
30 | ADCA.CALH = lese_Kalibrierungsbyte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1));
|
31 |
|
32 | ADCA.CH0.CORRCTRL &= 0b11111110; // Korrektur abschalten
|
33 |
|
34 | for (Wartezaehler=0; Wartezaehler<10;); // 10 mSek warten
|
35 |
|
36 | // MUXPOS und MUXNEG auf den selben Eingang legen (beide auf ADC6 = 1,65V):
|
37 | ADCA.CH0.CTRL = 0b00000011; // Diff. Signal, Verstärkung = 1x, MUXNEG für Pinne 4,5,6,7 + GND
|
38 | if (DIP_Schalter & 0b00010000) // 10-fache Verstärkung
|
39 | { ADCA.CH0.CTRL = 0b00010011; // Diff. Signal, Verstärkung = 16x, MUXNEG für Pinne 4,5,6,7 + GND
|
40 | ADCA.CH0.MUXCTRL= 0b00110010; } // Bits 6:3 (MUXPOS) == ADC6 (PA6) | Bits 2:0 (MUXNEG) == ADC6 (PA6)
|
41 | else // 1-fache Verstärkung
|
42 | { ADCA.CH0.CTRL = 0b00000011; // Diff. Signal, Verstärkung = 1x, MUXNEG für Pinne 4,5,6,7 + GND
|
43 | ADCA.CH0.MUXCTRL= 0b00110010; } // Bits 6:3 (MUXPOS) == ADC6 (PA6) | Bits 2:0 (MUXNEG) == ADC6 (PA6)
|
44 |
|
45 | while (miss_Spannung()!=1);
|
46 |
|
47 | Summe=0;
|
48 | for (uint8_t i=0; i<32; i++) // 32 Messwerte holen
|
49 | {
|
50 | while (miss_Spannung()!=1);
|
51 | Summe+=gemessene_Spannung;
|
52 | }
|
53 |
|
54 | if (Summe<0)
|
55 | { Summe = -Summe; // positiv machen
|
56 | Summe>>=5; // Dividieren durch Bitschieben
|
57 | Summe = -Summe; // wieder negativ machen
|
58 | }
|
59 | else Summe>>=5; // durch 32
|
60 |
|
61 | ADCA.CH0.OFFSETCORR0 = Summe & 0b11111111; // untere 8 Bit speichern
|
62 | ADCA.CH0.OFFSETCORR1 = Summe >> 8; // obere 12 Bit speichern
|
63 |
|
64 | if (DIP_Schalter & 0b00010000)
|
65 | Verstaerkung = 2000; // 10-fache Verstärkung
|
66 | else Verstaerkung = 1978; // 1-fache Verstärkung
|
67 |
|
68 | ADCA.CH0.GAINCORR0 = Verstaerkung & 0b11111111;
|
69 | ADCA.CH0.GAINCORR1 = Verstaerkung >> 8;
|
70 |
|
71 | ADCA.CH0.CORRCTRL |= 0b00000001; // Korrektur einschalten
|
72 |
|
73 | // Zurücksetzen auf ADC8 und ADC6
|
74 | setze_ADC_auf_Standardeinstellungen();
|
75 | }
|
76 |
|
77 |
|
78 | // nicht blockierende ADC-Abfrage
|
79 | // Ergebnis fertig: Rückgabe des Messwertes in "gemessene_Spannung"
|
80 | // Ergebnis nicht fertig: Rückgabe von -1
|
81 | // *** physik. Messwert - dig. Wert: ***
|
82 | // ADC kann auf Differenzeingängen zwischen 0..3,3V (absolut) messen, wobei die Differenz (bei 1V Referenz) von -0,95V bis +0,95V sein darf.
|
83 | // (nicht, wie aus Datenblatt S.77 annehmbar zwischen 0..1,0V absolut, sondern 0..3,3V absolut)
|
84 | // -0,95V entspricht -2047
|
85 | // +0,95V entspricht +2047
|
86 | uint8_t miss_Spannung(void) // Struktur "ADC_Wandlungen", die die Konvertierung verwaltet
|
87 | { ADC_CH_t *Kanal; // AD-Wandler hat bei XMEGAs bis zu vier Kanäle
|
88 | static uint8_t Erststart=1; // aller erster Aufruf startet den ADC ohne Bedingung
|
89 |
|
90 | Kanal= &(ADCA.CH0); // Kanal 0 messen (hier der einzig vorhandene)
|
91 |
|
92 | if (Kanal->INTFLAGS & 0b00000001) // Ergebnis vorhanden?
|
93 | { gemessene_Spannung = Kanal->RES;
|
94 | Kanal->INTFLAGS=0b00000001; // Flag "Konvertierung fertig" wieder löschen
|
95 | Kanal->CTRL |= ADC_CH_START_bm; // Neue Konvertierung starten
|
96 | return 1; }
|
97 | else
|
98 | { if (Erststart) // Noch nie gestartet
|
99 | { Erststart=0;
|
100 | Kanal->CTRL |= ADC_CH_START_bm; } // Neue Konvertierung starten
|
101 | return -1;
|
102 | }
|
103 | }
|