Forum: Mikrocontroller und Digitale Elektronik IR-Prorität bei ADCs


von Martin28 (Gast)


Lesenswert?

Hallo zusammen,

hänge grad ein bisschen beim programmieren fest.

Also: Controller:ATM8 also AVR Studio

habe bei meinem Programm den ADC3/4/5 im Betrieb und wollte wissen ob 
man jetzt anhand der Priorität des jeweiligen Feedbacks(3/4/5) sowas der 
interrupt Service Routine mitteilen kann.

Von den ISR`s habe ich 3 die folgendermaßen aufgebaut sind

ISR(ADC_vect,ADC_MUX_ADC3){bla}
ISR(ADC_vect,ADC_MUX_ADC4){bla}
ISR(ADC_vect,ADC_MUX_ADC5){bla}

Vielen Dank für Antworten...würde mir grade sehr helfen

von spess53 (Gast)


Lesenswert?

Hi

Du hast nur einen ADC und einen Interrupt. Welcher Kanal den 
Interrupt ausgelöst hat kannst du aus dem ADMUX-Register auslesen.

MfG Spess

von Martin28 (Gast)


Lesenswert?

Ja klar, habe im ADMUX z.B den Kanal.3 drinne.
Der wandelt dann auch und arbeitet die ISR(ADC_vect) ab.

Glaube eher das Problem ist wie Ich auf den Kanal.4 bzw. 5 komme.
Da Ich ja in der Main() den Kanal.3 zum wandeln definiert habe.

Ist das nicht über die in der 1sten Frage beschriebenen ISR(...) 
möglich?

von spess53 (Gast)


Lesenswert?

Hi

>Ist das nicht über die in der 1sten Frage beschriebenen ISR(...)
>möglich?

Nein. Du kannst einer ISR keinen Parameter übergeben, und auch keine 
drei ISRs definieren. Am besten du zeigst mal dein Programm.

MfG Spess

von Sven P. (Gast)


Lesenswert?

Martin28 schrieb:
> Glaube eher das Problem ist wie Ich auf den Kanal.4 bzw. 5 komme.
> Da Ich ja in der Main() den Kanal.3 zum wandeln definiert habe.
Indem du den Multiplexer auf Kanal 4 (oder 5) umstellst, den ADC wieder 
loslaufen lässt und das Ergebnis im nächsten Sprung in die ISR abholst?

Du hast halt nur einen ADC, dem der Multiplexer vorgeschaltet ist. Der 
ADC wandelt nur das, was aus dem Multiplexer rauskommt, und meldet sich 
per IRQ, wenn er fertig ist. Was der Multiplexer wiederum macht, ist dem 
ADC wurscht.

> Ist das nicht über die in der 1sten Frage beschriebenen ISR(...)
> möglich?
Doch schon. Du hast halt nur einen ADC, der erzeugt sinnigerweise 
immer denselben Interrupt, wenn er fertig ist, also springt der 
Prozessor dann immer in ein und dieselbe Serviceroutine.
Da kannst du das Ergebnis der Umwandlung dann abholen, den Multiplexer 
umstellen und den ADC erneut starten usw.

von Martin28 (Gast)


Lesenswert?

// AD Enable

    ADCSRA |= (1<<ADEN);
    ADCSRA |= (1<<ADSC);



    //ADCSRA |= (0<<ADATE);
    //ADCSRA |= (0<<ADIF);
    ADCSRA |= (0<<ADIE);
    ADCSRA |= (0<<ADPS2)|(0<<ADPS1)|(0<<ADPS0);






    ADMUX |= (0<<REFS1)|(0<<REFS0);
    ADMUX |= (0<<ADLAR);

    //ADMUX |= (0<<MUX3)|(0<<MUX2)|(1<<MUX1)|(1<<MUX0);
    //ADMUX |= (1<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
    //ADMUX |= (0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(1<<MUX0);
    ADMUX |= (1<<MUX3)|(1<<MUX2)|(0<<MUX1)|(0<<MUX0);


Wie man sieht, habe Ich hier nur einen Wert im ADMUX plaziert. Was in 
der ISR abgeht is ja jetzt erstmal nicht so wichtig.

Aber habe es schon verstanden, dass Ich nur eine ISR habe...
also ISR(ADC_vect).

Grüße

von spess53 (Gast)


Lesenswert?

Hi

>ADCSRA |= (1<<ADSC);

Du solltest den ADC erst mal fertig Konfigurieren bevor du eine Wandlung 
startest.

>ADCSRA |= (0<<ADPS2)|(0<<ADPS1)|(0<<ADPS0);

Der ADC-Takt sollte zwischen 50kHz und 200kHz liegen. Mit dieser 
Eistellung läuft er mit dem vollen Controllertakt.

>Wie man sieht, habe Ich hier nur einen Wert im ADMUX plaziert.

Es steht nirgends im Datenblatt im Datenblatt, das man den im Programm 
nicht wieder ändern kann.

MfG Spess

von Stephan K. (stephan_k)


Lesenswert?

Bitte schoen.....das funzt :-)
In data[] stehen die Werte der 7 AD-Kanaele fuer weitere Verarbeitung.



1
#include <avr/interrupt.h>
2
#include "adc_int.h"
3
4
volatile uint8_t ADC_ACTIVE_CHANNEL;
5
volatile data[8];
6
7
void INIT_ADC(void)
8
{
9
  uint16_t dummy_read;    // used for dummy reading
10
  
11
  ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Set ADC prescaler to 128 - 125KHz sample rate @ 16MHz
12
13
  ADMUX |= (1 << REFS0); // Set ADC reference to AVCC
14
  ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading
15
  
16
  // Normaly no MUX values needed to be changed to use ADC0
17
  // Just in case set them to first channel
18
  ADC_ACTIVE_CHANNEL = 0;
19
  ADMUX = (ADMUX & ~(0x1F)) | (ADC_ACTIVE_CHANNEL & 0x1F);
20
  
21
  ADCSRA &= ~(1 << ADATE);   // Disable free-Running Mode
22
  ADCSRA |= (1 << ADEN);    // Enable ADC
23
  ADCSRA |= (1 << ADSC);    // Start dummy conversion
24
  while (ADCSRA & (1<<ADSC) ) {}// Wait for result
25
26
  dummy_read = ADCW;    // Read the value from ADCW, or next result will not be taken
27
    
28
  ADCSRA |= (1 << ADIE);    // Enable ADC Interrupt
29
  
30
}
31
32
ISR(ADC_vect)
33
{
34
  ADCSRA &= ~(1 << ADIE);  // Disable ADC Interrupt
35
  
36
  // Copy ADCW value to the data structure and change channel for next interrupt 
37
  data[ADC_ACTIVE_CHANNEL] = ADCW;    // Store Value
38
  ADC_ACTIVE_CHANNEL++;    // Next channel
39
  if(ADC_ACTIVE_CHANNEL==8)
40
     ADC_ACTIVE_CHANNEL=0;
41
  // set active channel for next interrupt service
42
  ADMUX = (ADMUX & ~(0x1F)) | (ADC_ACTIVE_CHANNEL & 0x1F);
43
44
  ADCSRA |= (1 << ADIE);  // Enable ADC Interrupt
45
  ADCSRA |= (1 << ADSC);  // Start single conversion
46
  
47
}

von Martin28 (Gast)


Lesenswert?

Sorry, die Wandlung wurde etwas weiter oben in meinem Programm 
gestartet.

Alles klar. Danke für die Informationen Spess. Auch Danke an dich Sven.

Gruß Martin

von Martin28 (Gast)


Lesenswert?

Merci Stephan. :)

von Stephan K. (stephan_k)


Lesenswert?

Da ich die Frage gefragt bekommen habe ( korrekte Satzstellung? ), ich 
lese in dem Source nicht ADCH und ADCL als einzelnde Byte aus, sondern 
ADCW. Das ist das selbe, nur als Word-Wert. Hab auch noch kein 
Datenblatt gefunden, wo ADCW erklaert wird. Also, keine Panik. Das funzt 
so;-)

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.