DÍA 021 DE 365

Fase 1: Fundamentos de C y Lógica de Software

📖 Teoría a Estudiar

La Ilusión del Punto Decimal

En el corazón de la ALU de un procesador Cortex-M o MC9S08, el valor 15450 es simplemente una cadena de bits. Si ese valor representa litros con tres cifras de precisión (escala de 1000), el punto decimal es solo un requerimiento visual de la Interfaz Humano-Máquina (HMI). Matemáticamente, podemos separar este número en dos componentes enteros utilizando divisiones y residuos.

Extracción de Partes (División y Módulo)

Dado un valor total $V$ y una escala decimal base $10^n$, podemos fragmentar la cifra sin tocar la memoria dinámica:

A partir de aquí, solo debemos armar el Arreglo de Caracteres en reversa, inyectando el símbolo '.' exactamente después de iterar la parte fraccionaria.

INYECCIÓN COSMÉTICA DE PUNTO DECIMAL uint32_t: 15450 / 1000 = 15 Parte Entera % 1000 = 450 Parte Fraccional ['1', '5', '.', '4', '5', '0', '\0'] .

⚙️ Ejercicios Prácticos

Ejercicio 1: Crea la función formatear_punto_fijo, capaz de tomar un número entero en bruto y convertirlo a un arreglo de caracteres (String) insertando el punto decimal según el nivel de precisión requerido (ej. 3 decimales para Litros, 2 para Moneda).


#include <stdint.h>

// --- 1. FUNCIÓN AUXILIAR DE INVERSIÓN (Del Día 20) ---
void reverse_string(char* str, uint8_t length) {
    uint8_t start = 0;
    uint8_t end = length - 1;
    while (start < end) {
        char temp = str[start];
        str[start] = str[end];
        str[end] = temp;
        start++;
        end--;
    }
}

// --- 2. EL MOTOR DE PUNTO FIJO A TEXTO ---
void formatear_punto_fijo(uint32_t valor_crudo, uint8_t num_decimales, char* buffer) {
    uint8_t i = 0;
    uint32_t divisor = 1;
    
    // Calcular el divisor base 10 (ej. 3 decimales -> divisor = 1000)
    for(uint8_t d = 0; d < num_decimales; d++) {
        divisor *= 10;
    }
    
    // Fragmentación del número
    uint32_t parte_entera = valor_crudo / divisor;
    uint32_t parte_frac = valor_crudo % divisor;
    
    // A) Procesar la parte fraccionaria extrayendo dígitos inversamente
    for(uint8_t d = 0; d < num_decimales; d++) {
        buffer[i++] = (parte_frac % 10) + '0';
        parte_frac /= 10;
    }
    
    // B) INYECCIÓN DEL PUNTO COSMÉTICO
    if(num_decimales > 0) {
        buffer[i++] = '.';
    }
    
    // C) Procesar la parte entera
    if (parte_entera == 0) {
        buffer[i++] = '0';
    } else {
        while (parte_entera > 0) {
            buffer[i++] = (parte_entera % 10) + '0';
            parte_entera /= 10;
        }
    }
    
    // D) Sellado con Terminador Nulo
    buffer[i] = '\0';
    
    // E) Rotar el arreglo a la posición humana legible
    reverse_string(buffer, i);
}

// --- SIMULACIÓN DEL SÚPER BUCLE ---
int main(void) {
    char buffer_display[16];
    
    // Volumen: 15.450 Litros
    uint32_t volumen_sensor = 15450; 
    formatear_punto_fijo(volumen_sensor, 3, buffer_display);
    
    // Dinero: $290.45 Pesos
    uint32_t costo_calculado = 29045; 
    formatear_punto_fijo(costo_calculado, 2, buffer_display);
    
    return 0;
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: HMI Determinista y Ligera.

Al erradicar la función sprintf y construir tu propia lógica de formateo, has recuperado incontables ciclos de reloj en tu microcontrolador y ahorrado Kilobytes en la memoria Flash. El despachador de grado industrial requiere actualizar la pantalla LCD y emitir tramas por UART hacia el módulo telemetría constantemente. Con esta arquitectura, la conversión de los datos de metrología es tan rápida que no afectará tus tiempos de sondeo de los sensores de presión críticos.

📝 Resumen del Día

❓ Cuestionario de Autoevaluación

1. ¿Qué ocurriría si intentamos formatear un valor de dinero de 29005 centavos con 2 decimales usando este algoritmo?
Respuesta: El algoritmo funciona a la perfección. La parte fraccionaria es 5. En el primer ciclo del bucle fraccionario extrae '5'. Luego 5 / 10 = 0. En el segundo ciclo extrae 0 % 10 = 0, por lo que inserta '0'. Inyecta el punto. Luego procesa 290 de la parte entera. Al invertirse todo, el buffer dice correctamente 290.05, demostrando que los ceros a la izquierda de la fracción se respetan.