/*
PB2 (INT0) used for external interrupt.
PB0, PB1, PB2, PB3, PB4, PB5 pin change interrupt.
*/
/*
SREG - AVR Status Register
The AVR Status Register – SREG – is defined as:
Bit 7 6 5 4 3 2 1 0
0x3F I T H S V N Z C SREG
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Init Value 0 0 0 0 0 0 0 0
Bit 7 – I: Is the Global Interrupt Enable which enables the interrupt usage for the Microcontroller.
- - - - - - - - - - - - - - - - - - -
GIMSK – General Interrupt Mask Register
Bit 7 6 5 4 3 2 1 0
0x3B – INT0 PCIE – – – – – GIMSK
Read/Write R R/W R/W R R R R R
Init Value 0 0 0 0 0 0 0 0
- Setting the INT0 bit to 1 enables the external interrupt to PB2 ( INT0 ) pin.
- Possible to trigger interrupt even if the PB2 is configured as output.
This allows software to trigger external interrupt rather than triggering by an external change.
- PCIE bit enables the pin change interrupt. Setting the pin enables this interrupt.
in addition need to configure the pins to attach to this interrupt.
- - - - - - - - - - - - - - - - - - -
MCUCR – MCU Control Register
The External Interrupt Control Register A contains control bits for interrupt sense control.
Bit 7 6 5 4 3 2 1 0
0x35 BODS PUD SE SM1 SM0 BODSE ISC01 ISC00 MCUCR
Read/Write R R/W R/W R/W R/W R R/W R/W
Init Value 0 0 0 0 0 0 0 0
- ISC01 and ISC00 bits in MCUCR register is used to configure the point at which an external interrupt should be triggered.
Table 9-2. Interrupt 0 Sense Control
ISC01 ISC00 Description
0 0 The low level of INT0 generates an interrupt request.
0 1 Any logical change on INT0 generates an interrupt request.
1 0 The falling edge of INT0 generates an interrupt request.
1 1 The rising edge of INT0 generates an interrupt request.
- - - - - - - - - - - - - - - - - - -
PCMSK – Pin Change Mask Register
Bit 7 6 5 4 3 2 1 0
0x15 – – PCINT5 PCINT4 PCINT3 PCINT2 PCINT1 PCINT0 PCMSK
Read/Write R R R/W R/W R/W R/W R/W R/W
Init Value 0 0 0 0 0 0 0 0
The bits PCINT0 to PCINT5 are used to attache the pin change interrupt to ATtiny85 pins PB0 to PB5.
- - - - - - - - - - - - - - - - - - -
GIFR – General Interrupt Flag Register
Bit 7 6 5 4 3 2 1 0
0x3A – INTF0 PCIF – – – – – GIFR
Read/Write R R/W R/W R R R R R
Init Value 0 0 0 0 0 0 0 0
This register contains the interrupt flag register for both external and pin change interrupt.
This flag bits will be set by hardware when the interrupt occurs.
This bit will be cleared when the controller executes the corresponding interrupt service routine ( ISR ).
*/
#include <TinyDebug.h>
#include <avr/io.h>
#include <avr/interrupt.h> // required for ISR(INT0_vect) macro
#include <avr/delay.h>
#define LED0 PB0
#define LED1 PB1
#define BUTTON PB2
ISR (INT0_vect) {
// Button pin with pull-up resistor reads HIGH at startup.
// When button is pushed it goes LOW and ISR is triggerd on falling edge.
PORTB |= (1 << LED0);
_delay_ms(200);
PORTB &= ~(1 << LED0);
_delay_ms(200);
// Debug.print("LED0 "); Debug.println(PINB);
}
ISR (PCINT0_vect) {
if (bit_is_clear(PINB, LED1)) { // if bit is clear / LOW
PORTB |= (1 << LED1); // set bit, turn on
}
else { // if bit is set / HIGH
PORTB &= ~(1 << LED1); // clear bit, turn off
}
// Debug.print("LED1 "); Debug.println(PINB);
}
void external_interrupt() {
/*
This register contains the bits INT0 and PCIE. Setting the INT0 bit to 1 enables the external interrupt to
PB2 (INT0) pin. It is possible to trigger interrupt even if the PB2 is configured as output.
This allows the software to trigger external interrupt rather than triggering by an external even itself.
*/
GIMSK |= (1 << INT0); // Enabling INT0 (external interrupt)
MCUCR |= (1 << ISC01); // Configuring as falling edge
// same as SREG – Status Register: • Bit 7 – I: Global Interrupt Enable
sei(); // Enabling global interrupt
}
// Status change on PB0 triggers this interrupt. Status change comes from external interrupt.
void pin_change_interrupt() {
GIMSK |= (1 << PCIE); // Enabling PCIE (pin change interrupt)
PCMSK |= (1 << PCINT0); // Pin change enable PB0 (LED0)
}
int main() {
DDRB |= (1 << LED0) | (1 << LED1); // Set PB0 and PB1 as output(LED)
PORTB |= (1 << BUTTON); // initialize pullup resistor on button pin PB2, 00000100
external_interrupt();
pin_change_interrupt();
Debug.println(PINB);
while(1) {
Debug.println(PINB);
}
}