I've done some playing, and worked out how to turn on the external interrupts on the atmega128 I am using for R2.
Code:
#define F_CPU 1000000UL
#include < avr/io.h>#include < util/delay.h>#include < avr/interrupt.h>#include "r2.h"
int main(void) {
// Activate all the LEDs, set their pins to output
bit_set(LED_WHITE_L_DDR, LED_WHITE_L_BIT);
bit_set(LED_WHITE_R_DDR, LED_WHITE_R_BIT);
bit_set(LED_RED_L_DDR, LED_RED_L_BIT);
bit_set(LED_RED_R_DDR, LED_RED_R_BIT);
bit_set(LED_YELLOW_FL_DDR, LED_YELLOW_FL_BIT);
bit_set(LED_YELLOW_FR_DDR, LED_YELLOW_FR_BIT);
bit_set(LED_YELLOW_RL_DDR, LED_YELLOW_RL_BIT);
bit_set(LED_YELLOW_RR_DDR, LED_YELLOW_RR_BIT);
// enable internal pullup on PD0
bit_set(PORTD, BIT(0));
// enable external interrupts
EIMSK = BIT(INT0) | BIT(INT1);
// enable global interrupts
sei();
// turn on the white and red LEDs
bit_set(LED_WHITE_L_PORT, LED_WHITE_L_BIT);
bit_set(LED_WHITE_R_PORT, LED_WHITE_R_BIT);
bit_set(LED_RED_L_PORT, LED_RED_L_BIT);
bit_set(LED_RED_R_PORT, LED_RED_R_BIT);
// loop forever
while (1)
{
delayms(500);
}
return 0;
}
// delay for up to 65k milliseconds
void delayms(uint16_t millis)
{
// loop, delaying 1ms each iteration
while ( millis )
{
_delay_ms(1);
millis--;
}
}
// this catches the Interrupt sent from pin INT0
ISR(INT0_vect)
{
//Turn everything off
bit_clear(LED_WHITE_L_PORT, LED_WHITE_L_BIT);
bit_clear(LED_WHITE_R_PORT, LED_WHITE_R_BIT);
bit_clear(LED_RED_L_PORT, LED_RED_L_BIT);
bit_clear(LED_RED_R_PORT, LED_RED_R_BIT);
// loop forever, flashing our indicators.
while(1)
{
bit_flip(LED_YELLOW_FL_PORT, LED_YELLOW_FL_BIT);
bit_flip(LED_YELLOW_FR_PORT, LED_YELLOW_FR_BIT);
bit_flip(LED_YELLOW_RL_PORT, LED_YELLOW_RL_BIT);
bit_flip(LED_YELLOW_RR_PORT, LED_YELLOW_RR_BIT);
delayms(500);
}
}Changing Trigger Mode:
By default, the interrupt triggers when the pin is brought low. If we want to change this behavior, we need to poke at the External Interrupt Control Registers, EICRA (for INT0 - INT3) and EICRB (for INT4 - INT7).
Each interrupt pin has 2 bits in the EICR Registers, ISCxO and ISCx1. This Gives 4 possible options for triggering:
- 0 0: Default, Trigger when INTx is held low
- 0 1: Not Used
- 1 0: Trigger when INTx changes from 1 to 0
- 1 1: Trigger when INTx changes from 0 to 1
So, to turn on INT1, and set it to trigger on a rising edge, we,d use the following code:
// enable external interrupt
EIMSK = BIT(INT0);
// set the interrupt to trigger on a rising edge
EICRA |= BIT(ISC00) | BIT(ISC01);Video:
[youtube=http://www.youtube.com/watch?v=pSuCHiK-Xq4]