#include <STM32FreeRTOS.h>
// Definiciones Tiempos (ms)
#define TIEMPO_CONTEO 300
#define TIEMPO_PARPADEO 100
#define TIEMPO_REFRESCO 3
// Variables globales
volatile uint8_t U = 0;
volatile uint8_t D = 0;
volatile uint8_t C = 0;
volatile uint8_t UM = 0;
// Tabla de decodificación
byte deco_dato[] = {
0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78,
0x00, 0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0E
};
// Segmentos a–g: D2–D8
const int segmentos[] = {2, 3, 4, 5, 6, 7, 8};
// Anodos (control de cada dígito)
const int anodos[] = {9, 10, 11, 12}; // D9–D12
// LED de parpadeo
const int LED_PIN = LED_BUILTIN; // (PA5 en Nucleo)
// Prototipos
void TaskVisualiza(void *parameter);
void TaskCuenta(void *parameter);
void TaskParpadeo(void *parameter);
void setup() {
Serial.begin(115200);
Serial.println("Iniciando sistema con FreeRTOS...");
// Inicialización de pines
pinMode(LED_PIN, OUTPUT);
for (int i = 0; i < 7; i++) pinMode(segmentos[i], OUTPUT);
for (int i = 0; i < 4; i++) pinMode(anodos[i], OUTPUT);
// Apagar todos los dígitos
for (int i = 0; i < 4; i++) digitalWrite(anodos[i], HIGH);
// Crear tareas
xTaskCreate(TaskVisualiza, "Visualiza", 256, NULL, 2, NULL);
xTaskCreate(TaskCuenta, "Cuenta", 256, NULL, 1, NULL);
xTaskCreate(TaskParpadeo, "Parpadeo", 128, NULL, 1, NULL);
// Iniciar planificador
vTaskStartScheduler();
}
void loop() {
}
// Tarea: Parpadeo del LED
void TaskParpadeo(void *parameter) {
(void) parameter;
while (true) {
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
vTaskDelay(TIEMPO_PARPADEO / portTICK_PERIOD_MS);
}
}
// Tarea: Contador de 4 dígitos
void TaskCuenta(void *parameter) {
(void) parameter;
while (true) {
U++;
if (U == 10) {
U = 0;
D++;
if (D == 10) {
D = 0;
C++;
if (C == 10) {
C = 0;
UM++;
if (UM == 10) UM = 0;
}
}
}
vTaskDelay(TIEMPO_CONTEO / portTICK_PERIOD_MS);
}
}
// Tarea: Multiplexado del 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], HIGH);
uint8_t valor;
switch (estado) {
case 0: valor = deco_dato[U]; digitalWrite(anodos[0], LOW); break; // Unidades
case 1: valor = deco_dato[D]; digitalWrite(anodos[1], LOW); break; // Decenas
case 2: valor = deco_dato[C]; digitalWrite(anodos[2], LOW); break; // Centenas
case 3: valor = deco_dato[UM]; digitalWrite(anodos[3], LOW); break; // Unidades de millar
default: valor = 0x7F; break;
}
// Mostrar segmentos (bit 0 = a, bit 6 = g)
for (int i = 0; i < 7; i++) {
bool estadoSegmento = (valor >> i) & 0x01;
digitalWrite(segmentos[i], estadoSegmento); // Ánodo común → 1 = apagado
}
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.