Files
2025-03-17 17:43:11 +01:00

144 lines
3.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "header.h"
// 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)
#define TIMER_TOP_MS 20
volatile uint8_t value = 0;
volatile Boolean pressed = FALSE;
volatile Boolean timer_0_init = FALSE;
volatile Boolean timer_delay_enabled = FALSE;
volatile uint16_t timer_delay = 0;
void print_binary(int value) {
int mask_3 = 0b1000;
int bit_at_3 = value & mask_3;
int bit_at_4 = bit_at_3 << 1;
PORTB = (value & 0b111) + bit_at_4;
}
void increment_int() {
// int *value = params->value;
// int max = params->max;
value = (value >= MAX) ? MAX : ++value;
}
void decrement_int() {
// int *value = params->value;
// int min = params->min;
value = (value <= MIN) ? MIN : --value;
}
void increment_led() {
// IncrementParams *params = (IncrementParams *)param;
increment_int();
print_binary(value);
}
void decrement_led() {
// IncrementParams *params = (IncrementParams *)param;
decrement_int();
print_binary(value);
}
void timer0_init_1_ms() {
TCCR0A |= (1 << WGM01); // CTC mode
OCR0A = 249; // Compare match every 1ms (F_CPU / Prescaler = 16,000,000 / 64 = 250,000 ticks/sec)
TIMSK0 |= (1 << OCIE0A); // Enable Compare Match A interrupt
TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64
sei(); // Enable global interrupts
timer_0_init = TRUE;
}
void launch_delay_ms(void) {
if (!timer_0_init) {
timer0_init_1_ms();
}
CLEAR(PCICR, PCIE2); // disable interupt PCINT2
CLEAR(PCMSK2, PCINT20);
CLEAR(PCMSK2, PCINT18);
timer_delay = 0;
timer_delay_enabled = TRUE;
SET(PCIFR, PCIF2); // reset flag interrupt PCINT2
}
ISR(TIMER0_COMPA_vect) {
if (!timer_delay_enabled) {
return;
}
timer_delay++;
if (timer_delay >= TIMER_TOP_MS) {
// TOGGLE_ELEM(LED1);
timer_delay_enabled = FALSE;
SET(PCICR, PCIE2); // re-enable interupt PCINT2
SET(PCMSK2, PCINT20);
SET(PCMSK2, PCINT18);
}
}
void on_press(int bit, void (*action)(void)) {
// if ((TEST(PIND, bit)) == 0) {
// action();
// _delay_ms(20);
// while ((TEST(PIND, bit)) == 0) {
// continue;
// }
// _delay_ms(20);
// }
launch_delay_ms();
if (!pressed) {
// if ((TEST(PIND, bit)) == 0) {
// }
pressed = TRUE;
action();
} else {
pressed = FALSE;
}
}
// 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);
MODE_OUTPUT(LED3);
MODE_OUTPUT(LED4);
MODE_INPUT(BUTTON1);
MODE_INPUT(BUTTON2);
PULLUP_ON(BUTTON1);
PULLUP_ON(BUTTON2);
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
while(1);
}
ISR(PCINT2_vect) {
if (!TEST_PIN(BUTTON1)) {
on_press(SW1, increment_led);
}
if (!TEST_PIN(BUTTON2)) {
on_press(SW2, decrement_led);
}
}