ADC-Messung an mehreren Ports

Gast #1388955
Lesenswert?

Hallo Leute,

ich versuche gerade an meinem atmega168 abwechselnd die Ports ADC6 und 
ADC7 einzulesen.

So aktiviere ich das ganze:
1
ADMUX |= (1<<REFS1) | (1<<REFS0); 
2
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); 
3
// ADC On | ADC Start | Irq after Compare | Irq On | Prescale 128

und so versuche ich das Ganze zuzuweisen:
1
SIGNAL(SIG_ADC) {
2
      
3
  switch(ADMUX & 0x07) {
4
     case 0x06:   adc0_value = ADCW; 
5
                  ADMUX |= 0x07;break;
6
     case 0x07:   adc1_value = ADCW; 
7
                  ADMUX |= 0x06;break;
8
     default:     ADMUX |= 0x06;break;
9
    } 
10
    
11
    ADCSRA |= (1<<ADSC);
12
 }

Mein Problem ist, er springt nur einmal den Port 0x06 an.
Den Port 0x07 aktualisiert er aber regelmäßig und korrekt.

An was kann denn das liegen?

Danke im Voraus!
#1390457
Lesenswert?

Hallo,

subguru schrieb:
> Oh ja, vielen Dank!!!
>
> Ich ging davon aus er setzt mir die Bits so wie ich sie angebe. Da fehlt
> mir wohl die Praxis ;-)

Was hat das mit Praxis zu tun? ;-)

Schreib es doch mal nicht verkürzt:
     default:     ADMUX |= 0x06;break;

     default:     ADMUX = ADMUX | 0x06;

Wenn jetzt in ADMUX bereits 0x07 steht und mit 0x06 oder verknüpft wird, 
was ändert sich dann wohl?

   00000111
OR 00000110
------------
   00000111

Gruß aus Berlin
Michael
Moderator (Firma: Titel) Persönliche Seite #1390528
Lesenswert?

subguru schrieb:
> Ich ging davon aus er setzt mir die Bits so wie ich sie angebe.
Er setzt sie schon, aber er lässt die anderen Bits gesetzt.
So wäre das besser:
1
     case 0x06:   adc0_value = ADCW; 
2
                  ADMUX = 0x07; break;
3
     case 0x07:   adc1_value = ADCW; 
4
                  ADMUX = 0x06; break; // diese Zeile könntest du sogar ganz weglassen ;-)
5
     default:     ADMUX = 0x06; break;
#1390939
Lesenswert?

Hallo,

Lothar Miller schrieb:
> subguru schrieb:
>> Ich ging davon aus er setzt mir die Bits so wie ich sie angebe.
> Er setzt sie schon, aber er lässt die anderen Bits gesetzt.
> So wäre das besser:
>
1
>      case 0x06:   adc0_value = ADCW;
2
>                   ADMUX = 0x07; break;
3
>      case 0x07:   adc1_value = ADCW;
4
>                   ADMUX = 0x06; break; // diese Zeile könntest du sogar
5
> ganz weglassen ;-)
6
>      default:     ADMUX = 0x06; break;
7
>

auch diese Lösung führt nicht unbedingt zum gewünschten Ergebnis,
in ADMUX sind noch andere Bits, REFS0, REFS1 und ADLAR beim Mega8 als 
Beispiel.

Die würden dann mit auf 0 gesetzt...

Richtig wäre:

      default:     ADMUX = (ADMUX & 0xF8) | 0x06; break;
Noch besser wäre eine Maske zu definieren:

#define MUX_MASK 0b11111000 // MUX-Bits auf 0
#define MUX6     0b00000110
#define MUX7     0b00000111

und dann
      default:     ADMUX = (ADMUX & MUX_MASK) | MUX6; break;

oder ähnlich.
Die Definitionen ins passende Headerfile gepackt und man hat bei 
Umbauten nur eine Stelle zum Ändern.

PS: meine Fehler bitte durch C-Programmierer korrigieren,
ich mache immernoch sehr wenig C und viel Assembler...

Gruß aus Berlin
Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren