Forum: Compiler & IDEs Timer0 Overflow Interrupt wird nicht ausgeführt


von Johannes (Gast)


Lesenswert?

Hallo,
ich arbeite im Moment an einem Sägezahnwellen-Tongenerator mit Atmega8 
als Kernstück. Nun möchte ich einen Frequenzwechsel per Schalter 
realisieren.
Wenn der Schalter gedrückt wird, wird der INT0 Interrupt über 
Falling-Edge ausgelöst, das funktioniert auch soweit.

Die Entprellung funktioniert bei mir über Timer0, bei dem ein Overflow 
auslöst, dass eine Variable (buttonChangeAllowed) auf 1 gesetzt wird, 
diese wird bei der ersten fallenden Flanke auf INT0 auf 0 gesetzt.

Der Timer0 Overflow Interrupt löst aber nie aus, d.h. im AVR Simulator 
wird zwar TOV0 im TIFR Register gesetzt, aber der Breakpoint im 
Interrupt nicht erreicht, obwohl Global Interrupts enabled sind (über 
sei() ) und TOIE0 im TIMSK Register gesetzt ist.
In Hardware macht sich dies bemerkbar dadurch, dass nur einmal der Ton 
gewechselt wird, danach gibt es keine Reaktion mehr auf die Betätigung 
des Schalters (eigentlich sollte jeder Druck des Schalters den jeweils 
nächsten Ton auf einer C-Dur-Tonleiter abspielen).




TL;DR: ISR(TIMER0_OVF_vect) löst nie aus, halp! ;)




Vielen Dank schonmal für eure Hilfe!

Hier noch der Code:
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <avr/wdt.h>
4
#include <avr/interrupt.h>
5
#include <math.h>
6
7
#define F_CPU 1000000
8
#define SAMPLING_TIME 32
9
#define MAXVAL_16 65536
10
11
volatile uint16_t voutFull=0;
12
volatile uint16_t deltaM;
13
volatile uint8_t buttonChangeAllowed=1; //is 1 if at least 256 timer0 updates have passed since last button interrupt
14
static uint16_t frequencies[8]= {131,147,165,175,196,220,247,262};
15
volatile uint8_t currFreq=0;
16
volatile float freq=131.0f;
17
18
void recalculateFreq() {
19
  deltaM=(uint16_t)(((SAMPLING_TIME*freq)/F_CPU)*MAXVAL_16);
20
}
21
22
ISR(TIMER0_OVF_vect) {
23
  buttonChangeAllowed=1;
24
  TCCR0=0; //stop the timer
25
  TCNT0=0; //reset the timer
26
}
27
28
29
ISR(TIMER1_COMPA_vect) {
30
  voutFull+=deltaM;
31
  
32
  uint8_t vout=voutFull>>8;
33
  
34
  PORTD=(vout & 0b11110000) + (PORTD & 0b00001111);
35
  PORTC=(vout & 0b00001111) + (PORTB & 0b11110000);
36
}
37
38
39
ISR(INT0_vect) {
40
  //if the button gets pressed:
41
  
42
  if (buttonChangeAllowed) { //if enough time has passed since last change
43
    TCCR0=(1<<CS02)|(1<<CS00); //set timer 0 to a 1024 prescaler, thus reenabling it.
44
    
45
    ++currFreq;
46
    if (currFreq>7) currFreq=0; //reset after the maximum tuneheight
47
    freq=(float)(frequencies[currFreq]);
48
    recalculateFreq();
49
  }
50
}
51
52
void setup() {
53
    DDRD=0b11110000;
54
  DDRC=0b00001111;
55
  DDRD&=~(1<<2); //set switch pin to 'in'
56
  PORTD=(1<<2); //Enable pull-up resistor
57
  
58
  TCCR0  = 0; //Disable timer 0 for now.
59
  TCCR1B=(1<<CS10); // prescaler for timer 1 is set to 1
60
  TCCR1B|=(1<<WGM12); //Timer Compare Match mode on
61
  
62
  TCNT1=0x0; //Initialise timer 1 with 0.
63
  TCNT0=0x0; //Initialise timer 0 with 0.
64
  
65
  OCR1A=SAMPLING_TIME-1; //Timer Compare Value set to x Ticks.
66
67
  TIMSK=(1<<TOIE0)|(1<<OCIE1A); //Enable timer0 overflow interrupt and timer1A CTC interrupt
68
  MCUCR=(1<<ISC01);     //Set interrupt on falling edge on INT0, that is PIND2
69
  
70
  GICR=(1<<INT0);         //Enable interrupt for INT0  
71
}
72
73
int main(void)
74
{
75
  wdt_disable();
76
  
77
  cli();
78
  
79
  setup();
80
  
81
  recalculateFreq();
82
  
83
  sei(); //Enable Interrupts.
84
  
85
    while (1) {
86
          
87
    }    
88
}

von Walter S. (avatar)


Lesenswert?

Johannes schrieb:
> TCCR0  = 0; //Disable timer 0 for now.

und wo wird er enabled?

von Johannes (Gast)


Lesenswert?

Walter S. schrieb:
> Johannes schrieb:
>> TCCR0  = 0; //Disable timer 0 for now.
>
> und wo wird er enabled?


Hier, wenn der Schalter das erste Mal gedrückt wird:


Johannes schrieb:
> ISR(INT0_vect) {
>   //if the button gets pressed:
>
>   if (buttonChangeAllowed) { //if enough time has passed since last change
>     TCCR0=(1<<CS02)|(1<<CS00); //set timer 0 to a 1024 prescaler, thus 
reenabling it.
>
>     ++currFreq;
>     if (currFreq>7) currFreq=0; //reset after the maximum tuneheight
>     freq=(float)(frequencies[currFreq]);
>     recalculateFreq();
>   }
> }


Der Timer läuft danach auch, sagt AVR Simulator... Die TCNT0 Bits ändern 
sich regelmäßig und nach einer Weile wird auch das TOV0 Bit in TIFR 
gesetzt.

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.