ADC-Messung an mehreren Ports

Gast #1388955
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.