Atmega8 und Interrupts

OP #838375
Hallo,

Mit meinem kleinen Beispielcode im Anhang stehe ich vor einem Rätsel.
Ich möchte u.A. drei Analogwerte einlesen und einen davon über die RS232 
weitersenden, dies zyklisch per Timerinterrupt gesteuert, also ständig 
einlesen, rumrechnen und ca alle Sekunde einmal den Analogwert senden.

Lese ich in der Interruptroutine den AD-Wert zum Senden ein, habe ich 
kein Problem.
Aber sobal ich in der main-loop die Werte einlese und im 
Interrupthandler versenden möchte, geht es nicht.
Es sieht fuer mich so aus, als ob der main "nicht abgearbeitet" wird, 
irgendwie ein irq-vektor/reset  das Programm wieder neu startet.
Ich sehe den Denkfehler aber nicht.

liebe Grüße
jochen
Angehängte Dateien:
Gast #838398
>cli();      // Interrupts nicht zulassen

Sinnfrei innerhalb einer ISR, da dort sowieso keine anderen Interrupts 
zugelassen werden.
1
SIGNAL (SIG_OVERFLOW0)
2
{
3
  cli();      // Interrupts nicht zulassen << sinnfrei
4

5
    takt--;
6

7
  if (takt == 0) {
8
    takt = TIMERVALUE;
9
      ucSend = 1;
10

11
Wie lange dauert der ganze Spaß hier?   
12
    UARTPutChar(0x01);
13
    // UARTPutChar(readAnalogValues(0));  // vor Rechen
14
    UARTPutChar(readAnalogValues(1));  // hinter Rechen
15
//    UARTPutChar(ucAnalogValues[1]);
16
    UARTPutChar(PIND & 0xfc);
17
    // UARTPutChar(readAnalogValues(2));  // Einsteller
18
    UARTPutChar(0xff);
19

20
    }
21
  sei();        << wenn das Sperren schon sinnfrei ist, braucht man sich um das Freigeben auch nicht mehr kümmern...
22

23
}


Ich würde sagen, dass deine ISR viel zu langsam ist.

Weiterhin sollte man den ADC nur ein Mal initialisieren und den ersten 
Messwert verwerfen. Die darauffolgenden Messwerte sind dann auch erste 
richtig gültig.
Gast #838421
In der main-loop belädst Du das Array:
>ucAnalogValues[i]= readAnalogValues(i);
Der Inhalt des Arrays wird aber nirgendwo verwendet...

Dafür wartet die ISR
>SIGNAL (SIG_OVERFLOW0)
aktiv auf ADC-Ergebnisse (4x in readAnalogValues(unsigned char ucMux)):
1
for (i=0;i<4;i++) {
2
    ADCSRA |= (1<<ADSC);
3
  while (ADCSRA&(1<<ADSC)) {}

Aktives Warten auf ADC-Ergebnisse innerhalb einer Timer-ISR finde ich...
...unkonventionell.
#838424
Maddin wrote:
> In der main-loop belädst Du das Array:
>>ucAnalogValues[i]= readAnalogValues(i);
> Der Inhalt des Arrays wird aber nirgendwo verwendet...

Doch:
//    UARTPutChar(ucAnalogValues[1]);
Die auskommentierte Zeile gehört zu dem "funktioniert nicht"-Fall.
Gast #838443
>Die auskommentierte Zeile gehört zu dem "funktioniert nicht"-Fall.
OK, sorry...
Noch eine Bemerkung zum Datenaustausch:
Wenn das Array auf "Tasklevel" (main loop) gegeschrieben und auf 
Interrupt-Level gelesen wird, muß der Schreibzugriff in "main" geschützt 
werden (d.h. unter Interruptsperre), damit im Interrupt keine halb 
geschriebenen Daten an die UART gesendet werden...
Gast #838458
Ahh, ich glaube, es ist Zeit fürs Bett.
Ich bin von 10bit-Werten ausgegangen, obwohl die Fkt. ja nur 8bit vom 
ADC verwendet und
1
unsigned char
 zurückgibt.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 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.