#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/flash.h"
#include "hardware/sync.h"
#include "hardware/irq.h"
#include "hardware/timer.h"
// Definições de pinos
#define BUTTON_A_PIN 5
#define BUTTON_B_PIN 6
#define LED_PIN 13
// Configuração da memória flash
#define FLASH_TARGET_OFFSET (256 * 1024) // Offset na flash para salvar o modo
#define FLASH_PAGE_SIZE 256 // Tamanho da página flash
#define FLASH_SECTOR_SIZE 4096 // Tamanho do setor flash
// Variáveis globais
volatile int count = 0;
volatile bool led_on = false;
volatile uint32_t start_time = 0;
volatile uint32_t blink_interval = 100; // Piscar a 10 Hz por padrão
volatile bool mode_1hz = false;
// Função para salvar o modo na memória flash
void save_mode_to_flash(bool mode) {
uint8_t mode_data[FLASH_PAGE_SIZE] = {0}; // Buffer para salvar o estado
mode_data[0] = mode ? 1 : 0; // 1 = 1 Hz, 0 = 10 Hz
uint32_t ints = save_and_disable_interrupts();
flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE); // Apagar setor
flash_range_program(FLASH_TARGET_OFFSET, mode_data, FLASH_PAGE_SIZE); // Gravar
restore_interrupts(ints);
printf("Modo salvo na memória flash: %s Hz\n", mode ? "1" : "10");
}
// Função para carregar o modo salvo da memória flash
bool load_mode_from_flash() {
const uint8_t *flash_target_contents = (const uint8_t *)(XIP_BASE + FLASH_TARGET_OFFSET);
return flash_target_contents[0] == 1;
}
// Função de debounce
bool debounce_gpio(uint gpio) {
static uint32_t last_time = 0;
uint32_t now = to_ms_since_boot(get_absolute_time());
if (now - last_time > 50) { // Delay de debounce de 50 ms
last_time = now;
return true;
}
return false;
}
// Callback para os botões
void button_callback(uint gpio, uint32_t events) {
if (gpio == BUTTON_A_PIN && (events & GPIO_IRQ_EDGE_RISE)) {
if (debounce_gpio(BUTTON_A_PIN)) {
count++;
printf("Botão A pressionado. Contagem: %d\n", count);
if (count == 5) {
led_on = true;
start_time = to_ms_since_boot(get_absolute_time());
printf("LED piscando por 10 segundos a %s Hz\n", mode_1hz ? "1" : "10");
}
}
} else if (gpio == BUTTON_B_PIN && (events & GPIO_IRQ_EDGE_RISE)) {
if (debounce_gpio(BUTTON_B_PIN)) {
mode_1hz = !mode_1hz; // Alterna entre 1 Hz e 10 Hz
blink_interval = mode_1hz ? 1000 : 100; // Atualiza o intervalo
printf("Modo alterado para %s Hz\n", mode_1hz ? "1" : "10");
save_mode_to_flash(mode_1hz); // Salva o novo modo na flash
}
}
}
// Callback do temporizador para piscar o LED
bool repeating_timer_callback(struct repeating_timer *t) {
static bool led_state = false;
static uint32_t last_toggle = 0;
uint32_t now = to_ms_since_boot(get_absolute_time());
if (led_on) {
if (now - last_toggle >= blink_interval / 2) {
gpio_put(LED_PIN, led_state);
led_state = !led_state;
last_toggle = now;
}
if (now - start_time >= 10000) { // Após 10 segundos
gpio_put(LED_PIN, 0); // Desliga o LED
led_on = false;
count = 0; // Reseta a contagem
printf("LED piscando terminado. Contagem reiniciada. Modo atual: %s Hz\n", mode_1hz ? "1" : "10");
}
}
return true;
}
int main() {
stdio_init_all();
// Carrega o modo salvo da memória flash
mode_1hz = load_mode_from_flash();
blink_interval = mode_1hz ? 1000 : 100;
printf("Modo inicial carregado: %s Hz\n", mode_1hz ? "1" : "10");
// Configuração dos GPIOs
gpio_init(BUTTON_A_PIN);
gpio_set_dir(BUTTON_A_PIN, GPIO_IN);
gpio_pull_up(BUTTON_A_PIN);
gpio_set_irq_enabled_with_callback(BUTTON_A_PIN, GPIO_IRQ_EDGE_RISE, true, &button_callback);
gpio_init(BUTTON_B_PIN);
gpio_set_dir(BUTTON_B_PIN, GPIO_IN);
gpio_pull_up(BUTTON_B_PIN);
gpio_set_irq_enabled_with_callback(BUTTON_B_PIN, GPIO_IRQ_EDGE_RISE, true, &button_callback);
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_put(LED_PIN, 0); // LED desligado inicialmente
// Configuração do temporizador para controlar o LED
struct repeating_timer timer;
add_repeating_timer_ms(10, repeating_timer_callback, NULL, &timer);
while (true) {
tight_loop_contents(); // Aguarda interrupções
}
}
Loading
pi-pico-w
pi-pico-w