Why Does Disabling OCIE1A Cause Immediate ISR Re-trigger on Mega 2560?

Hii guys šŸ˜ŒšŸ˜Œ Iā€™m creating lighting variations on PORTA with a MEGA 2560 board.
I am using a zero-cross detection that triggers an interrupt, which calls the "void passage_a_0" function.
A command (continuous action on a button) modifies a lighting level setting from 1 to 25. This setting adjusts the phase delays corresponding to the lighting level.
I have an issue with the ISR interrupt. Below is the simplified code of the two related interrupts:
// Simplified zero-cross and ISR for continuous variation on bit 7 of PORTA
void passage_a_0 () {
TCNT1 = 0; // Initialize TNCT1
if (variation_demandee == 128) { // We are on bit 7
PORTA &= ~variation_demandee; // Turn off bit 7
OCR1A = retard_phase[niv_ecl[7]]; // Set the value of OCRIA
bitSet(TIMSK1, OCIE1A); // Set OCIE1A to 1 to allow the compare interrupt with OCIE1A
}
n0++; // Count the number of passes in this interrupt
}

ISR(TIMER1_COMPA_vect) {
PORTA |= 128; // Immediately act on the port with the concerned bit
bitClear(TIMSK1, OCIE1A); // Clear the OCIE1A bit to disable the compare interrupt with OCR1A
n++; // Count the number of passes in this interrupt
}
// Simplified zero-cross and ISR for continuous variation on bit 7 of PORTA
void passage_a_0 () {
TCNT1 = 0; // Initialize TNCT1
if (variation_demandee == 128) { // We are on bit 7
PORTA &= ~variation_demandee; // Turn off bit 7
OCR1A = retard_phase[niv_ecl[7]]; // Set the value of OCRIA
bitSet(TIMSK1, OCIE1A); // Set OCIE1A to 1 to allow the compare interrupt with OCIE1A
}
n0++; // Count the number of passes in this interrupt
}

ISR(TIMER1_COMPA_vect) {
PORTA |= 128; // Immediately act on the port with the concerned bit
bitClear(TIMSK1, OCIE1A); // Clear the OCIE1A bit to disable the compare interrupt with OCR1A
n++; // Count the number of passes in this interrupt
}
Problem:
With the bitClear(TIMSK1, OCIE1A); instruction in the ISR, which is necessary, the ISR is executed immediately as if OCR1A were set to 0.
However, if this instruction is removed, the variation works correctly, taking into account the OCR1A values for the phase delay. But depending on the value of OCR1A, the ISR is called several times before the next zero-cross.
Why is the ISR triggered immediately in the presence of 'bitClear'?
Is it a code error or a defective board?
2 Replies
wafa_ath
wafa_athā€¢2mo ago
Instead of clearing the flag inside the ISR, try disabling the interrupt before modifying the OCR1A value by adding bitClear(TIMSK1, OCIE1A); before setting OCR1A in the passage_a_0 function. This should prevent multiple interrupts from being triggered.
Enthernet Code
Enthernet Codeā€¢2mo ago
@Camila_99$$ The issue you're facing with the ISR in your code is likely due to a timing problem when clearing the OCIE1A bit inside the interrupt. When you clear this bit within the ISR, it may cause the interrupt to trigger prematurely, as if OCR1A were set to 0. However, if you don't clear the bit|, the ISR` works but gets triggered multiple times before the next zero-cross event.
Want results from more Discord servers?
Add your server