Atmega8 und Interrupts

OP #838375
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
Angehängte Dateien:
Gast #838398
Lesenswert?
• ▲
▼
>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
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)):
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.
Gast #838443
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...

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