Hallo zusammen, nachdem jetzt der ADC tadellos funktioniert, möchte ich nun die "einfache" ADC-Wandlung in ein Interruptgesteuertes Ereignis umbauen. Funktioniert nur noch nicht so ganz. Es soll ein Lauflicht aus 4 LEDs werden, je nachdem ob das Poti auf 0 V oder auf 5 V ist, soll die Laufgeschwindigkeit schneller oder langsamer sein. Irgendwas stimmt aber mit meinem ISR-Abschnitt noch nicht. Oder liegt der Fehler woanders? Kann mal bitte jemand kurz drübersehen? Wenn ich es richtig deute, bleibt die Variable "result" ständig auf Null. Christian
Das geht nicht
1 | PORTD |= (1<<PD0); _delay_ms(result); PORTD &= ~(1<<PD0); |
_delay_ms kann man nicht mit Variablen benutzen. D.h. man kann schon. Nur stimmen die Zeiten nicht
1 | void my_delay_ms( uint16_t value ) |
2 | {
|
3 | while( value ) { |
4 | _delay_ms( 1 ); |
5 | value--; |
6 | }
|
7 | }
|
8 | |
9 | ....
|
10 | |
11 | PORTD |= (1<<PD0); my_delay_ms(result); PORTD &= ~(1<<PD0); |
1 | ISR(ADC_vect) |
2 | {
|
3 | char sreg=SREG; // Interrupt Status auslesen |
4 | |
5 | cli(); // Interrupts aus |
6 | |
7 | // Ergebnis der Konvertierung auslesen
|
8 | result = ADCW; |
9 | |
10 | SREG=sreg; // Interrupt Status zurückschreiben |
11 | }
|
Lass das SREG in Ruhe. Das ist ein Register, das geht dich nichts an! cli brauchst du nicht innerhalb einer ISR. In einer iSR sind Interrupts automatisch aus.
>_delay_ms(result);
Blödsinn Nummer 1:
_delay_ms(); arbeitet nur mit Konstanten Werten.
Für variable delays bau dir eine Routine ala:
void MyDelayMs(uint16_t delay)
{
while(delay--) _delay_ms(1);
}
Blödsinn Nummer 2:
cli(); in einem Interrupt macht keinen Sinn
ISR(ADC_vect)
{
// Ergebnis der Konvertierung auslesen
result = ADCW;
}
Ach wie schön klein ist diese Interruptroutine jetzt;)
Und funktioniert ohne das ganze Geraffel das von einem
unglaublichen Halbwissen zu stammen scheint.
holger, spar dir diese saublöde Anmache, bitte. Wenn du dich über "Geraffel" und "Halbwissen" beschwerst, dann macht vielleicht mal dieses Forum dicht, schließlich ist es dafür da, Fragen von Personen zu beantworten die sich nicht so gut auskennen (Ich). Da kann ich sonst auch genausogut meine Glaskugel zu Hause fragen, die gibt mir bestimmt keine so dummen Kommentare als Antwort. Falls jemand noch konstruktive Vorschläge hat, die mir wirklich weiterhelfen, ich bin ganz Ohr. Danke. Die besagten Vorschläge von vorhin brachten übrigens keine Besserung im Programmablauf. Trotzdem Danke. Christian
Hi Vielleicht bin ich blind, aber ich sehe keine Zeile, in der du den ADC startest. MfG Spess
Hier:
1 | // ADC aktivieren und Teilungsfaktor auf 8 stellen
|
2 | ADCSRA |= (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); |
und hier:
1 | // ADC Dauerfeuer (Endlosschleifenbetrieb) einschalten
|
2 | ADCSRA |= (1<<ADFR); |
:) Oder? Geht doch so? Christian
Hi
>Oder? Geht doch so?
Nein. Der Free Running Mode muss durch setzen von ADSC in ADCSRA
gestartet werden.
MfG Spess
Jawoll, perfekt, genau das wars. Danke Spess. Hab die Zeile noch hinzugefügt, jetzt gehts!
1 | // Free Running Mode aktivieren durch erste Messung
|
2 | ADCSRA |= (1<<ADSC); |
@christian_w
>holger, spar dir diese saublöde Anmache, bitte.
Mach ich. Ich merk mir auch deinen Namen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.