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
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 ?
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.
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
}
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.
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)
Super, danke, bin fälschlicherweise immer davon ausgegangen, dass im
Freerunningmode nur dann in die ISR gesprungen wird, wenn der Wert am
AD-Eingang sich ändert.
Danke vielmals,
LG
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.
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.
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.
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