/* Filename: intEx1
Author: Renier Del Rosario
Date: 22/4/2024
Description: interrupt detector for push button
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
// Function prototype for initializing external interrupt PCINT0
void pcint0_init(void);
#define DEBOUNCE_DELAY_MS 50
volatile uint8_t lastState = 0xFF; // Initialize to all high (not pressed)
volatile uint8_t currentState = 0xFF; // Current state of PB0 to PB7
#define mask 0b11110000
volatile unsigned char SwitchState = 0x00;
// Global variables
volatile unsigned char PinChange = 0; // Initialized to False
volatile unsigned char counter = 0; // Global variable for debugging
// Main function
int main(void) {
Serial.begin(9600);
// User initializations
DDRB = 0x00; // Configure only PB0 (PCINT0) as input
PORTB = 0x0F; // Activate pull-up resistor on PB0~PB3
DDRA = 0xFF; // All Port A pins configured as output
// Initialize external interrupt PCINT0
pcint0_init();
PORTA = mask;
// Infinite loop
while (1) {
// Check if pin change detected
if (PinChange) {
// Toggle PA7 (LED or output)
PORTA = mask ^ SwitchState;
_delay_ms(1000);
PORTA = 0xF0;
// Reset pin change detection
PinChange = 0;
}
}
}
// Function definition for initializing external interrupt PCINT0
void pcint0_init(void) {
cli(); // Disable interrupts
PCICR |= (1 << PCIE0); // Enable PCINT0 interrupt
PCMSK0 |= (1 << PCINT0) | (1 << PCINT1) | (1 << PCINT2) | (1 << PCINT3); // Enable interrupt on PB0
PCIFR |= (1 << PCIF0); // Clear interrupt flag for PCINT0
sei(); // Enable interrupts
}
ISR(PCINT0_vect) {
// Read the state of PB0 ~ PB3
uint8_t pb0State = PINB & (1 << PB0);
uint8_t pb1State = PINB & (1 << PB1);
uint8_t pb2State = PINB & (1 << PB2);
uint8_t pb3State = PINB & (1 << PB3);
currentState = PINB;
// Check for a valid state change after debounce delay
if (currentState != lastState) {
_delay_ms(DEBOUNCE_DELAY_MS); // Debounce delay
// Read the state again after debounce delay
currentState = PINB;
// Check if the state remains the same after debounce
if (currentState != lastState) {
// Update lastState to reflect the valid state change
lastState = currentState;
// Check if PB0 is pressed
if (pb0State == 0) {
Serial.println(PINB);
// PB0 is pressed
Serial.println("Button PB0 is pressed");
SwitchState = 0b11110001;
// Add your code here for handling PB0 press
}
// Check if PB1 is pressed
if (pb1State == 0) {
Serial.println(PINB);
// PB1 is pressed
Serial.println("Button PB1 is pressed");
// Add your code here for handling PB1 press
SwitchState = 0b11110010;
}
// Check if PB2 is pressed
if (pb2State == 0) {
Serial.println(PINB);
// PB2 is pressed
Serial.println("Button PB2 is pressed");
// Add your code here for handling PB2 press
SwitchState = 0b11110100;
}
// Check if PB3 is pressed
if (pb3State == 0) {
Serial.println(PINB);
// PB3 is pressed
Serial.println("Button PB3 is pressed");
// Add your code here for handling PB3 press
SwitchState = 0b11111000;
}
}}
// Clear the pin change flag
PinChange = 1;
PCIFR |= (1 << PCIF0);
}