INF2004_Labs/lab_3/lab_3.c

87 lines
2.0 KiB
C

/**
* To develop a simple stopwatch that measures time intervals between
* button presses.
*
* On pressing the START pseudo-button (GP15),
* the stopwatch will begin,
* and the elapsed time will be displayed every second on
* the Serial Monitor (or equivalent).
*
* Releasing the START pseudo-button will stop the timer and
* reset the elapsed time to zero.
*
* The START pseudo-button must incorporate a debouncing algorithm.
*
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#define PSEUDO_BTN 15
#define DELAY_US 1000000
unsigned long long time = 0;
struct repeating_timer timer;
bool repeating_timer_callback(struct repeating_timer *t) {
// Print elapsed time every second
printf("Elapsed Time: %llus\n",
(time_us_64() - time) / 1000000);
return true;
}
void gpio_callback(uint gpio, uint32_t events) {
// Start timer on button press
if (gpio == PSEUDO_BTN && events == GPIO_IRQ_EDGE_FALL)
{
time = time_us_64();
printf("Timer Started at %llu\n", time);
add_repeating_timer_us(
DELAY_US,
repeating_timer_callback,
NULL,
&timer
);
}
// Stop timer on button release
else if (gpio == PSEUDO_BTN && events == GPIO_IRQ_EDGE_RISE)
{
printf("Timer Stopped at %llu\n", time_us_64());
cancel_repeating_timer(&timer);
// Print elapsed time and reset
printf("Final Elapsed Time: %llus\n",
(time_us_64() - time) / 1000000);
time = 0;
}
}
static void btn_init()
{
gpio_init(PSEUDO_BTN);
gpio_set_dir(PSEUDO_BTN, GPIO_IN);
gpio_set_pulls(PSEUDO_BTN, true, false);
gpio_set_irq_enabled_with_callback(
PSEUDO_BTN,
GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL,
true,
&gpio_callback
);
}
int main()
{
stdio_init_all();
btn_init();
while (true) {
tight_loop_contents();
}
}