Forum: Mikrocontroller und Digitale Elektronik xmega single ADC-Messung


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Peet (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

folgendes Problem:
1
#include <avr/io.h>
2
#define F_CPU 32000000UL
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
6
volatile uint8_t temp1=0;
7
  
8
9
int main(void)
10
{
11
initClock();
12
PORTD.DIRSET = 0b11111111 ;      // Output: 8xLED
13
14
ADCA.CTRLB = 0b00000100;    //ADC 8 Bit
15
ADCA.REFCTRL = 0b00010000;   //VCC/1.6 ref
16
ADCA.PRESCALER = 0;          // Prescaler 4
17
ADCA.CTRLA = 0b00000001;    // ADC enable
18
  
19
ADCA.CH0.MUXCTRL = 0b00001000;  //MUXPOS=ADC1 pin=PA1
20
21
sei();
22
PMIC.CTRL=0x07;
23
ADCA.CH0.INTCTRL = 0x03;    //prio high
24
    
25
26
while (1) 
27
{  
28
_delay_ms(4000);
29
ADCA.CH0.CTRL = 0b10000001;   //ADCA Channel 0 starten
30
}
31
32
}
33
34
35
    
36
    ISR (ADCA_CH0_vect)
37
    {
38
      temp1 = ADCA_CH0RESL;
39
      PORTD.OUT = temp1;
40
    }

Ich möchte mir den Messwert auf 8LEDs anzeigen lassen. Allerdings stimmt 
nur jede zweite Messung. Bei den Messungen zwischendrin leuchtet immer 
nur die LED an Pin7. Woran liegt das?

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Es wäre hilfreich gewesen, den konkreten Mikrocontroller zu benennen. 
Xmega ist ja ein weites Feld.

Ein Schuss ins Blaue: Musst du in der ISR eventuell zwei Register in 
einer bestimmten Reihenfolge lesen, da der ADC (prinzipiell) mehr als 
8bit unterstützt?

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
https://www.e-lab.de/downloads/DOCs/XMEGA_A_Manual.pdf

Kapitel 3.11  Accessing 16-bit Registers:

The AVR data bus is 8 bits wide, and so accessing 16-bit registers 
requires atomic operations. These registers must be byte-accessed using 
two read or write operations...
For a read operation, the low byte of the 16-bit register must be read 
before the high byte. When the low byte register is read by the CPU, the 
high byte of the 16-bit register is copied into the temporary register 
in the same clock cycle as the low byte is read. When the high byte is 
read, it is then read from the temporary register.

Es hat bestimmt irgendwie damit zu tun.

: Bearbeitet durch User
von Peet (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich nutze den ATXmega16D4

Nacheinander auslesen wie z.B.
1
    ISR (ADCA_CH0_vect)
2
    {
3
      temp1 = ADCA_CH0RESL;
4
      temp2 = ADCA_CH0RESH;
5
      PORTD.OUT = temp1;  
6
    }
funktioniert leider auch nicht.
Hat jemand einen funktionsfähigen Code für den ADC eines xmega?
Das blöde Teil bringt mich so langsam zur Verzweiflung.

von M. K. (sylaina)


Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Es wäre hilfreich gewesen, den konkreten Mikrocontroller zu benennen.
> Xmega ist ja ein weites Feld.

Bzgl. ADC ist das völlig egal, da sind alle Xmega gleich. Das ist ja 
einer deren Vorteile.

@TE schau mal hier nach, da gibts ein Tutorial zum ADC auf dem Xmegas, 
was IMO recht gut ist:

https://www.kampis-elektroecke.de/?page_id=1644

von Gerhard G. (xmega)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

du solltest die Wandlungs-Routine abwarten

while ((ADCA.CH0.INTFLAGS & ADC_CH_IF_bm)==0);
ADCA.CH0.INTFLAGS=ADC_CH_IF_bm;


Vollständiger Code:(ev. Register und ADC ändern!)

unsigned int adca_read(void)
{
unsigned int data;

// Start the AD conversion
ADCA.CH0.CTRL|= 1<<ADC_CH_START_bp;
// Wait for the AD conversion to complete
while ((ADCA.CH0.INTFLAGS & ADC_CH_IF_bm)==0);
// Clear the interrupt flag
ADCA.CH0.INTFLAGS=ADC_CH_IF_bm;
// Read the AD conversion result
((unsigned char *) &data)[0]=ADCA.CH0.RESL;
((unsigned char *) &data)[1]=ADCA.CH0.RESH;
return data;
}

von Peet (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Auf Kampis-elektroecke wird leider keine ISR verwendet. Die Lösung ist 
ähnlich komplex wie:

Gerhard G. schrieb:
> Hallo,
>
> du solltest die Wandlungs-Routine abwarten
>
> while ((ADCA.CH0.INTFLAGS & ADC_CH_IF_bm)==0);
> ADCA.CH0.INTFLAGS=ADC_CH_IF_bm;
>
> Vollständiger Code:(ev. Register und ADC ändern!)
>
> unsigned int adca_read(void)
> {
> unsigned int data;
>
> // Start the AD conversion
> ADCA.CH0.CTRL|= 1<<ADC_CH_START_bp;
> // Wait for the AD conversion to complete
> while ((ADCA.CH0.INTFLAGS & ADC_CH_IF_bm)==0);
> // Clear the interrupt flag
> ADCA.CH0.INTFLAGS=ADC_CH_IF_bm;
> // Read the AD conversion result
> ((unsigned char *) &data)[0]=ADCA.CH0.RESL;
> ((unsigned char *) &data)[1]=ADCA.CH0.RESH;
> return data;
> }

Danke soweit, aber es muss doch noch eine einfachere Lösung geben. Bei 
den Atmegas gehts ja auch mit z.B.:
1
ISR(ADC_vect){   
2
  unsigned short ADCres_lo=ADCL;
3
  unsigned short ADCres_hi=ADCH;
4
  gADCres=(ADCres_hi << 8) | ADCres_lo;
5
}
oder:
1
ISR(ADC_vect)                           
2
{
3
    if(ADC == 432)  {             
4
    PORTB|= (1 << PB2);               
5
    } 
6
}

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Bewertung
0 lesenswert
nicht lesenswert
Peet schrieb:
> aber es muss doch noch eine einfachere Lösung geben

Gibt es auch. Du stellst den ADC auf FreeRun, startest ihn einmal und 
holst dir dann nur noch die Resultate aus dem CH0RES Register ab (und 
zwar als 16-bit in einem Schwupps, denn der Kompiler erledigt das für 
dich).

Wenn das alles automatisch passieren soll, ist evtl. auch das Event 
System interessant.
Hier mal für 3 Kanäle auf dem STM32F100RB vom DiscoveryVL Board:
1
// Setup the ADC for 3-Channel sampling
2
// runs free with 3 channels , zero effort
3
// setup your desired current sensor in PMSM.h first
4
static void ADCInit(void)
5
{
6
  ADC.CTRLA = 0x01;   // switch it on
7
  ADC.CTRLB = ADC_RESOLUTION_12BIT_gc | (ADC_MODE << 4) ;  // 12 bit right adjusted
8
  ADC.PRESCALER = ADC_PRESCALER_DIV256_gc;
9
  ADC.REFCTRL = ADC_REFSEL_VCC_gc;
10
  ADC.EVCTRL = ADC_SWEEP_012_gc ;  // sweep over 3 channels
11
// Get calibration data
12
  ADC.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
13
  ADC.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );
14
// speed input
15
  ADC.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
16
  ADC.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc;
17
// temperature input
18
  ADC.CH1.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
19
  ADC.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc;
20
#if (CURRENT_SENSOR == SENSOR_ACS)
21
  ADC.CH2.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
22
  ADC.CH2.MUXCTRL = ADC_CH_MUXPOS_PIN2_gc;
23
#elif (CURRENT_SENSOR == SENSOR_NXP)
24
// diff. channel
25
// gain32 for weak KMZ magnetic field sensor
26
  ADC.CH2.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | ADC_CH_GAIN_32X_gc;
27
  ADC.CH2.MUXCTRL = ADC_CH_MUXPOS_PIN4_gc | ADC_CH_MUXNEG_PIN5_gc;
28
#endif
29
  ADC.CTRLB = ADC_RESOLUTION_12BIT_gc | (ADC_MODE << 4) | (1 << 3);// enable freerun
30
}
Da sind noch einige Besonderheiten drin, die du aber rauswerfen 
kannst/solltest.
Abholen der Werte jederzeit z.B. mit
1
myChannel0 = ADC.ADC0RES;
2
myChannel1 = ADC.ADC1RES;

von M. K. (sylaina)


Bewertung
0 lesenswert
nicht lesenswert
Peet schrieb:
> Auf Kampis-elektroecke wird leider keine ISR verwendet. Die Lösung ist
> ähnlich komplex wie:

Lies dir auf der Seite mal alles zum Xmega durch, ISR wird da auch 
beschrieben wie das gehandhabt wird (Hi, Mid und Low-Level Interrupts 
usw) und es ist wirklich sehr sehr einfach, es ist halt Fleißarbeit.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Ich vermisse in der Diskussion den Hinweis, was der TO konkret falsch 
gemacht hat.

Das Einzige, was mir aufgefallen ist, dass er zunächst nur ADCA_CH0RESL 
gelesen hat und dann im zweiten Versuch ADCA_CH0RESL gefolgt von 
ADCA_CH0RESH, was nach meiner Einschätzung dem Datenblatt entspricht.

Allerdings werden in allen genannten Beispielen die beiden Register in 
einem Rutsch in eine 16bit Variable gelesen. Kann das der Knackpunkt 
sein?

von M. K. (sylaina)


Bewertung
0 lesenswert
nicht lesenswert
Meiner Meinung nach fehlen dem TE hier noch einige Grundlagen. Ich hab 
aktuell leider nur Platinen (fürs Breadboard) für die ATXMEGAs aber 
keine Controller. Sonst hätte ich schon selbst mal einen Bleistiftcode 
erstellt. Hab mir u.a. mit Hilfe von Kampis Elektronikecke die 
ATXMEGA-Programmierung beigebracht. Hab hier noch nen Code rumfliegen, 
der ne FFT auf den ATXMEGA macht und hab dabei den internen ADC 
verwendet. Allerdings hatte ich das Seinerzeit ohne ISR benutzt.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe kaum Erfahrung mit Xmega, weil ich nur eine einzige Anwendung 
von ATmega auf Xmega portiert habe. Zufälligerweise hatte ich dort den 
ADC auch im Single-Shot Verfahren verwendet, allerdings ohne Interrupt. 
Vielleicht hilft mein Code:
1
#include "ADC.h"
2
#include <avr/io.h> 
3
#include <string.h>
4
#include <stdint.h>
5
#include "../hw-layout.h"
6
7
// Functions to access the internal ADC of Xmega targets.
8
9
// required settings:
10
// #define F_CPU                32000000
11
// #define ADC_CHANNELS         4
12
13
// Note: For all functional registers, I used the old syntax because
14
// the structures of the ADC are incorrectly defined in WinAVR.
15
16
// get a sample from ADC chip.
17
// chanell must be in range 0-15.
18
uint16_t getADC(const int channel) {
19
    ADCA_CH0_MUXCTRL = (channel<<3);    
20
    // flush the previous result
21
    ADCA_CTRLA |= 2; // 2=ADC_FLUSH_bm but not defined in WinAVR
22
    // start one sample
23
    ADCA_CH0_INTFLAGS=1;
24
    ADCA_CH0_CTRL |= ADC_CH_START_bm;
25
    // wait for the result
26
    while((ADCA_CH0_INTFLAGS & 1)==0);
27
    return ADCA_CH0RES;
28
}
29
30
// initialize the ADC 
31
void initADC() {
32
    ADCA_CTRLA = ADC_ENABLE_bm;
33
    ADCA_CTRLB = ADC_RESOLUTION_12BIT_gc;
34
    ADCA_REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm;
35
    ADCA_PRESCALER = ADC_PRESCALER_DIV8_gc; 
36
    ADCA_CH0_CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; 
37
}
38
39
// select reference
40
// The value can be "INT1V", "INTVCC", "AREFA" or "AREFB"
41
// returns 1 on success
42
uint8_t setAREF(const char* name) {
43
    if (strcmp(name,"INT1V")==0)
44
        ADCA_REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm; 
45
    else if (strcmp(name,"INTVCC")==0)
46
        ADCA_REFCTRL = ADC_REFSEL_VCC_gc   | ADC_BANDGAP_bm; 
47
    else if (strcmp(name,"AREFA")==0)
48
        ADCA_REFCTRL = ADC_REFSEL_AREFA_gc | ADC_BANDGAP_bm; 
49
    else if (strcmp(name,"AREFB")==0)     
50
        ADCA_REFCTRL = ADC_REFSEL_AREFB_gc | ADC_BANDGAP_bm;                        
51
    else 
52
        return 0;
53
    // Perform one sample to initialize the ADC on the new reference
54
    getADC(0);
55
    return 1;
56
}

Auch ich lese hier das Ergebnis in einem Rutsch in eine 16bit Variable 
aus.

von Volker B. (Firma: L-E-A) (vobs)


Bewertung
0 lesenswert
nicht lesenswert
Peet schrieb:

(...)
> #define F_CPU 32000000UL
(...)
> ADCA.PRESCALER = 0;          // Prescaler 4
(...)
> Ich möchte mir den Messwert auf 8LEDs anzeigen lassen. Allerdings stimmt
> nur jede zweite Messung. Bei den Messungen zwischendrin leuchtet immer
> nur die LED an Pin7. Woran liegt das?

Bist Du Dir sicher, dass der ADC mit 8 MHz noch sinnvoll arbeitet?
Das Datenblatt sagt max. 1800 kHz.

Ich verstehe auch nicht, warum Du eine dermaßen hohe ADC-Frequenz 
einstellst, wenn Du nur alle 4 s einen Messwert anforderst...

Ansonsten kann ich keinen (offensichtlichen) Fehler erkennen. Das Lesen 
von ADCA_CH0RESL sollte entgegen der hier geäußerten Mutmaßungen im 
gewählten 8-Bit-Modus korrekt sein.

Grüßle
Volker

: Bearbeitet durch User
Beitrag #5613417 wurde vom Autor gelöscht.
von Peet (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Volker B. schrieb:
> Bist Du Dir sicher, dass der ADC mit 8 MHz noch sinnvoll arbeitet?
> Das Datenblatt sagt max. 1800 kHz.
>
> Ich verstehe auch nicht, warum Du eine dermaßen hohe ADC-Frequenz
> einstellst, wenn Du nur alle 4 s einen Messwert anforderst..

Die 4 sek sind nur für Testzwecke.

Du hast recht. Genau das scheint der Fehler zu sein. Bis Prescaler 32 
funktioniert es. Bei 16 nicht mehr. Danke!

Das wundert mich aber. Damit würde ja eine Wandlung ca 250µs dauern. Ich 
kann mich erinnern einem Atmega88A Wandlungen von ca 30µs realisiert zu 
haben. Das muss doch irgendwie schneller gehen??

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Da muss ich meinen Code auch mal überprüfen, weil mein Prescaler auch 
falsch ist.

von Volker B. (Firma: L-E-A) (vobs)


Bewertung
0 lesenswert
nicht lesenswert
Peet schrieb:

> Du hast recht. Genau das scheint der Fehler zu sein. Bis Prescaler 32
> funktioniert es. Bei 16 nicht mehr. Danke!

Freut mich, dass das Problem gelöst werden konnte -- und danke für die 
Rückmeldung!

> Das wundert mich aber. Damit würde ja eine Wandlung ca 250µs dauern. Ich
> kann mich erinnern einem Atmega88A Wandlungen von ca 30µs realisiert zu
> haben.

Naja, die Xmegas haben einen 12-bit ADC ggü. den 10 Bit der AVRs.
Und 400kHz ADC-Takt für beim mega88A sind wohl auch schon deutlich 
außerhalb der Spezifikationen. Das kann, muss aber nicht funktionieren.

> Das muss doch irgendwie schneller gehen??

Wenn's auf Geschwindigkeit ankommt, warum konfigurierst Du den ADC dann 
nicht im free-running Mode? So sollten dann auch die "Up to 300 thousand 
samples per second" aus dem Datenblatt möglich sein.

Ansonsten solltest Du auf den XmegaAU umsteigen. Dank der vier Kanäle 
kann er mit einem ADC bis zu vier Quellen überlappend wandeln, wobei man 
natürlich auch die selbe Signalquelle auf alle Kanäle schalten kann.

Grüßle
Volker

von Peet (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Die Behauptung von mir bezüglich der Wandlungsdauer ist Unsinn. Bin aus 
irgendeinem Grund beim ADC von einer ähnlichen, taktweisen, 
inkrementation (256 Takte) wie bei einem 8-Bit-Timer ausgegangen.

Die Oszi-Messung ergibt rund 6µs!

von Volker B. (Firma: L-E-A) (vobs)


Bewertung
0 lesenswert
nicht lesenswert
Peet schrieb:

> Die Oszi-Messung ergibt rund 6µs!

OK, dann passt's ja zu den Angaben im Datenblatt. 300 kS/s wären 3.3 µs 
pro Wandlung. Im Single-Shot-Mode benötigt er doppelt so viele Zyklen, 
was dann die von Dir gemessenen 6 µs wären.

Grüßle
Volker

von Peet (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke.

Ich möchte nun gerne eine zweite Messung an einem anderen Pin 
durchführen und auch eine weitere ISR nutzen. Das müsste doch durch 
einen anderen Kanal realisierbar sein, oder?

Das heißt doch, wenn ich alle CH0 im Code durch CH1 ersetze müsste es 
doch funktionieren. Tut es aber nicht. Wieso?
1
int main(void)
2
{
3
initClock();
4
PORTD.DIRSET = 0b11111111 ;      // Output: 8xLED
5
6
ADCA.CTRLB = 0b00000100;    //ADC 8 Bit
7
ADCA.REFCTRL = 0b00010000;   //VCC/1.6 ref
8
ADCA.PRESCALER = 0x03;          // Prescaler 32
9
ADCA.CTRLA = 0b00000001;    // ADC enable
10
  
11
ADCA.CH1.MUXCTRL = 0b00001000;  //MUXPOS=ADC1 pin=PA1
12
13
sei();
14
PMIC.CTRL=0x07;
15
ADCA.CH1.INTCTRL = 0x03;    //prio high
16
    
17
18
while (1) 
19
{  
20
_delay_ms(4000);
21
ADCA.CH1.CTRL = 0b10000001;   //ADCA Channel 1 starten
22
}
23
24
}
25
26
27
    
28
    ISR (ADCA_CH1_vect)
29
    {
30
      temp1 = ADCA_CH0RESL;
31
      PORTD.OUT = temp1;
32
    }

von Volker B. (Firma: L-E-A) (vobs)


Bewertung
0 lesenswert
nicht lesenswert
Peet schrieb:
> Danke.
>
> Ich möchte nun gerne eine zweite Messung an einem anderen Pin
> durchführen und auch eine weitere ISR nutzen. Das müsste doch durch
> einen anderen Kanal realisierbar sein, oder?

...wenn der ATXmega16D4, den Du lt. obiger Aussage verwendest, mehr als 
einen hätte...

> Das heißt doch, wenn ich alle CH0 im Code durch CH1 ersetze müsste es
> doch funktionieren. Tut es aber nicht. Wieso?

Probier' den 16A4U...

Grüßle
Volker.

P.S.: "funktioniert nicht" ist eine saumäßig doofe Aussage! Vermutlich 
weigert sich bereits der Compiler. Die entsprechende Fehlermeldung wäre 
hier extrem hilfreich...

von Peet (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich erhalte keine Fehlermeldung.

Im Datenblatt steht:

One twelve-channel, 12-bit, 200ksps Analog to Digital Converter

Schade, ich habe mir bei dem Satz sogar 12 Kanäle vorgestellt :)

von Volker B. (Firma: L-E-A) (vobs)


Bewertung
0 lesenswert
nicht lesenswert
Peet schrieb:
> Ich erhalte keine Fehlermeldung.

Merkwürdig, in dem iox16d4.h auf meinem System ist weder ein
ADCA.CH1 noch ein ADCA_CH1_vect definiert.

> Im Datenblatt steht:
>
> One twelve-channel, 12-bit, 200ksps Analog to Digital Converter

Das ist mal wieder dümmliches Marketing-Geschwafel, das sich hier auf 
die Multiplexer-Kanäle bezieht.
M.W. hat nur die Ax(U)-Familie mehrere echte ADC-Kanäle, vier um genau 
zu sein.

> Schade, ich habe mir bei dem Satz sogar 12 Kanäle vorgestellt :)

Dann musst Du eben im Interrupt den Multiplexer umschalten. Wo ist das 
Problem?

Hinweis: Falls der ADC frei läuft, ist die nächste Wandlung bereits im 
Gang, wenn der Irpt-Handler ausgeführt wird. Das Umschalten des MUX 
wirkt also erst auf das Ergebnis, das im übernächsten Interrupt gelesen 
wird. Das erfordert etwas Gehirnartistik, ist aber machbar :-) und war 
bei den AVRs auch nicht anders.

Grüßle
Volker.

: Bearbeitet durch User
von Peet (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ziel ist es am Ende 4 Pins zu haben an denen zu bestimmten Zeitpunkten 
eine Spannung gemessen werden soll. Die Messwerte müssen in Variablen 
gespeichert werden. Pro Pin eine Variable, die stetig neu beschrieben 
wird.

OK, die Pins kann ich durch MUXCTRL einzeln abfragen/messen.

Aber wie mache ich das, wenn ich für alle 4 Pins nur eine ISR habe. Ich 
brauche eine eindeutige Zuordnung zwischen Pin und Variable.. Ich hoffe 
man versteht mein Problem...

Frage nebenbei.. wieso muss das Multiplexer umschalten unbedingt in der 
ISR erfolgen??

von Volker B. (Firma: L-E-A) (vobs)


Bewertung
0 lesenswert
nicht lesenswert
Peet schrieb:
> Ziel ist es am Ende 4 Pins zu haben an denen zu bestimmten Zeitpunkten
> eine Spannung gemessen werden soll.

Juhu, ich liebe Salami!

> OK, die Pins kann ich durch MUXCTRL einzeln abfragen/messen.

Wo ist dann das Problem?

> Aber wie mache ich das, wenn ich für alle 4 Pins nur eine ISR habe. Ich
> brauche eine eindeutige Zuordnung zwischen Pin und Variable.. Ich hoffe
> man versteht mein Problem...

Meine Güte! Wieviel RAM besitzt der 16D4? Da sollte es doch möglich 
sein, eine 8-Bit-Zählvariable zu opfern, die gleichzeitig als Index für 
das Feld mit den Ergebnissen dient?

Außerdem interessant: Oben forderst Du 12 ADC-Kanäle, nun genügen 
plötzlich vier -- weißt Du wirklich was Du willst?

> Frage nebenbei.. wieso muss das Multiplexer umschalten unbedingt in der
> ISR erfolgen??

Weil Du weiter oben darüber gejammert hast, dass Dir der ADC nicht 
schnell genug ist, bin ich davon ausgegangen, dass Du ein 
Super-Power-User bist, dem nichts schnell genug geht -- Salami eben...

Natürlich kannst Du den ADC im Single-Shot-Modus betreiben und in aller 
Ruhe den MUX einstellen und dann den ADC wieder starten. Dadurch wird 
die Samplerate aber mindestens halbiert. Da ich Deine Anwendung nicht 
kenne -- die Salami lässt grüßen -- kann ich leider nicht (hell-)sehen, 
ob das in Deiner Anwendung noch zulässig ist...

Grüßle
Volker

P.S.: Die anderen Menschen sind in der Regel nicht des Hellsehens 
mächtig!

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.