ADC bei ATmega328p triggert immer

Gast #4907209
Lesenswert?

Hallo allerseits,

Ich habe einen ATmega328p - pu und an den ADC 5 ein Potentiometer 
geschlossen. An einem weiteren Pin habe ich eine LED gehängt, die immer 
dann genau ein mal blinkt, sobald ich die ISR des AD´s betrete 
(ADC_vect).
Was ich komisch finde, ist ,dass sobald ich den ADC5 mit einem 
Jumper-Kabel mit einem konstanten Potential verbinde (z.b. +5V) (oder 
GND), dass bei mir die LED durchblinkt....das heißt, dass ich dauernd 
von neuem in die ISR hineinspringe, obwohl der AD-Eingang auf einem 
konstanten Level ist.
Hab ich mich bis jetzt immer getäuscht, oder wurde nicht behauptet, dass 
nur dann in die (AD)-ISR hineingesprungen wird, wenn eine Änderung am 
AD-Eingang vorliegt ?

Bei mir scheint dauernd hineingesprungen zu werden....außer ich lasse 
den AD-Eingang ohne Anschluss, also das Kabel in der Luft hängen.

Oder kann es nur sein, dass meine Spannungsversorgung vom µC (USB) immer 
etwas schwankt, und der so leichte Änderungen merkt ?

Danke für die Hilfe, mfg
Felix
Gast #4907215
Lesenswert?

Hallo,

also dies "ich dauernd von neuem in die ISR hineinspringe" bezweifele 
ich.
Dafür sind wir Menschen viel zu groß. :;

Es liegt an deinem Programm...

Wenn der ADC mit einem passenden Prescaler und der ADC Interrupt richt 
eingerichtet wurde, dann wird nach ein pass µs immer der ADC Interrupt 
Vektor angesprungen. Dort muss man des ADC-Wert ADCW auch lesen.
Startest Du dort die ADC - Wandlung neu ?
Gast #4907218
Lesenswert?

Hi,

Ach ja behaupten muss man nichts ! Denn es gibt Datenblätter zu deinem 
AVR µC und Application Notes von Atmel zu unterschiedlichen 
Fragestellungen.
Diese sind deine Bibel - oder auch Wissensbasis - ohne Diese man so 
einen AVR µC eigentlich nicht nutzen kann.
Gast #4907248
Lesenswert?

Hier mein Code:

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h> //Nur zu Testzwecken

void ADC_init(void);

volatile int farbwert=0;

int main(void)
{

DDRD |= (1<<PD3);
PORTD |= (1<<PD3); //Hier hängt die LED,


  ADC_init();
  sei();

    while (1);
}

ISR(ADC_vect)
{
  farbwert = ADCH;

  PORTD ^= (1<<PD3); //Hier soll sich der Status der LED ändern....hier 
blinkt es aber dauernd, obwohl ich nicht am POTI drehe.... ??? warum ???

  _delay_ms(100); //Ich weiß, Delay in ISR = Katastrophe....ist aber nur 
zu Testzwecken

}

void ADC_init(void)
{
ADMUX |= (1<<REFS0)|(1<<MUX2)|(1<<MUX0)|(1<<ADLAR); //Referenzspannung 
intern 5V, ADC5, Nur 8 bit Result
ADCSRA |= 
(1<<ADEN)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADIE)|(1<<ADATE)|(1<<ADSC); 
//Enable, Prescaller von 8, Interrupt Enable, Left-Adjust für 8 bit, 
Start Conversion
//Per Default befindet sich der ADC im FreeRunningMode, d.h. er Triggert 
automatisch bei Änderung
}
Gast #4907250
Lesenswert?

Sorry, hatte vergessen, den Code mit Formatvorlagen zu bearbeiten ^^

1
Hier mein Code:
2

3
#define F_CPU 8000000UL
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include <util/delay.h> //Nur zu Testzwecken
7

8
void ADC_init(void);
9

10
volatile int farbwert=0;
11

12
int main(void)
13
{
14

15
DDRD |= (1<<PD3);
16
PORTD |= (1<<PD3); //Hier hängt die LED,
17

18

19
  ADC_init();
20
  sei();
21

22
    while (1);
23
}
24

25
ISR(ADC_vect)
26
{
27
  farbwert = ADCH;
28
  
29
  PORTD ^= (1<<PD3); //Hier soll sich der Status der LED ändern....hier blinkt es aber dauernd, obwohl ich nicht am POTI drehe.... ??? warum ???
30

31
  _delay_ms(100); //Ich weiß, Delay in ISR = Katastrophe....ist aber nur zu Testzwecken
32
  
33
}
34

35
void ADC_init(void)
36
{
37
ADMUX |= (1<<REFS0)|(1<<MUX2)|(1<<MUX0)|(1<<ADLAR); //Referenzspannung intern 5V, ADC5, Nur 8 bit Result
38
ADCSRA |= (1<<ADEN)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADIE)|(1<<ADATE)|(1<<ADSC); //Enable, Prescaller von 8, Interrupt Enable, Left-Adjust für 8 bit, Start Conversion
39
//Per Default befindet sich der ADC im FreeRunningMode, d.h. er Triggert automatisch bei Änderung
40
}
Gast #4907279
Lesenswert?

Hi Felix ,

fein nun ist doch alles klar, das Programm macht genau, was Du 
programmiert hast !

Wenn Du nun z.B. Timer 0 auf eine 100ms Intervall einstellst und den 
ADC-Wandler über den Timer 0 triggerst, dann erhälst Du eine 
Wandlungsrate von 10Hz.

Und die LED blinkt nicht so schnell.
Gast #4907341
Lesenswert?

In 99% der Fälle muss der ADC nicht im Free-Running-Mode laufen,
wenn man sowieso die Werte nur alle 0,5 bis 10 ms abholt und
verarbeitet. Die Beobachtung eines Potis ist genau so ein Fall!

Welche zeitliche Auflösung ist denn für die Messwerte
erforderlich???

Meist geht es so viel besser:

Timer-Interrupt alle 0,5 bis 10 ms (oder > 10 ms)
- Hole ADC-Wert ab
- Starte ADC neu (Single Aquisition!)
  (Bei einem ADC-Takt von 50...200 kHz ist der neue Wert
   nach 0,26...0,065 ms abholbereit)
  Also gibt's beim nächsten Timer-Interrupt einen neuen Wert.
- Arbeite alles andere ab, was zeitlich getaktet sein muss...
- RETI (Ende der Interrupt-Service-Routine)
#4907405
Lesenswert?

Je nach Prozessor ist freerunning etwas anders. Der SAM3X oder nen LPC 
z.B. lassen den letzten Wert im Register bis man ihn einmal ausgelesen 
hat. Dann wird automatisch ein neuer Wert eingelesen. Hier beim Atmega 
ist das aber anders.

Der ADC-Wert an sich ist aber auch nie so stabil, sodass er sich auch 
bei angelegten VCC ändern wird.
#4907442
Lesenswert?

Nico W. schrieb:
> Der ADC-Wert an sich ist aber auch nie so stabil, sodass er sich auch
> bei angelegten VCC ändern wird.

Wie bitte? Aber nur wenn man Vcc als Referenz nimmt und AVcc nicht 
entsprechend beschaltet hat. Hält man sich an die Empfehlungen von Atmel 
dann ist der ADC-Wert bei stabilen Umgebungsbedingungen bei gleicher 
Messspannung bombenfest, da ändert sich schlicht gar nichts.
Gast #4907527
Lesenswert?

M. K. schrieb:
> Avr schrieb:
> Delay im isr? Ist nicht sein ernst, oder?
>
> Den Kommentar daneben hast du aber auch gelesen, oder?

Der Kommentar klingt in etwa: sich ins Knie zu schießen ist nicht gut, 
aber ich mache es mal tritzdem, mal gucken was passiert...

Wie auch immer, muss jeder selber wissen wie er etwas macht, ich 
bevorzuge es, das Datenblatt zu lesen.
#4907581
Lesenswert?

Hi

Dem TO ist scheinbar bekannt, daß ein Delay in einer ISR nichts zu 
suchen hat.

Warum hat Er Es denn nun doch gemacht??
Naja, wenn man etwas nachdenkt, KÖNNTE dieses Delay dafür gut sein, daß 
man die LED aufblitzen sehen KANN - sonst hat man das gleiche Problem, 
wie bei einem prellendem Taster, daß dort auch 2 ISR direkt 
hintereinander kommen können und die Diagnose-LED scheinbar Nichts 
anzeigt.

Aber was laber ich hier- habt Ihr bestimmt bedacht und trotzdem als 'Du 
pöser Pursche Du' verworfen, weil: Man macht 'Es' einfach nicht und wenn 
so was gemacht wird, wird auch NIEMALS das Hirn eingeschaltet ... 
schließlich wissen wir ja, was man nicht macht, schei? drauf, was der TO 
sich wohl gedacht hat ... blöde Anfänger ...

So, jetzt könnt Ihr weiter machen ... Stichworte waren: ISR und Delay

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