Hallo zusammen,
ich habe mal wieder ein (Paar) Problem(e).
zuerst ein paar erklaerende Worte zu meinem Projekt:
Ich baue ein Indiziersystem fuer einen Motorenpruefstand.
Dieses System soll den Druck im Brennraum und den Hub der Nadel der
Einspritzduese "winkelrichtig" messen.
Hierzu habe ich den ATXMega128A1 eingesetzt, der ueber das Eventsystem
von einem Incrementalgeber der auf der Kurbelwelle sitzt getriggert
wird. (4096 Inkremente pro Umdrehung).
Ueber den (im Eventsystem des XMega128A1vorhandenen) Quadraturencoder
werden die beiden getrennten (nicht gemultiplexte) Analogeingaenge des
XMega getriggert. Sie ziehen mit steigender Flanke des Inkrementalgebers
(A-Signal) synchron die Messwerte des Druckes und des Nadelhubes ein.
Das ganze laeuft (leider, da DFLL nicht funktioniert) mit dem internen
kalibrierten 32MHz RC-Oszillator
Hardwaremaessig ist der Analogteil so umgeetzt wie im Anhang zu erkennen
(analog_teil.PNG).
Am analogen Eingang 1 haengt ein Ladungsverstaerker der Firma Kistler
(Ausgangssignal +/- 10V).
Am Eingang 2 haengt ein Messverstaerker der Firma AVL, der ueber eine
Oscillatorbox den Messwert des induktiven Nadelhubsensors misst
(Ausgangssignal +/- 10V).
Der Analogkanal A ist schneller eingestellt als Kanal B.
Der Teiler fuer den ADC Clock A ist auf 64, der fuer ADC Clock B auf 128
eingestellt.
Deshalb sollte der Interrupt fuer ADC B fertig erst kommen, wenn ADC A
sicher fertig ist.
Ueber das Interrupt des ADC B wird dann die Datenuebertragung ueber USB
(FTDI 2232H) gestartet. (Nicht in einer ISR, sondern per Polling auf das
I-Flag, weil der ISR Overhead zu viel Performance kosten wuerde.)
Jetzt zu meinen Problemen:
Problem 1 ( gross und fuer mich sehr wichtig)
Unter bestimmten (mir nicht klaren) Umstaenden habe ich auf dem
Analogeingang 1 ein Quantisierungsproblem.
Die 4 LSBs gehen alle auf 1.
Ich habe dann nur noch 8 bit Aufloesung (und den Fehler der 4 LSBs fest
auf 1)
Ist der AVL Messverstaerker ausgeschaltet ist dieses Problem nicht mehr
vorhanden. (Siehe example_w_quant_prob.png und
example_wo_quant_prob.png)
Ebenso koennen sich die Umstaende im Laufe der Zeit so aendern, dass ein
Uebergang (der Anteil der Messwerte mit Quantisierungsfehler geht
langsam von 100% auf 0% zurueck!) zu einer einwandfreien Messung
stattfindet.
Ich wuerde mich SEHR (!) freuen, wenn hier jemand einen Hinweis haette
dieses Problem zu beseitigen.
Problem 2 ( besorgniserregend aber eher nebensaechlich da fuktionierende
Einstellung gefunden)
Es gibt offensichtlich ein Problem mit den 2 ADCs im Xmega128A1.
Ich habe eine Zeit lang mit dem ADC Timing "spielen" muessen, bis ich
brauchbare Messwerte bekommen habe.
Dies funktioniert nur, wenn den ADC A mit 32MHz/64 und ADC B mit
32MHz/128 betreibe.
Stelle ich dad ADC Timing anders ein, bekomme ich eine Schwinung auf
wenigstems einen der ADC Kanaele. (siehe A_64_B128.png und
A_64_B_64.png)
Die Frequenz und Amplitude unterscheidet sich auch zwischen zwei XMegas.
Den genauen Zusammenhang habe ich aber aus Zeitgruenden nicht genauer
dokumentiert.
Auch hier wuerde ich mich ueber eine Erklaerung freuen.
Im Anhang habe ich noch Ausschnitte aus meinen Sourcen angehaengt.
Vielen Dank, schoenen Gruss,
Balze aka AVR Noob
P.S.: Sourcenausschnitt aus main():
1 | ....
|
2 | EVSYS.CH4MUX = EVSYS_CHMUX_PORTD_PIN3_gc;
|
3 | EVSYS.CH4CTRL = EVSYS_DIGFILT_2SAMPLES_gc;
|
4 |
|
5 | ADCA.EVCTRL = (uint8_t) ADC_SWEEP_0_gc |
|
6 | ADC_EVSEL_4567_gc |
|
7 | ADC_EVACT_CH0_gc;
|
8 |
|
9 | ADCA.CTRLB = ( ADCA.CTRLB & ~ADC_RESOLUTION_gm ) |
|
10 | ADC_RESOLUTION_LEFT12BIT_gc | ADC_CONMODE_bm;
|
11 | ADCA.PRESCALER = ( ADCA.PRESCALER & ~ADC_PRESCALER_gm ) |
|
12 | ADC_PRESCALER_DIV64_gc;
|
13 |
|
14 | ADCA.REFCTRL = ( ADCA.REFCTRL & ~ADC_REFSEL_gm ) |
|
15 | ADC_REFSEL_AREFA_gc;
|
16 | ADCA.CTRLA |= ADC_ENABLE_bm;
|
17 |
|
18 | ADCA.CH0.MUXCTRL = (uint8_t) ADC_CH_MUXPOS_PIN2_gc | ADC_CH_MUXNEG_PIN1_gc;
|
19 |
|
20 | ADCA.CH0.CTRL = (ADCA.CH0.CTRL & (~(ADC_CH_INPUTMODE_gm|ADC_CH_GAINFAC_gm))) | (uint8_t) ADC_CH_INPUTMODE_DIFF_gc;
|
21 |
|
22 | ADCB.EVCTRL = (uint8_t) ADC_SWEEP_0_gc |
|
23 | ADC_EVSEL_4567_gc |
|
24 | ADC_EVACT_CH0_gc;
|
25 |
|
26 | ADCB.CTRLB = ( ADCB.CTRLB & ~ADC_RESOLUTION_gm ) |
|
27 | ADC_RESOLUTION_12BIT_gc| ADC_CONMODE_bm;
|
28 |
|
29 | ADCB.PRESCALER = ( ADCB.PRESCALER & ~ADC_PRESCALER_gm ) |
|
30 | ADC_PRESCALER_DIV128_gc;
|
31 | ADCB.CH0.INTCTRL = (ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL_MED_gc);
|
32 |
|
33 | ADCB.REFCTRL = ( ADCB.REFCTRL & ~ADC_REFSEL_gm ) |
|
34 | ADC_REFSEL_AREFB_gc;
|
35 | ADCB.CTRLA |= ADC_ENABLE_bm;
|
36 |
|
37 | ADCB.CH0.MUXCTRL = (uint8_t) ADC_CH_MUXPOS_PIN2_gc | ADC_CH_MUXNEG_PIN1_gc;
|
38 |
|
39 | ADCB.CH0.CTRL = (ADCB.CH0.CTRL & (~(ADC_CH_INPUTMODE_gm|ADC_CH_GAINFAC_gm))) | (uint8_t) ADC_CH_INPUTMODE_DIFF_gc;
|
40 |
|
41 | for (;;) {
|
42 | while (!ADCB.INTFLAGS){
|
43 | }
|
44 |
|
45 | ADCB.INTFLAGS |= 0x01;
|
46 |
|
47 | PORTJ.OUT = TCC0.CNTL; // Zaehler der Inkremente low
|
48 | PORTH.OUT &= ~(PIN0_bm);
|
49 | PORTH.OUT |= (PIN0_bm);
|
50 |
|
51 | PORTJ.OUT = TCC0.CNTH; // Zaehler der Inkremente high
|
52 | PORTH.OUT &= ~(PIN0_bm);
|
53 | PORTH.OUT |= (PIN0_bm);
|
54 |
|
55 | PORTJ.OUT = ADCB.CH0RESL;
|
56 | PORTH.OUT &= ~(PIN0_bm);
|
57 | PORTH.OUT |= (PIN0_bm);
|
58 |
|
59 | PORTJ.OUT = ADCA.CH0RESL | ADCB.CH0RESH;
|
60 | PORTH.OUT &= ~(PIN0_bm);
|
61 | PORTH.OUT |= (PIN0_bm);
|
62 |
|
63 | PORTJ.OUT = ADCA.CH0RESH;
|
64 | PORTH.OUT &= ~(PIN0_bm);
|
65 | PORTH.OUT |= (PIN0_bm);
|
66 | }
|