diff --git a/module04/ex02/header.h b/module04/ex02/header.h index b4d8b56..e7a7ea8 100644 --- a/module04/ex02/header.h +++ b/module04/ex02/header.h @@ -14,7 +14,17 @@ // PROTOTYPES // // main.c -void blink_led_1(); -void vary_duty(); +void print_binary(int value); +void increment_int(); +void decrement_int(); +void increment_led(); +void decrement_led(); +void on_press(int bit, void (*action)(void)); + +// +// MACROS +// +#define MAX 15 +#define MIN 0 #endif // HEADER_H \ No newline at end of file diff --git a/module04/ex02/main.c b/module04/ex02/main.c index e3a85c3..478cecd 100644 --- a/module04/ex02/main.c +++ b/module04/ex02/main.c @@ -1,10 +1,27 @@ #include "header.h" -typedef struct { - int *value; - int max; - int min; -} IncrementParams; +// ALTERNATE FUNCTIONS : +// Table 14-9 : port D alternate functions +// BUTTON1 SW1 PD2 : +// -> INT0 (External Interrupt 0 Input) +// -> PCINT18 (Pin Change Interrupt 18) +// BUTTON2 SW2 PD4 : +// -> XCK (USART External Clock Input/Output) +// -> T0 (Timer/Counter 0 External Counter Input) +// -> PCINT20 (Pin Change Interrupt 20) +// EXTERNAL INTERRUPTS GROUP : +// 13.2.4 : pin change interrupt controle register (PCICR) +// -> bit PCIE2 for PCINT[23:16] (PCI2 Interrupt Vector) +// PCMSK2 to enable each pin +// INTERRUPT VECTORS NAME : +// Table 12-6 : interrupts vectors +// -> PCINT2_vect +// ENABLE PIN CHANGE INTERRUPT : +// 13.2.6 : PCMSK2 – Pin Change Mask Register 2 +// -> (1 << PCINT20) | (1 << PCINT18) + +volatile uint8_t prevPIND; // Store previous state of PIND +volatile uint8_t value = 0; void print_binary(int value) { int mask_3 = 0b1000; @@ -13,33 +30,33 @@ void print_binary(int value) { PORTB = (value & 0b111) + bit_at_4; } -void increment_int(IncrementParams *params) { - int *value = params->value; - int max = params->max; - *value = (*value >= max) ? max : ++(*value); +void increment_int() { + // int *value = params->value; + // int max = params->max; + value = (value >= MAX) ? MAX : ++value; } -void decrement_int(IncrementParams *params) { - int *value = params->value; - int min = params->min; - *value = (*value <= min) ? min : --(*value); +void decrement_int() { + // int *value = params->value; + // int min = params->min; + value = (value <= MIN) ? MIN : --value; } -void increment_led(void *param) { - IncrementParams *params = (IncrementParams *)param; - increment_int(params); - print_binary(*(params->value)); +void increment_led() { + // IncrementParams *params = (IncrementParams *)param; + increment_int(); + print_binary(value); } -void decrement_led(void *param) { - IncrementParams *params = (IncrementParams *)param; - decrement_int(params); - print_binary(*(params->value)); +void decrement_led() { + // IncrementParams *params = (IncrementParams *)param; + decrement_int(); + print_binary(value); } -void on_press(int bit, void (*action)(void*), void *params) { +void on_press(int bit, void (*action)(void)) { if ((TEST(PIND, bit)) == 0) { - action(params); + action(); _delay_ms(20); while ((TEST(PIND, bit)) == 0) { continue; @@ -48,7 +65,7 @@ void on_press(int bit, void (*action)(void*), void *params) { } } -// write a program that increments and decrements a binary number using the buttons, and displays the result on the LEDs +// write a program that incr/decr-ements a number with the buttons, using interrupts, empty infinite loop, and displays the result on LEDs in binary int main() { MODE_OUTPUT(LED1); MODE_OUTPUT(LED2); @@ -56,17 +73,28 @@ int main() { MODE_OUTPUT(LED4); MODE_INPUT(BUTTON1); MODE_INPUT(BUTTON2); - - int value = 0; - int max = 15; - int min = 0; - IncrementParams params = {&value, max}; + PULLUP_ON(BUTTON1); + PULLUP_ON(BUTTON2); - while(1) { - on_press(SW1, increment_led, ¶ms); - on_press(SW2, decrement_led, ¶ms); + SREG |= ENABLE_GLOBAL_INTERRUPT; + + PCICR = (1 << PCIE2); // 13.2.4 : enable pin change interrupt, bit PCIE2 for PCINT[23:16], (Table 14-9 : alternates : PD2 - PCINT18, PD4 - PCINT20) + PCMSK2 = (1 << PCINT20) | (1 << PCINT18); // 13.2.6 : enable individual pin chang interrupt + + prevPIND = PIND; + + while(1); +} + +ISR(PCINT2_vect) { + uint8_t currentPIND = PIND; // Read the current state of Port D + uint8_t changedPins = currentPIND ^ prevPIND; // Find changed bits + + if (!TEST(changedPins, SW1)) { + on_press(SW1, increment_led); } -} - -ISR(TIMER0_COMPA_vect) { + if (!TEST(changedPins, SW1)) { + on_press(SW2, decrement_led); + } + prevPIND = currentPIND; }