Reputation: 36
The code can be found in Checking INTF0 Without ISR
The code works as expected when the main() function is present but it does not when main() function is left out of the code. I do not want to use the ISR handling as many had already suggested. Does someone can point me to what I am not seeing? Thanks in advance.
#include <avr/io.h>
// This is just an example.
// Pushbutton without bouncing connected between ground and INT0 pin - D2.
// LED connected betwwen ground(cathode) and D8-B0 (anode).
// LED state toggles each time pushbutton is pressed.
// Not using IRS in order to avoid its overhead.
// Polling INTF0 flag state.
// Code works as expected when main() function is present.
// Otherwise it fails.
// Cannot use main() function in the final code because it avoids the
// Arduino initialization needed by other project libraries
#define LED_PIN PB0 // LED pin
#define NO_MAIN // comment to use main()
#ifndef NO_MAIN
int main() {
setup();
while (true) {
loop();
}
return 0;
}
#endif
void setup() {
// Set LED_PIN as output
DDRB |= (1 << LED_PIN);
// Enable pull-up resistor on INT0 (PD2)
PORTD |= (1 << PD2);
// Configure INT0 to trigger on falling edge
EICRA |= (1 << ISC01); // Falling edge trigger
EICRA &= ~(1 << ISC00);
// Enable INT0 interrupt (this enables the flag, not the ISR)
EIMSK |= (1 << INT0);
}
void loop() {
// Poll INTF0 flag in the main loop
if (EIFR & (1 << INTF0)) {
// Clear the INTF0 flag by writing 1 to it
EIFR |= (1 << INTF0);
// Toggle LED
PORTB ^= (1 << LED_PIN);
}
}
Upvotes: 0
Views: 38
Reputation: 36
After some research, I concluded that the Arduino framework somehow prevents polling the External Interrupt flag (INTF0
). The same hardware and code worked flawlessly when the main
function was explicitly defined.
This issue was solved by placing a cli() function call at the last line of setup() function.
Upvotes: 0
Reputation: 4003
Some notes on the code:
Depending on the event source, a proper debouncing might be required, e.g. when using a switch or button or similar input devices. When a switch is bouncing, you may get several events in fast succession, and when their number is even, the LED will appear as if it dod not change.
In order to reset a flag bit, the code is like EIFR = 1 << INTF0
in almost all cases. EIFR |= (1 << INTF0)
will inadvertently reset all flags that are set in EIFR
.
On modern AVRs, toggling a port register is achieved by PINB = 1 << LED_PIN
. Advantage is that it is faster, smaller code, and most importantly it is atomic, which PORTB ^= (1 << LED_PIN)
is not.
Upvotes: 0