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
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
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?
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
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.
// 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
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
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 | }
|
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.