mod04 ex02 wip

This commit is contained in:
hugo LAMY
2025-03-12 15:02:28 +01:00
parent 08dab7e608
commit 2625dc0946
2 changed files with 75 additions and 37 deletions

View File

@@ -14,7 +14,17 @@
// PROTOTYPES // PROTOTYPES
// //
// main.c // main.c
void blink_led_1(); void print_binary(int value);
void vary_duty(); 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 #endif // HEADER_H

View File

@@ -1,10 +1,27 @@
#include "header.h" #include "header.h"
typedef struct { // ALTERNATE FUNCTIONS :
int *value; // Table 14-9 : port D alternate functions
int max; // BUTTON1 SW1 PD2 :
int min; // -> INT0 (External Interrupt 0 Input)
} IncrementParams; // -> 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) { void print_binary(int value) {
int mask_3 = 0b1000; int mask_3 = 0b1000;
@@ -13,33 +30,33 @@ void print_binary(int value) {
PORTB = (value & 0b111) + bit_at_4; PORTB = (value & 0b111) + bit_at_4;
} }
void increment_int(IncrementParams *params) { void increment_int() {
int *value = params->value; // int *value = params->value;
int max = params->max; // int max = params->max;
*value = (*value >= max) ? max : ++(*value); value = (value >= MAX) ? MAX : ++value;
} }
void decrement_int(IncrementParams *params) { void decrement_int() {
int *value = params->value; // int *value = params->value;
int min = params->min; // int min = params->min;
*value = (*value <= min) ? min : --(*value); value = (value <= MIN) ? MIN : --value;
} }
void increment_led(void *param) { void increment_led() {
IncrementParams *params = (IncrementParams *)param; // IncrementParams *params = (IncrementParams *)param;
increment_int(params); increment_int();
print_binary(*(params->value)); print_binary(value);
} }
void decrement_led(void *param) { void decrement_led() {
IncrementParams *params = (IncrementParams *)param; // IncrementParams *params = (IncrementParams *)param;
decrement_int(params); decrement_int();
print_binary(*(params->value)); 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) { if ((TEST(PIND, bit)) == 0) {
action(params); action();
_delay_ms(20); _delay_ms(20);
while ((TEST(PIND, bit)) == 0) { while ((TEST(PIND, bit)) == 0) {
continue; 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() { int main() {
MODE_OUTPUT(LED1); MODE_OUTPUT(LED1);
MODE_OUTPUT(LED2); MODE_OUTPUT(LED2);
@@ -56,17 +73,28 @@ int main() {
MODE_OUTPUT(LED4); MODE_OUTPUT(LED4);
MODE_INPUT(BUTTON1); MODE_INPUT(BUTTON1);
MODE_INPUT(BUTTON2); MODE_INPUT(BUTTON2);
PULLUP_ON(BUTTON1);
int value = 0; PULLUP_ON(BUTTON2);
int max = 15;
int min = 0;
IncrementParams params = {&value, max};
while(1) { SREG |= ENABLE_GLOBAL_INTERRUPT;
on_press(SW1, increment_led, &params);
on_press(SW2, decrement_led, &params); 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);
} }
} if (!TEST(changedPins, SW1)) {
on_press(SW2, decrement_led);
ISR(TIMER0_COMPA_vect) { }
prevPIND = currentPIND;
} }