Forum: Mikrocontroller und Digitale Elektronik ATtiny44 & ADC interne Vref


von Klaus R. (klaus2)


Lesenswert?

Hallo zusammen,

der ADC läuft, macht aber Unsinn - ich vermute, weil ich Aref als 
Ausgang nutze (muss). Muss ich den bei einem 44er auch mit 100n extern 
beschalten und darf ihn nicht als Ausgang nutzen? Als was muss DDRA 
definiert sein bzw. darf man nach dem Konfigurieren der internen Vref 
diesen Pin noch über DDRA & PORTA mit 0 (Ausgang) & 0 (low) beschreiben?

Derzeit nutze ich Aref als Ausgang und ich vermute, dass deshalb nur 
Murks gemessen wird?

Klaus.

von Klaus R. (klaus2)


Lesenswert?

...ich habe jetzt mal alles andere aus dem Program entfernt, um 
Interferenzen zu vermeiden. Nun passiert folgendes, beim ändern der 
Versorgungsspg ändern sich ADCL+H insofern, als dass die eingestellte 
Schwelle (250) erreicht und die LED an oder aus geht. Sieht also so aus, 
als wenn ich intern gegen einen falschen Kanal messe bzw. dieser nicht 
freigegeben ist?

...

uint16_t ADC_Read(void){

  uint16_t ADC_value=0;

  ADMUX  |= (1<<MUX2);        // Kanal 2 (PA2)

  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"

  while (ADCSRA & (1<<ADSC) ) {}   // auf Abschluss der Konvertierung 
warten

  ADC_value = ADCL;         // mit uint16_t x
  ADC_value += (ADCH<<8);   // in zwei Zeilen (LSB/MSB-

  return ADC_value;             // ADC auslesen und zurückgeben

}

...

//******************
// Hauptfunktion
//******************


int main(void) {


  DDRA = (0 << ADC) | (1 << LED_RHP) | (1 << LED_R) | (1 << LED_G) | (1 
<< LED_B) | (1 << LED_W) | (0 << Taste);
  PORTA = (0 << ADC) | (0 << LED_RHP) | (0 << LED_R) | (0 << LED_G) | (0 
<< LED_B) | (1 << LED_W) | (1 << Taste);

  DDRB &= (0 << Dynamo);
  PORTB |= (1 << Dynamo);



  TCCR0A = (1<<WGM01) | (1<<WGM00) | (0<<COM0A1) | (0<<COM0A0) | 
(1<<COM0B1) | (0<<COM0B0);  // Timer/Counter-Mode && PWM-Mode
  TCCR0B |= (1<<WGM02) |(0<<CS02)|(1<<CS01)|(1<<CS00);        // 
T/C-Mode & Prescaler

  GIMSK |= (1<<INT0)|(0<<PCIE1)|(0<<PCIE0);               // Ext. IRQ 
enabled & Pin Change Interrupt Mode
  MCUCR |= (1<<SM1)|(0<<SM0)|(1<<ISC01)|(0<<ISC00);          // 
Sleep-Mode & Falling Edge Interrupt

  TIMSK0 |= (0<<TOIE0) | (1<<OCIE0A) | (1<<OCIE0B);          // 
Timer-Overflow, Output-C A, Output-C B

  OCR0A = timer;
  OCR0B = 200;

  TCNT0 = timer;


  ADMUX = (1<<REFS1) | (0<<REFS0);                  // Interne Referenz 
1,1V
  ADCSRA = (1<<ADSC) | (1<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);       // 
Frequenzvorteiler
  ADCSRB |= (0<<ADLAR);                        // Linksbündig = 1
  ADCSRA |= (1<<ADEN);                                // ADC aktivieren

  sei();

  while(1) {

  // ADC auswerten

  if (flag_S == 1){

    PORTA ^= (1<<LED_R);

  uint16_t adcval_old, adcval=0;

  adcval_old = adcval;

  adcval = ADC_Read();

  if(adcval > 250) sbi(PORTA, LED_B);

  else cbi(PORTA, LED_B);

    }
}

von Stefan E. (sternst)


Lesenswert?

Klaus R. schrieb:
> ADMUX  |= (1<<MUX2);        // Kanal 2 (PA2)

Nö, das ist PA4.

von Klaus R. (klaus2)


Lesenswert?

...ich Idiot. Es ist natürlich MUX1 - man man man, jetzt tuts :)

EDIT: Danke, Stefan, mit fiel es gerade auch wie Schuppen von den Augen.

Gruß, Klaus.

von Ulrich H. (lurchi)


Lesenswert?

Beim Mux vom ADC schreibt man besser nicht (1<<MUX1), sondern gleich die 
2 für Kanal 2. Da kann man halt direkt die Kanalnummer eintragen, vor 
allem wenn man nicht die |= Verknüpfung nutzt sonder direkt den Wert 
einträgt.

von Klaus R. (klaus2)


Lesenswert?

Recht haste...läuft aber nun alles, wie es soll - Danke!

Und Aref muss nicht mit 100n versorgt werden, puh :)

Klaus.

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.