Hi, I just spend a little time wondering why my timer interrupt fires immediately until I cleared the interrupt flag manually before enabling. Same thing with an external interrupt, when I first use it it's ok. Before enabling the second time I have to clear the flag. Maybe this is a standard procedure but I never needed to do that before, is this normal or what could be the reason ?
Thank you
Mat
attiny24A: manually clear Interrupt Flags required ?
Hi, I just spend a little time wondering why my timer interrupt fires immediately until I cleared the interrupt flag manually before enabling.
Clearing an interrupt flag works only, if you follow the data sheet.
E.g. on the ATTiny13:
TIFR0 = 1<<TOV0;
Peter
what is your point ? I know how to clear the flag, the question is why do I have to do it. I thought it should be clear when enabling the interrupt and be cleared when the ISR is executed. Or am I wrong there ?
With the ext int is it set to low level? If so then the IF bit will be set even after the ISR is entered so that on the RETI it will return to main(), execute one opcode then re-enter the ISR
nice thought, but nope, it is configured on falling edge.
the question is why do I have to do it
...and be cleared when the ISR is executed. Or am I wrong there ?
But you're right here's the code. It starts off with a blinking (standby). When a (low active) button is pressed (falling edge) the green led and an SSR is switched on. Then the next while waits for the button to be pressed and held. If it is held long enough (5s @8MHz) the green led and the SSR are switched off and the program returns to the first blinking while. If the button is released earlier then the timer interrupt is disabled again and everything stays on. Without the clearing of the bits in "GIFR" and "TIFR" it doesn't work. The defines aren't listed here.
volatile char CMD_STATE; int main(void){ //INIT SSR_PORT_DDR |= SSR_bm; SSR_OFF(); /////////////////////////////////////////////////// MCUCR &= ~(1<<ISC00); MCUCR |= (1<<ISC01); // falling edge gens. int. GIMSK |= (1<<INT0); // enable INT0 Interrupt /////////////////////////////////////////////////// LED_PORT_DDR = 0; LED_PORT_DDR |= (GREEN_LED_bm | RED_LED_bm); GREEN_LED_ON(); RED_LED_ON(); _delay_ms(250); GREEN_LED_OFF(); RED_LED_OFF(); /////////////////////////////////////////////////// TCCR1B |= ((1<<WGM12)|(1<<CS12)|(1<<CS10)); // CTC, clk/1024 OCR1A = 39062; TCNT1 = 0; /////////////////////////////////////////////////// CMD_STATE = 0; sei(); while(1){ while(1){ GREEN_LED_ON(); _delay_ms(150); GREEN_LED_OFF(); _delay_ms(1250); if(CMD_STATE) break; } SSR_ON(); //SWITCH ON SSR GREEN_LED_ON(); while(!(PINB&0x04)); // wait till button not pressed while(1){ if(CMD_STATE == 0){ SSR_OFF(); //SWITCH OFF SSR GREEN_LED_OFF(); while(!(PINB&0x04)); // wait till button not pressed GIFR |= (1<<INTF0); GIMSK |= (1<<INT0); // re-enable INT0 Interrupt break; } if(!(PINB&0x04)){ TCNT1=0; TIFR1 |= (1<<OCF1A); // clear int flag TIMSK1 |= (1<<OCIE1A); while(!(PINB&0x04)){ if(CMD_STATE == 0){ break; } } TIMSK1 &= ~(1<<OCIE1A); } } } return 0; } /***************************************************************/ //ISR ISR(EXT_INT0_vect){ GIMSK &= ~(1<<INT0); //disable interrupt CMD_STATE = 1; return; } ISR(TIM1_COMPA_vect){ TIMSK1 &= ~(1<<OCIE1A); // disable timer int CMD_STATE = 0; return; }
Yes, it will be cleared when the ISR is executed, but that in no way prevents another triggering event from happening that sets the flag again (this includes the time during the ISR).
I thought it should be clear when enabling the interrupt
ok, so a bouncing button could be the reason for the external thing maybe ? What about the timer, is the flag set when the counter reaches the TOP value although the interrupt isn't enabled ?
is the flag set when the counter reaches the TOP value although the interrupt isn't enabled
Yes. That's what the datasheet says the flags do.
ok, I didn't understand it like that, but you're right, no word about the interrupt having to be enabled for the flag-set. So I could start the timer clock when enabling the interrupt, but now it's working this way. Thanks to all for clearing this up.
no word about the interrupt having to be enabled for the flag-set.
??? There >>IS<< "word" about what Cliff said, and what your quoted question asked.
• Bit 0 – TOV1: Timer/Counter1, Overflow Flag
The setting of this flag is dependent of the WGM13:0 bits setting. In Normal and CTC modes, the TOV1 Flag is set when the timer overflows. Refer to Table 15-4 on page 137 for the TOV1 Flag behavior when using another WGM13:0 bit setting.TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt Vector is executed. Alternatively, TOV1 can be cleared by writing a logic one to its bit location.
What part of the phrase in bold is ambiguous? You will find similar wording for [nearly? cannot think of an exception] AVR interrupt flags of that type.
Lee
In fact I was going to quote exactly the text that Lee quoted but amongst the first three PDFs I looked at (which all had the same text) I couldn't find one that wasn't "secure" and that would let me copy/paste. :-(
hey, didn't you get I'm agreeing :-) I said
you're right
yes the flag setting is independant of the interrupt enable bit. If it wasn't we could never poll for a condition. Therefore it is always a wise idea to clear an interrupt flag just before enabling the interrupt source. This will prevent accidental firings of the interrupt immediately after the interrupt is enabled.
ok, then we have settled that. :) Thank you ! Strange and pure luck obviously that I never needed to do that before. Maybe because I never disabled-enabled ints before, but just switched them on...
Just off topic, if I click on "message icons" or "smiles" I get a little window saying "hacking attempt 1" but no icons or something. What is that supposed to mean ?
What is that supposed to mean ?
It means, just as it has for more than a year, that Atmel don't have the staff costs to fix the faults in this PHPBB system ;-)
If you want smiles then use [Preview] and in that view they are listed at the left where they can be clicked to insert into the text.
Hahaha :lol: ok, thanks for the hint, I don't use them very often here and didn't even notice it's for a year