Interrupt startet nicht

Gast #2900827
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?
Gast #2900910
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??
Gast #2901067
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
#2901751
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.

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