#include <STM32FreeRTOS.h>
// Definiciones
#define TIEMPO_REFRESCO 2 // ms
#define TIEMPO_ANTIRREBOTE 50 // ms
// Anodos (control de dígitos)
const int ANODOS[4] = {12, 11, 10, 9}; // D12–D9
// Segmentos a–g: D2–D8
const int SEGMENTOS[7] = {2, 3, 4, 5, 6, 7, 8};
// Botón de control
const int BOTON_PIN = A0; //Usar PC13 montaje real ó Pulsador conectado entre A0 y GND
// Variables globales
volatile uint8_t respuesta = 0; // 0–3: índice de mensaje actual
byte msg[4][4];
// Prototipos
void TaskVisualiza(void *parameter);
void TaskBoton(void *parameter);
void setup() {
Serial.begin(115200);
Serial.println("Iniciando sistema FreeRTOS - Control por botón...");
// Inicializar pines
for (int i = 0; i < 4; i++) pinMode(ANODOS[i], OUTPUT);
for (int i = 0; i < 7; i++) pinMode(SEGMENTOS[i], OUTPUT);
pinMode(BOTON_PIN, INPUT_PULLUP); // activo en LOW
// Inicializar matriz de mensajes
// msg[0] = "__FF"
msg[0][0] = 0b11111111;
msg[0][1] = 0b11111111;
msg[0][2] = 0b00001110;
msg[0][3] = 0b00001110;
// msg[1] = "PAUS"
msg[1][0] = 0b00001100;
msg[1][1] = 0b00001000;
msg[1][2] = 0b01000001;
msg[1][3] = 0b00010010;
// msg[2] = "PLAY"
msg[2][0] = 0b00001100;
msg[2][1] = 0b01000111;
msg[2][2] = 0b00001000;
msg[2][3] = 0b00010001;
// msg[3] = vacío
msg[3][0] = 0b11111111;
msg[3][1] = 0b11111111;
msg[3][2] = 0b11111111;
msg[3][3] = 0b11111111;
// Crear tareas
xTaskCreate(TaskVisualiza, "Visualiza", 256, NULL, 2, NULL);
xTaskCreate(TaskBoton, "Boton", 128, NULL, 1, NULL);
// Iniciar planificador
vTaskStartScheduler();
}
void loop() {
}
// Tarea: Lectura del botón con antirrebote
void TaskBoton(void *parameter) {
(void) parameter;
bool estadoAnterior = HIGH;
while (true) {
bool estadoActual = digitalRead(BOTON_PIN);
if (estadoActual == LOW && estadoAnterior == HIGH) {
// Se detecta una pulsación (flanco descendente)
respuesta = (respuesta + 1) % 4; // ciclo 0→1→2→3→0
Serial.print("Mensaje actual: ");
Serial.println(respuesta);
vTaskDelay(TIEMPO_ANTIRREBOTE / portTICK_PERIOD_MS);
}
estadoAnterior = estadoActual;
vTaskDelay(10 / portTICK_PERIOD_MS); // pequeño retardo de lectura
}
}
// Tarea: Multiplexar display
void TaskVisualiza(void *parameter) {
(void) parameter;
uint8_t estado = 0;
while (true) {
// Apagar todos los dígitos (ánodo común → HIGH = apagado)
for (int i = 0; i < 4; i++) digitalWrite(ANODOS[i], LOW); //montaje real usar HIGH
// Seleccionar byte correspondiente al dígito actual
uint8_t valor = msg[respuesta][estado % 4];
// Mostrar segmentos (bit 0=a ... bit 6=g)
for (int i = 0; i < 7; i++) {
bool bit_val = (valor >> i) & 0x01;
digitalWrite(SEGMENTOS[i], bit_val); // Ánodo común → 1 = apagado
}
// Encender el dígito actual
digitalWrite(ANODOS[estado % 4], HIGH); //montaje real usar LOW
estado++;
if (estado >= 4) estado = 0;
vTaskDelay(TIEMPO_REFRESCO / portTICK_PERIOD_MS);
}
}
//OJO (void) parameter;
//se debe incluir (void) parameter; al inicio de cada tarea para evitar advertencias
//del compilador y dejar el código limpio en los casos en que la tarea no necesita
//recibir paramentros. Cuando se reciben parametros no se usa.