Forum: Mikrocontroller und Digitale Elektronik ADC free running mode mit Interrupt


von Andi (Gast)


Lesenswert?

Hallo,
ich bin seit ein paar Tagen dabei einen Atmega 16 zu programmieren, mit 
welchem ich die Spannungen und Ströme in einem Labornetzteil messe und 
die Werte anschließend auf einem LCD ausgeben möchte. Zum vorläufigen 
Test möchte ich auf dem LCD in der ersten Zeile den aktuellen ADC-Wert 
von Kanal 1 und in der zweiten Zeile den aktuellen ADC-Wert von Kanal 2 
ausgeben.

Hier ist mein vorläufiges Programm:
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <util/delay.h>
4
#include <stdlib.h>
5
#include <stdio.h>
6
#include <avr/interrupt.h>
7
#include <math.h>
8
9
10
#define admux_init     0b01000001    //ADC1 wählen
11
12
uint16_t calc_fin=0, adc_1_voltage, adc_2_ref, adc_3_current, adc_4_current_limit;
13
unsigned char  count_step=0;
14
char buffer1[20], buffer2[20];
15
16
17
ISR(ADC_vect)
18
{
19
  switch(count_step)
20
  {
21
    case 0:
22
      
23
      adc_1_voltage= ADCW;
24
      ADCW=0;
25
      ADMUX= 0b01000010;  //ADC2 wählen
26
      break;
27
28
    case 1:
29
      adc_2_ref= ADCW;
30
      ADCW=0;
31
      ADMUX= 0b01000011;  //ADC3 wählen
32
      break;
33
34
    case 2:
35
      adc_3_current= ADCW;
36
      ADCW=0;
37
      ADMUX= 0b01000100;  //ADC4 wählen
38
      break;
39
40
    case 3:
41
      adc_4_current_limit= ADCW;
42
      ADCW=0;
43
      ADMUX= admux_init;  //ADC1 wählen
44
      break;
45
  }
46
47
  count_step++;
48
49
  if(count_step>3)
50
  {
51
    count_step=0;
52
  }
53
}
54
      
55
56
57
void display(void)
58
{
59
  
60
  lcd_setcursor(0 , 1);  //setze Cursor in erste Zeile
61
  utoa(adc_1_voltage, buffer1, 10);  
62
  lcd_string(buffer1);  //Ausgabe des ADC-Wertes von Kanal 1 in erster Zeile
63
  
64
  lcd_setcursor(0 , 2);  //setze Cursor in zweite Zeile
65
  utoa(adc_2_ref, buffer2, 10);  
66
  lcd_string(buffer2);  //Ausgabe des ADC-Wertes von Kanal 2 in zweiter Zeile    
67
68
}
69
70
71
void init(void)
72
{
73
  DDRB= 0b00100000;  //PB5 als Ausgang für LED
74
  ADCSRA= 0b11101111;  //ADC einschalten, start conversion,free running mode
75
  ADMUX= admux_init;  //left adjusted für 10 bit ADC- Wandlung, ADC1 wählen
76
  lcd_init();
77
  sei();    //global interrupts enable     
78
}
79
80
81
82
main()
83
{
84
  init();
85
86
  while(1)
87
  {
88
    //calculation();    
89
    display();    
90
  }
91
}

Leider hänge ich seit zwei Tagen an einem recht seltsamen Problem. Auf 
dem LCD wird nämlich in der ersten Zeile nicht der Wert von Kanal 1, 
sondern der von Kanal 4 angezeigt. Ähnlich sieht es mit der zweiten 
Zeile aus. Da wird nämlich nicht der Wert von Kanal 2, sondern der von 
Kanal 4 angezeigt.
Aufgrund dieses Fehlverhaltens habe ich probiert ich mir das Programm 
mit dem AVR Dragon im JTAG-Debugmodus angeschaut und dabei folgendes 
festgestellt:

Wenn ich mit F11 durchsteppe werden alle ADC-Werte in den korrekten 
Variablen abgespeichert, das ganze funktioniert auch über lange Zeit 
(längeres Drücken der F11 Taste). Allerdings wird die Funktion Display() 
nie richtig aufgerufen, immer wenn der Debugger reinspringen müsste ruft 
er erneut die ISR auf.

Wenn ich mit F10 durchsteppe bestätigt sich meine fehlerhafte 
LCD-Ausgabe. Im Watch-Fenster sieht man, dass der ADC-Wert von Kanal 4 
in der Variablen adc_1_voltage und der ADC-Wert von Kanal 1 in der 
Variablen adc_2_ref abgespeichert werden. Daran ändert sich auch nichts 
wenn ich lang auf F10 bleibe. Interessant ist auch, dass direkt nach 
Aufrufen der init-Funktion und anscheinend direkt vor aufrufen der 
display() Funktion zwei Interrupts korrekt ausgeführt werden (richtige 
Werte in den Variablen) und dann direkt nach dem ersten Aufruf der 
display() Funktion die richtigen Werte auf dem LCD erscheinen. Diese 
beiden Interrupts sind komischerweise beim Debuggen nicht sichtbar. Auf 
jeden Fall wird direkt nach dem ersten Aufrufen der display()-Funktion 
fälschlicherweise der Wert von Kanal 4 in der Variablen adc_1_voltage 
gespeichert und von da an funktioniert das Programm fehlerhaft.

Ich hoffe, dass meine Schilderungen verständlich waren und mir jemand 
helfen kann.

Vielen Dank im Voraus fürs Durchlesen und Mitdenken

Andi

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:

> Leider hänge ich seit zwei Tagen an einem recht seltsamen Problem. Auf
> dem LCD wird nämlich in der ersten Zeile nicht der Wert von Kanal 1,
> sondern der von Kanal 4 angezeigt.

Tja.
Eine Änderung des MUX wirkt sich erst beim Start der nächsten Messung 
aus. Zu dem Zeitpunkt an dem du in der ISR den MUX änderst, läuft aber 
schon die nächste Messung. D.h. der Interrupt für diese Messung benutzt 
noch die alte MUX Einstellung. Oder anders gesagt: du änderst gerade den 
MUX, dessen Ergebnis du erst bei der übernächsten Messung bekommen 
wirst.


Ganz ehrlich:
Ich würd da nicht wirklich mit dem Free Running Mode und Interrupt 
rumwerken. D.h. Interrupt - ja - vielleicht. Aber nicht Free Running.

Bringt ja sowieso nichts. So schnell wie du sampelst, kannst du eh das 
Display nicht updaten, weil kein Mensch so schnell schauen kann.

von Andi (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Tja.
> Eine Änderung des MUX wirkt sich erst bei der nächsten Messung aus. Zu
> dem Zeitpunkt an dem du in der ISR den MUX änderst, läuft aber schon die
> nächste Messung. D.h. der Interrupt für diese Messung benutzt noch die
> alte MUX Einstellung.

Das mit der Änderung der MUX ist mir schon klar. Das hab ich im Code 
schon berücksichtigt. Beim Studieren haben wir das auch schon mal so 
ähnlich gemacht. Drum sollte es prinzipiell funktionieren.

Karl Heinz Buchegger schrieb:
> anz ehrlich:
> Ich würd da nicht wirklich mit dem Free Running Mode und Interrupt
> rumwerken. D.h. Interrupt - ja - vielleicht. Aber nicht Free Running.

Ich könnte es auch mit single conversion in einer Funktion ganz ohne 
Interrupt machen. Aber irgendwie fand ich die Lösung vom Studium mit 
free running mode und Interrupt am Elegantesten.

von Peter D. (peda)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Bringt ja sowieso nichts. So schnell wie du sampelst, kannst du eh das
> Display nicht updaten, weil kein Mensch so schnell schauen kann.

So isses!

Ergonomisch ist eine Anzeigerate von 200..500ms.
Für 4 Meßwerte also einen Timerinterrupt alle 50ms die Messung starten 
lassen und dann nach 200ms auf das LCD ausgeben.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:

> Ich könnte es auch mit single conversion in einer Funktion ganz ohne
> Interrupt machen. Aber irgendwie fand ich die Lösung vom Studium mit
> free running mode und Interrupt am Elegantesten.

Find ich ehrlich gesagt nicht.
Wenn man bedenkt, dass der ADC nur eine Handvoll Takte zum Wandeln 
braucht, macht dein µC (fast) nix anderes mehr, als nur ADC-Interrupt 
bearbeiten. Und das aus keinem guten Grund.
Ist er mit einer ISR fertig, hat auch der ADC schon wieder ein Ergebnis 
und schon wieder gehts in die nächste ISR rein.
Und ehrlich gesagt: Ich bin mir nicht sicher, ob dann die Zuordnung von 
MUX zu deiner Zählvariable noch stimmt.

: Wiederhergestellt durch User
von Peter D. (peda)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und ehrlich gesagt: Ich bin mir nicht sicher, ob dann die Zuordnung von
> MUX zu deiner Zählvariable noch stimmt.

Deshalb im Interrupt den ADC auslesen, den MUX umschalten und dann erst 
die nächste Messung starten. Dann kann auch mal ein anderer Interrupt 
dazwischen kommen und nichts geht schief.

Free-Running ist nur für einen Kanal richtig geeignet. Dann braucht man 
keinen Interrupt und das Main liest den ADC, wann es will.


Peter

von Norbert (Gast)


Lesenswert?

Hmmm, vielleicht eine andere Optimierung benutzt?
Die Variablen, die in der ISR verändert werden sind nicht als volatile 
gekennzeichnet!

Die free-running Konfiguration sollte kein Problem darstellen, wenn man 
der Versatz -1 berücksichtigt.

von Andi (Gast)


Lesenswert?

Jetzt hab ich gerade nochmal in meinen Studienunterlagen nachgekuckt. 
Mein Programmaufbau entspricht genau dem, was unser Professor uns damals 
gezeigt hatte. Allerdings muss ich dazu sagen, dass er uns das nur 
theoretisch an der Tafel gezeigt hat, ich es also praktisch noch nie so 
funktionieren gesehen habe.

Karl Heinz Buchegger schrieb:
> Find ich ehrlich gesagt nicht.
> Wenn man bedenkt, dass der ADC nur eine Handvoll Takte zum Wandeln
> braucht, macht dein µC (fast) nix anderes mehr, als nur ADC-Interrupt
> bearbeiten. Und das aus keinem guten Grund.
> Ist er mit einer ISR fertig, hat auch der ADC schon wieder ein Ergebnis
> und schon wieder gehts in die nächste ISR rein.
> Und ehrlich gesagt: Ich bin mir nicht sicher, ob dann die Zuordnung von
> MUX zu deiner Zählvariable noch stimmt.

Deine Erklärung macht dann schon Sinn. Ich bin beim Verstehen der 
Vorlesungslösung immer davon ausgegangen, dass nach einer 
abgeschlossenen AD-Wandlung das Ergebnis ausgelesen wird und 
anschließend das ADMUX Register für den nächsten Kanal verändert wird 
und erst danach der AD-Wandler mit der nächsten Wandlung beginnt. Bin 
also davon ausgegangen, dass zwischen dem Ende einer AD-Wandlung und dem 
Beginn einer neuen immer eine kleine Pause ist, dass das mit dem Updaten 
des ADMUX Registers es so funktioniert.

Dass dem nicht so ist und  auch Professoren nur Menschen sind wäre 
hiermit mal wieder belegt.

Peter Dannegger schrieb:
> Deshalb im Interrupt den ADC auslesen, den MUX umschalten und dann erst
> die nächste Messung starten. Dann kann auch mal ein anderer Interrupt
> dazwischen kommen und nichts geht schief.
>
> Free-Running ist nur für einen Kanal richtig geeignet. Dann braucht man
> keinen Interrupt und das Main liest den ADC, wann es will.
>
>
> Peter

Das sehe ich jetzt, nachdem ich nun weiß, dass sich ein free running 
mode mit mehreren Kanälen mit nur einem Interrupt nicht bewerkstelligen 
lässt genauso. Darum werd ich jetzt das ganze einfach mit Single 
Conversion in einer Funktion lösen.

Danke vielmals für eure Hilfe. Ohne euch würde ich noch ewig versuchen 
eine nicht funktionierende Lösung zum Laufen zu bringen.

von 121212qw (Gast)


Lesenswert?

Hi

> Wenn man bedenkt, dass der ADC nur eine Handvoll Takte zum Wandeln
> braucht, macht dein µC (fast) nix anderes mehr, als nur ADC-Interrupt
> bearbeiten. Und das aus keinem guten Grund.

Na ja nicht ganz. Mit seiner Einstellung dauert eine AD-Wandlung 13x128 
Controllertakte. Also ist der Controller maximal zu 5...10% mit dem 
AD-Wandler beschäftigt. Das ganze lässt sich reduzieren, wenn man statt 
Free-Running den Autotrigger-Mode benutzt, also mit einen Timer 
triggern.

MfG spess

von Norbert (Gast)


Lesenswert?

Andi schrieb:
> Das sehe ich jetzt, nachdem ich nun weiß, dass sich ein free running
> mode mit mehreren Kanälen mit nur einem Interrupt nicht bewerkstelligen
> lässt genauso. Darum werd ich jetzt das ganze einfach mit Single
> Conversion in einer Funktion lösen.

Selbstverständlich lässt sich das bewerkstelligen.

Wenn der Interrupt ausgelöst wird und du bspw. auf Kanal drei 
umschaltest, so weisst du automatisch das der gerade von dir gelesene 
Wert zu Kanal zwei gehört!

0 - > 3
1 - > 0
2 - > 1
3 - > 2

von Norbert (Gast)


Lesenswert?

Noch etwas detaillierter beschrieben:

- Interrupt löst aus
- Der ADC befindet sich bereits in der Konvertierphase und nutz dazu den
  MUX Wert der von dir beim letzten Interrupt gesetzt wurde.
- ADC Wert wird gelesen
- Du setzt den neuen MUX Kanal (der aber erst beim nächsten Mal genutzt 
wird)
- ISR wird verlassen

von 121212qw (Gast)


Lesenswert?

Hi

>Wenn der Interrupt ausgelöst wird und du bspw. auf Kanal drei
>umschaltest, so weisst du automatisch das der gerade von dir gelesene
>Wert zu Kanal zwei gehört!

Einfacher ist es, ADMUX vorher auszulesen. Dann weiß man gleich, von 
welchem Kanal der Wert stammt.

MfG Spess

von Norbert (Gast)


Lesenswert?

121212qw schrieb:
> Einfacher ist es, ADMUX vorher auszulesen. Dann weiß man gleich, von
> welchem Kanal der Wert stammt.

Das stimmt, jedoch hat man dann noch eine volatile globale Variable die 
den identischen Informationsgehalt wie (count_step) nur um eins 
verschoben vorhält.

Wenn man nicht mit Prozessorzyklen oder Speicher haushalten muss ist es 
allerdings am Bequemsten.

von Andi (Gast)


Lesenswert?

121212qw schrieb:
> Einfacher ist es, ADMUX vorher auszulesen. Dann weiß man gleich, von
> welchem Kanal der Wert stammt.

Jetzt hab ich es mal nach deinem Vorschlag programmiert:

1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <util/delay.h>
4
#include <stdlib.h>
5
#include <stdio.h>
6
#include <avr/interrupt.h>
7
#include <math.h>
8
9
10
#define admux_init     0b01000001    //ADC1 wählen
11
12
uint16_t calc_fin=0, adc_1_voltage, adc_2_ref, adc_3_current, adc_4_current_limit;
13
unsigned char  count_step=0;
14
char buffer1[20], buffer2[20];
15
16
ISR(ADC_vect)
17
{
18
  switch(ADMUX & 0b00000111)
19
  {
20
    case 0b00000001:   adc_1_voltage= ADCW;
21
              ADCW=0;
22
              ADMUX= 0b01000010;  //ADC2 wählen
23
              break;
24
25
    case 0b00000010:  adc_2_ref= ADCW;
26
              ADCW=0;
27
              ADMUX= 0b01000011;  //ADC3 wählen
28
              break;  
29
30
    case 0b00000011:  adc_3_current= ADCW;
31
              ADCW=0;
32
              ADMUX= 0b01000100;  //ADC4 wählen
33
              break;
34
35
    case 0b00000100:  adc_4_current_limit= ADCW;
36
              ADCW=0;
37
              ADMUX= admux_init;  //ADC1 wählen
38
              break;
39
  }
40
}
41
      
42
43
void display(void)
44
{
45
  
46
  lcd_setcursor(0 , 1);  //setze Cursor in erste Zeile
47
  utoa(adc_1_voltage, buffer1, 10);  
48
  lcd_string(buffer1);  //Ausgabe des ADC-Wertes von Kanal 1 in erster Zeile
49
  
50
  lcd_setcursor(0 , 2);  //setze Cursor in zweite Zeile
51
  utoa(adc_2_ref, buffer2, 10);  
52
  lcd_string(buffer2);  //Ausgabe des ADC-Wertes von Kanal 2 in zweiter Zeile    
53
54
}
55
56
57
void init(void)
58
{
59
  DDRB= 0b00100000;  //PB5 als Ausgang für LED
60
  ADCSRA= 0b11101111;  //ADC einschalten, start conversion,free running mode
61
  ADMUX= admux_init;  //left adjusted für 10 bit ADC- Wandlung, ADC1 wählen
62
  lcd_init();
63
  sei();    //global interrupts enable     
64
}
65
66
67
68
main()
69
{
70
  init();
71
72
  while(1)
73
  {    
74
    display();    
75
  }
76
}



So habt ihr es doch gemeint, oder?
Das Programm hat aber genau die selbe Fehlfunktion wie vorher.

Gruß

von Ingo (Gast)


Lesenswert?

Verabschiede dich mal von dem Freerunmodus, trigger deine Messung per 
Hand...

von 121212qw (Gast)


Lesenswert?

Hi

>Verabschiede dich mal von dem Freerunmodus, trigger deine Messung per
>Hand...

Begründung.

MfG Spess

von Norbert (Gast)


Lesenswert?

Andi schrieb:
> So habt ihr es doch gemeint, oder?
> Das Programm hat aber genau die selbe Fehlfunktion wie vorher.

1) Die Variablen, die in der ISR modifiziert und im Hauptprogramm 
gelesen werden, sind immer noch nicht volatile.

2) Seh' ich das richtig,
  ADC_Kanal0 wird nicht benutzt,
  ADC_Kanal1-4 entsprechen den Variablen:
    adc_1_voltage, adc_2_ref, adc_3_current, adc_4_current_limit
  ADC_Kanal5-7 sind auch ungenutzt?

Dann wäre die ISR so richtig.

3) An Punkt 1) denken!

von Andi (Gast)


Lesenswert?

Norbert schrieb:
> 2) Seh' ich das richtig,
>   ADC_Kanal0 wird nicht benutzt,
>   ADC_Kanal1-4 entsprechen den Variablen:
>     adc_1_voltage, adc_2_ref, adc_3_current, adc_4_current_limit
>   ADC_Kanal5-7 sind auch ungenutzt?
>
> Dann wäre die ISR so richtig.

Ja genau so ist es. Nur Kanal 1 bis 4 hab ich benutzt.

Norbert schrieb:
> 1) Die Variablen, die in der ISR modifiziert und im Hauptprogramm
> gelesen werden, sind immer noch nicht volatile.

Habe ich jetzt gerade auch mal ausprobiert. Die globale Variablen 
einfach mal mit dem Namenszusatz volatile deklariert. Die Fehlfunktion 
des Programms bleibt aber weiterhin bestehen.

Aus diesem Grund habe ich mich zur klassischen Lösung mit Funktion und 
Single Conversion Mode entschieden, welche auch ohne Probleme 
funktioniert:
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <util/delay.h>
4
#include <stdlib.h>
5
#include <stdio.h>
6
#include <avr/interrupt.h>
7
#include <math.h>
8
9
10
#define adc_1     0b01000001    //ADC1 wählen
11
#define adc_2     0b01000010    //ADC2 wählen
12
#define adc_3     0b01000011    //ADC3 wählen
13
#define adc_4     0b01000100    //ADC4 wählen
14
15
uint16_t read_adc(uint8_t channel);
16
17
uint16_t calc_fin=0, adc_1_voltage, adc_2_ref, adc_3_current, adc_4_current_limit;
18
unsigned char  count_step=0;
19
char buffer1[20], buffer2[20];
20
21
  
22
23
24
25
uint16_t read_adc(uint8_t channel)
26
{
27
  uint16_t adc_value;
28
29
  ADMUX= channel;
30
  ADCSRA|= 0b01000000;  //start conversion
31
  while(ADCSRA & 0b01000000);    //warte bis AD-Wandlung abgeschlossen ist
32
  adc_value = ADCW;
33
  return adc_value;
34
35
}
36
void display(void)
37
{
38
  
39
  lcd_setcursor(0 , 1);  //setze Cursor in erste Zeile
40
  dtostrf(u_out,5,2,buffer1);
41
  lcd_string(buffer1);  //Ausgabe des ADC-Wertes von Kanal 1 in erster Zeile
42
  
43
  
44
45
}
46
47
48
void init(void)
49
{
50
  DDRB= 0b00100000;  //PB5 als Ausgang für LED
51
  ADCSRA= 0b10000111;  //ADC einschalten, single conversion
52
  lcd_init();    
53
}
54
55
56
57
main()
58
{
59
  init();
60
61
  while(1)
62
  {
63
    adc_1_voltage = read_adc(adc_1);
64
    adc_2_ref = read_adc(adc_2);
65
    adc_3_current = read_adc(adc_3);
66
    adc_4_current_limit = read_adc(adc_4);
67
68
    calculation();    
69
    display();    
70
  }
71
}

Gruß

von 121212qw (Gast)


Lesenswert?

Hi

>Die Fehlfunktion des Programms bleibt aber weiterhin bestehen.

Das kann aber nur an deinen C-Kenntnissen liegen. Ich benutze den ADC im 
Free-Running-Mode oder Autotrigger mit 2 bis 4 Kanälen seit über 12 
Jahren in verschiedenen Geräten. Allerdings in Assembler. Am ADC kann es 
also nicht liegen.

MfG Spess

von Ingo (Gast)


Lesenswert?

@Spess:
Weil es unsinnig ist, einen Interrupt auszulösen wenn die Wandlung 
fertig ist, wenn der ADC im Freerun ist. Dann lieber dann messen wenn 
man einen Messwert braucht. Du löst sicherlich keinen Interrupt aus wenn 
die Wandlung fertig ist, oder? Sollte die CPU Auslastung deutlich 
reduzieren. Ich trigger immer mittels Timer in einem bestimmten 
Zeitraster eine Messung und schalte den MUX nach Belieben um, wenn eine 
Messung fertig ist.

Hat man DMA kann man natürlich Freerun machen, der DMA schaufelt dann 
die Werte in dieVariable ohne CPU Auslastung.


Ingo

von 121212qw (Gast)


Lesenswert?

Hi

>Du löst sicherlich keinen Interrupt aus wenn
>die Wandlung fertig ist, oder?

Selbstverständlich. Ich hatte schon weiter oben geschrieben, das die 
CPU-Belastung bei den ADC-Einstellungen von Andi relativ gering ist. Bei 
angenommenen 100 Takten für den Interrupt sind es ca. 6% im 
Free-Running-Mode. Mit Autotrigger durch einen Timer lässt sich diese 
fast beliebig verkleinern. Also wo ist das Problem?

MfG Spess

von Norbert (Gast)


Lesenswert?

Ingo schrieb:
> Weil es unsinnig ist, einen Interrupt auszulösen wenn die Wandlung
> fertig ist, wenn der ADC im Freerun ist.

Darum haben sich die Atmel Leute auch gedacht:

Ach komm', ist zwar unsinnig aber lass uns doch trotzdem einen Interrupt 
Pfad für den ADC einbauen. Dann kann er immer schön einen Interrupt 
auslösen wenn eine Konvertierung fertig ist, ist zwar Quatsch weil 
Polling viel eleganter ist aber wir machen's doch mal... Haben ja gerade 
sowieso nichts zu tun und Chipfläche kostet auch kein Geld...

Und jetzt noch mal deutlich:
GERADE im free-running mode ist der ADC-IRQ Gold wert, erlaubt er doch 
zum Beispiel mit geringstmöglichem Overhead die maximale Anzahl an 
Konvertierungen reinzuholen und zu verarbeiten während die Hauptroutine 
nur minimal gebremst wird.

von Ingo (Gast)


Lesenswert?

Wie ihr meint.

von 121212qw (Gast)


Lesenswert?

Hi

>Wie ihr meint.

Du machst es doch auch so:

>Ich trigger immer mittels Timer in einem bestimmten
>Zeitraster eine Messung und schalte den MUX nach Belieben um, wenn eine
>Messung fertig ist.

Das ist das gleiche wie Autotrigger. Und Autotrigger über einen Timer 
benutze ich auch seit dem die AVRs das haben. Bei den ersten Geräten 
wurde ein ATMega103 eingesetzt der nur Free-Runnig-Mode kannte.
Und den ADC kann man auch abschalten, wenn man ihn nicht braucht. Dann 
gibt es auch keinen Interrupt.

MfG Spess

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.