From 1f3e31c29566347d4ddc7cdd5e448d14131de00f Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Fri, 2 Dec 2022 17:58:49 +0100 Subject: [PATCH] Added first implementation of hardware interrupt, and example for GPIO usage. --- examples/digital_io.c | 37 +++++++++++++++++++++++++++++++++++++ src/gympal.c | 24 +++++++++++++++++++----- 2 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 examples/digital_io.c diff --git a/examples/digital_io.c b/examples/digital_io.c new file mode 100644 index 0000000..dc9e9f1 --- /dev/null +++ b/examples/digital_io.c @@ -0,0 +1,37 @@ +/* +This example showcases digital input and output using the AVR chip's GPIO +pins. For all pins, we first have to configure them as either input or output. +We do this by writing to the DDRx register (data direction register) either a 1 +(for output) or 0 (for input). + +We can set the output of a pin by writing to PORTx, using bitwise operators. + +Reading can be done by reading from PINx, using bitwise operators. +*/ +#include +#include + +int main() { + // Pin 12 == Port B4, aka 4th bit on the B register. + // Set pin 12 as output. + DDRB |= 1 << PORTB4; + // Set pin 5 as input. + DDRD &= ~(1 << PORTD5); + // Write a 0 to pin 12 initially. + PORTB &= ~(1 << PORTB4); + uint8_t led = 0; + while (1) { + // Write current led status to pin 12. + if (led) { + PORTB |= 1 << PORTB4; + } else { + PORTB &= ~(1 << PORTB4); + } + led = !led; + _delay_ms(1000.0); + // Read input from pin 5. If it's HIGH, keep the LED on. + uint8_t pin5Value = (PIND & (1 << PIND5)) >> PIND5; + if (pin5Value) led = 1; + } + return 0; +} \ No newline at end of file diff --git a/src/gympal.c b/src/gympal.c index a0d766b..634dba8 100644 --- a/src/gympal.c +++ b/src/gympal.c @@ -1,19 +1,33 @@ #include +#include #include +volatile uint8_t a = 0; + void updatePin12(uint8_t status) { PORTB = status << PORTB4; } +ISR(PCINT2_vect) { + uint8_t value = (PIND & (1 << PIND5)) >> PIND5; + PORTB = value << PORTB4; +} + int main() { + PCICR |= 1 << PCIE2; + PCMSK2 |= 1 << PCINT21; + sei(); // Pin 12 == Port B4, aka 4th bit on the B register. // Set pin 12 as output. - DDRB = 1 << PORTB4; - uint8_t ledOn = 1; + DDRB |= 1 << PORTB4; + // Set pin 5 as input. + DDRD &= ~(1 << PORTD5); + PORTB &= ~(1 << PORTB4); while (1) { - updatePin12(ledOn); - ledOn = !ledOn; - _delay_ms(1000.0); + // updatePin12(ledOn); + // ledOn = !ledOn; + // _delay_ms(1000.0); + // DO NOTHING! rely on interrupt. } return 0; } \ No newline at end of file