/*
Filename: Four button interrupt
Author: Reed
Date: 2023/04/12
Description: This program receives button inputs via interrupts and outputs which pin the interrupt arrived on.
*/
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/iomxx0_1.h>
volatile bool pinChanged = false;
void init_interrupt(void);
int main(){
unsigned char val;
Serial.begin(9600);
DDRB = 0xF0; //configure PORTB 0-3 as input
PORTB = 0x0F; //configure pull-up resistors
DDRA = 0xFF; //configure PORTA as output
init_interrupt();
while (true) {
if(pinChanged){
//if button 1(Red) is pressed, PINB = 1110. We XOR with 1111 to obtain the value.
//eg. 1011 XOR 1111 = 0100.
val = PINB ^ 0x0F;
switch(val){
case 1:
Serial.println("Button 1: Red");
_delay_ms(300);
break;
case 2:
Serial.println("Button 2: Black");
_delay_ms(300);
break;
case 4:
Serial.println("Button 3: Green");
_delay_ms(300);
break;
case 8:
Serial.println("Button 4: Yellow");
_delay_ms(300);
break;
}
pinChanged = false;
}
}
return 0;
}
void init_interrupt(void){
cli(); //clear global interrupt
PCICR |= (1 << PCIE0); //enable interrupt on PCINT 0-7. Interrupts excecuted from PCI0 vector.
PCMSK0 |= 0x0F; //Enable interrupts on PCINT 0-3
PCIFR |= (1 << PCIF0); //Clear interrupt flag
sei(); //set global interrupt
}
ISR(PCINT0_vect){
pinChanged = true;
PCIFR |= (1 << PCIF0); //Clear interrupt flag
}