Forum: Mikrocontroller und Digitale Elektronik Interrupt startet nicht


von Pappnase (Gast)


Lesenswert?

Ich hab dieses Programm geschrieben und im Debugger getestet:
1
#ifndef F_CPU
2
#define F_CPU 1000000UL    // Prozessorgeschwindigkeit
3
#endif
4
5
// Prescaler (bei 16MHz F_CPU und 100Hz F_OC) = 256 (dann runder Wert!!!)
6
// Prescaler (bei  1Mhz F_CPU und 100Hz F-OC) =   8 (dann runder Wert!!!)
7
#define PRESCALER 8UL
8
#define F_OC 100UL // 100Hz (alle 10ms)
9
#define OCR1A_berechnet (F_CPU/(PRESCALER*F_OC))-1;
10
11
#include <avr/io.h>
12
#include <avr/interrupt.h>
13
#include <util/atomic.h>
14
15
volatile uint8_t zaehler = 10;
16
17
// eígenes Flag
18
volatile uint8_t eigen_flag = 0x00;
19
#define ZAEHLERFLAG 1
20
#define ZAEHLERFLAG_BIT (1<<ZAEHLERFLAG)
21
22
ISR (TIMER1_COMPA_vect)
23
{
24
  zaehler++;
25
  
26
  if (zaehler == 10) {
27
    eigen_flag |= ZAEHLERFLAG_BIT;
28
    zaehler = 0;
29
  }  
30
  
31
} // Ende ISR (TIMER1_COMPA_vect)
32
33
int main(void)
34
{
35
  // Timer1 konfigurieren
36
  TCCR1B |= 1; // (1<<CS11) | (1<<CS10);  //Prescaler 8: CS12=0 CS11=1 CS10=1   Prescaler 256: CS12=1 CS11=0 CS10=0
37
  TCCR1B &= ~(1<<CS12);
38
  OCR1A = OCR1A_berechnet;
39
  TIMSK1 = (1<<OCIE1A);  // Compare-Interrupt zulassen 
40
  
41
  // Interrupts einschalten
42
  sei ();
43
44
  while(1) {
45
    if (eigen_flag & ZAEHLERFLAG_BIT) {
46
      ATOMIC_BLOCK (ATOMIC_RESTORESTATE) {
47
        eigen_flag &= ~ZAEHLERFLAG_BIT;
48
        }
49
      
50
      // Tu was jede Minute        
51
    }        
52
   
53
    }
54
} // Ende main()

Im Debug-Modus hab ich den Prescaler auf 8 gelassen und bei ORC1A den 
Wert 3, damit ich nicht so oft "steppen" muss. Wenn der Timerwert TCNT1 
mit OCR1A übereinstimmt, wird in TIFR1 das OCF1A-Flag gesetzt, aber der 
Interrupt wird nicht gestartet und OCR1A geht nicht automatisch auf 
Null. So wie ich aber das GCC-Tutorial mit dem Timer verstanden habe, 
brauche ich es nicht zu "nullen" und der Interrupt TIMER1_COMPA müsste 
auch starten, tut er aber nicht :-(. Kann mir jmd. vielleicht nen Tipp 
geben, woram esliegen koennte?

von Reiner F. (reiner)


Lesenswert?

Hallo,

eine Antwort auf die Schnelle.
Könnte es sein, dass Du vergessen hast, den CTC Modus einzuschalten, 
d.h. die entsprechenden WGM Bits zu setzen.

Gruß
Reiner

von Pappnase (Gast)


Lesenswert?

Hmm, nun hab ich in TCCR1B WGM12 gesetzt, jetzt nullt der Zähler bei 
Iebereinstimmung, der Interrupt wird aber immer noch nicht aufgerufen 
:-(

Das Datenblatt kennt zu diesen Typen folgende Einstellungen, für 
Variante 04 habe ich mich entschieden, weis aber nicht, obs die richtige 
ist.


No Wgm3 Wgm2 Wgm1 Wgm0
12 1    1    0    0        CTC ICR1  Immediate MAX
04 0    1    0    0        CTC OCR1A Immediate MAX

Wie gesagt, der Interrupt startet einfach nicht. Oder starten Interrupts 
im Debugger generell nicht, wenn die aktiv sind und ausgelöst werden??

von Django (Gast)


Lesenswert?

Welcher µC?

von Pappnase (Gast)


Lesenswert?

Django schrieb:
> Welcher µC?

Atmega88, AVRStudio 6

von Spess53 (Gast)


Lesenswert?

Hi

>AVRStudio 6

Schon mal nach 'Known Issues' gesucht. Ich benutze AVR Studio 4.19. Dort 
gibt es auch einige PWM-Modi, die im Simulator nicht funktionieren. Aber 
CTC läuft.

MfG Spess

von Pappnase (Gast)


Lesenswert?

Spess53 schrieb:
> Schon mal nach 'Known Issues' gesucht

nee, weis nicht, wonach ich genau suchen soll :-(

Oder kann es sein, dass der Debugger das nicht simulieren kann, dass es 
theoretisch zwar richtig ist, der es aber einfach nicht kann?

von Stefan E. (sternst)


Lesenswert?

Pappnase schrieb:
> AVRStudio 6

Und im Einzelschritt gesteppt, richtig?
Das sei() funktioniert im Einzelschritt nicht. Setze einen Breakpoint 
und benutze dann Run. Und kontrolliere, ob das I-Flag in SREG auch 
tatsächlich gesetzt ist.

von Falk B. (falk)


Lesenswert?

@  Pappnase (Gast)

>Oder kann es sein, dass der Debugger das nicht simulieren kann, dass es
>theoretisch zwar richtig ist, der es aber einfach nicht kann?

Solche Fehler gab es mal, im aktuellen AVR-Studio sind die aber AFAIK 
nicht bekannt.

von Pappnase (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Und kontrolliere, ob das I-Flag in SREG auch
> tatsächlich gesetzt ist.
Hmm, jetzt hab ich in der ISR den Break-Point gesetzt und dann nicht im 
"Step"-Modus gedebugg und ich beobachte auch immer meine Zählvariable 
"zaehler", jetzt funktioniert es :-)

von Pappnase (Gast)


Lesenswert?

Aber ich habe noch nicht kapiert, wo der Unterschied zwischen diesen 
beiden Modi liegt:


No Wgm3 Wgm2 Wgm1 Wgm0
12 1    1    0    0        CTC ICR1  Immediate MAX
04 0    1    0    0        CTC OCR1A Immediate MAX

Ich hab jetzt den Modus 04 genommen, aber es gibt auch noch den Modus 
12, wo auch CTC drinnen steht.

von Spess53 (Gast)


Lesenswert?

Hi

>Ich hab jetzt den Modus 04 genommen, aber es gibt auch noch den Modus
>12, wo auch CTC drinnen steht.

Der Unterschied ist das Top-Register. Das bestimmt, wie weit der Timer 
läuft bis er wieder von Null anfängt. Im Mode 4 ist das OCR1A und im 
Mode 12 ICR1. Wenn du mit CTC ein Signal an einem Pin erzeugen willst, 
dann geht das nur im Mode 4.

MfG Spess

von Reiner F. (reiner)


Lesenswert?

Hallo,

> Der Unterschied ist das Top-Register. Das bestimmt, wie weit der Timer
> läuft bis er wieder von Null anfängt. Im Mode 4 ist das OCR1A und im
> Mode 12 ICR1. Wenn du mit CTC ein Signal an einem Pin erzeugen willst,
> dann geht das nur im Mode 4.

Die Aussage im letzten Satz sehe ich anders. Genau so wie im Mode 4 kann 
man auch im Mode 12 PWM Signale an einem Pin erzeugen. Im Mode 12 hat 
man, im Gegensatz zu Mode 4, zwei Register um an zwei Pins PWM Signale 
mit unterschiedlichem Tastverhältnis zu erzeugen. Mit ICR1 kann man dann 
die Frequenz der PWM genau einstellen - über den Prescaler funktioniert 
das nämlich nur grob. Mit OCR1A und OCR1B parametriert man dann die 
Tastverhältnisse der PWMs.
Ein weiterer Unterschied zwischen Mode 4 und Mode 12 liegt im Timing 
beim Ändern der Register OCR1A bzw. OCR1B.

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
Noch kein Account? Hier anmelden.