mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega8 und Interrupts


Autor: Jochen Kunz (jokunz)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir den Code jetzt nicht im Detail angesehen, aber ein CTRL-F 
fördert kein "volatile" zu Tage. Das wird das Problem sein.
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>cli();      // Interrupts nicht zulassen

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

    takt--;

  if (takt == 0) {
    takt = TIMERVALUE;
      ucSend = 1;

Wie lange dauert der ganze Spaß hier?   
    UARTPutChar(0x01);
    // UARTPutChar(readAnalogValues(0));  // vor Rechen
    UARTPutChar(readAnalogValues(1));  // hinter Rechen
//    UARTPutChar(ucAnalogValues[1]);
    UARTPutChar(PIND & 0xfc);
    // UARTPutChar(readAnalogValues(2));  // Einsteller
    UARTPutChar(0xff);

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

}


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.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"takt" sollte wirklich noch volatile deklariert werden!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum? "takt" wird ausschließlich im Interruptcode verwendet.
"ucAnalogValues" muss aber volatile sein.

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)):
for (i=0;i<4;i++) {
    ADCSRA |= (1<<ADSC);
  while (ADCSRA&(1<<ADSC)) {}

Aktives Warten auf ADC-Ergebnisse innerhalb einer Timer-ISR finde ich...
...unkonventionell.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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...

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, aber ich denke nicht, dass das hier zwingend nötig ist.
Wie kann denn ein einzelnes unsigned char "halb geschrieben" sein?

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
unsigned char
 zurückgibt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.