#include <STM32FreeRTOS.h>
// Definiciones
#define TIEMPO_REFRESCO_MS 3
// Tabla decodificación 7 segmentos
// 0–9, “E” (guion=10), “-” (error=11)
uint8_t deco_dato[] = {
0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78,
0x00, 0x10, 0x3f, 0x06
};
volatile uint8_t sol[4]= {10,10,10,10}; // valor inicial: “----”
// Definicion Pines ===
const int ANODOS_PINS[4] = {9, 10, 11, 12};
const int SEGMENTOS_PINS[7] = {2, 3, 4, 5, 6, 7, 8};
// Prototipos de funciones.
void TaskVisual(void *parameter);
void TaskSerial(void *parameter);
// === Configuración inicial ===
void setup() {
Serial.begin(115200);
Serial.println("Sistema iniciado...");
// Configurar pines
for (int i = 0; i < 4; i++) pinMode(ANODOS_PINS[i], OUTPUT);
for (int i = 0; i < 7; i++) pinMode(SEGMENTOS_PINS[i], OUTPUT);
// Apagar todos los dígitos y segmentos
for (int i = 0; i < 4; i++) digitalWrite(ANODOS_PINS[i], HIGH);
// Crear tareas
xTaskCreate(TaskVisual, "Visualiza", 256, NULL, 1, NULL);
xTaskCreate(TaskSerial, "Serial", 256, NULL, 1, NULL);
// Iniciar planificador
vTaskStartScheduler();
}
void loop() {
}
// === Tarea de visualización ===
void TaskVisual(void *parameter) {
(void)parameter;
uint8_t estado = 0;
while (true) {
// Apagar todos los dígitos antes de cambiar
for (int i = 0; i < 4; i++) digitalWrite(ANODOS_PINS[i], HIGH);
// Seleccionar valor a mostrar (invertido: sol[3] es millar)
uint8_t valor;
switch (estado) {
case 0: valor = deco_dato[sol[3]]; digitalWrite(ANODOS_PINS[3], LOW); break; // millares
case 1: valor = deco_dato[sol[2]]; digitalWrite(ANODOS_PINS[2], LOW); break; // centenas
case 2: valor = deco_dato[sol[1]]; digitalWrite(ANODOS_PINS[1], LOW); break; // decenas
case 3: valor = deco_dato[sol[0]]; digitalWrite(ANODOS_PINS[0], LOW); break; // unidades
default: valor = 0x7F; break;
}
// Mostrar segmentos
for (int i = 0; i < 7; i++) {
bool estadoSegmento = (valor >> i) & 0x01;
digitalWrite(SEGMENTOS_PINS[i], estadoSegmento);
}
estado++;
if (estado >= 4) estado=0;;
vTaskDelay(TIEMPO_REFRESCO_MS / portTICK_PERIOD_MS);
}
}
// === Tarea de recepción serial ===
void TaskSerial(void *parameter) {
(void)parameter;
char men_in[8];
int idx = 0;
while (true) {
while (Serial.available()) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
men_in[idx] = '\0';
if (idx == 4) {
bool valido = true;
for (int i = 0; i < 4; i++) {
if (men_in[i] < '0' || men_in[i] > '9') {
valido = false;
break;
}
}
if (valido) {
Serial.println("..Valido..");
// guardar en orden normal (millares a unidades)
sol[3] = men_in[0] - 48;
sol[2] = men_in[1] - 48;
sol[1] = men_in[2] - 48;
sol[0] = men_in[3] - 48;
} else {
Serial.println("..Invalido..");
for (int i = 0; i < 4; i++) sol[i] = 11; // “E”
}
} else {
Serial.println("..Esperando..");
for (int i = 0; i < 4; i++) sol[i] = 10; // “----”
}
idx = 0;
} else if (idx < 4) {
men_in[idx++] = c;
}
}
vTaskDelay(50 / 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.