Hi miteinander,
ich habe einen ATXMega256A3, er steuert als I²C-Slave ein Touchscreen
(resistiv).
Ich bin soweit vom ATXMega begeistert, es klappte auch alles wunderbar -
das einzige was bisschen komisch ist, ist der ADC. Erstmal verstehe ich
das Datenblatt nicht so 100% mit CH0-CH3 und was dort möglich ist -
soweit wie ich das Datenblatt verstanden habe, habe ich mir 2 Funktionen
für den ADC geschrieben. Ich nutze nur die ADC-Portpins auf PORTB (ADC1,
ADC2 für Touch, ADC4 für LDR). Jetzt kommt der Trick: Wenn ich einen
Kanal dauerhaft auslese funktioniert es wunderbar, wie beim ATMega
gewohnt werde die Werte sauber auf dem Display dargestellt (gilt für
jeden ADC-Pin). Ich takte mit 32MHz int. Osc.
In der Main lese ich alle 10ms den Touch aus, dabei erst horizontal,
danach vertikal. Ich schalte den ADC-Readpin einfach um. Als ich das
gemacht habe, hat er nicht mehr funktioniert (gab immer 4095 aus) - erst
als ich die Auslesezeit auf 100ms gesetzt habe (aus Zufall
herausgefunden) klappte es - jedoch hat er, die Kanäle vertauscht?! Dann
bin ich hergegangen, und habe 30ms horizontal, nach weiteren 30ms
vertikal - jetzt klappt das schonmal für den Touch ordnungsgemäß, obwohl
ich das Phänomen nicht verstehe.
Jetzt wollte ich noch den LDR (ADC4) alle 2sek. einlesen - jetzt ist er
überfordert! Touch funktioniert, beim LDR kommt irgendein Quark raus
(meist so um die 300). Wenn ich den Touch deaktiviere, und nur noch den
LDR auslese, klappt es allerdings hervorragend?!!!?
Ich bin überfragt, das war beim ATMega schöner :(.
Nachfolgend mal meine 2 Funktionen, ich rufe diese in der Main einfach
nach gew. Zeit auf, der "ADC_FEATURE_READ" Funktion übergebe ich den
einzulesenden Port (bspw 1 für ADC1 (TouchX), 2 für ADC2 (TouchY) und 4
für ADC4 (LDR).
1 | void ADC_init(void)
|
2 | {
|
3 | //ADC inits
|
4 | if (QUARZ_16MHZ)
|
5 | ADCB.PRESCALER=ADC_PRESCALER_DIV8_gc; //Max. ADC Sampling 2MSPS (16MHz/8=2MSPS)
|
6 | else
|
7 | ADCB.PRESCALER=ADC_PRESCALER_DIV16_gc; //Max. ADC Sampling 2MSPS (32MHz/16=2MSPS)
|
8 |
|
9 | ADCB.REFCTRL=ADC_REFSEL_AREFA_gc; //AREF as REF (Ub MC)
|
10 | ADCB.CTRLB=ADC_RESOLUTION_12BIT_gc;
|
11 | ADCB.CH0.CTRL=ADC_CH_INPUTMODE_SINGLEENDED_gc; //nur positiv
|
12 | ADCB.CTRLA=ADC_ENABLE_bm;
|
13 | }
|
14 |
|
15 | uint16_t ADC_FEATURE_READ(uint8_t adc_portB)
|
16 | {
|
17 | if (adc_portB>7)
|
18 | return (adc_portB);
|
19 |
|
20 | ADCB.CH0.MUXCTRL=(adc_portB<<3); //Port wählen //schieben, da nur positiv nehmen
|
21 | ADCB.CH0.CTRL |= (1<<ADC_CH_START_bp); //start conversion
|
22 | wdt_reset();
|
23 |
|
24 | while (!ADCB.CH0.INTFLAGS)
|
25 | wdt_reset();
|
26 |
|
27 | ADCB.CH0.INTFLAGS=0; //Clear Bit (don't know if hardware do that)
|
28 |
|
29 | return (ADCB.CH0.RES); //gebe das Ergebnis zurück (ADCW) hier nochmals gucken wg. Registern
|
30 | }
|
Kleiner Nachtrag:
ich habe gerade herausgefunden, dass wenn ich den LDR 2-3mal auslese das
es dann funktioniert (gilt auch für die Touch's). Jetzt bin ich komplett
verwirrt - das irgendwie nicht ganz original, oder?