DÍA 020 DE 365

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

📖 Teoría Explícita: Aritmética Base 10 y ASCII

1. La Matemática de la Extracción

¿Cómo extraes un dígito individual de un número masivo como 15450? La Unidad Aritmético Lógica (ALU) nos ofrece dos herramientas clave en base decimal:

2. El Salto ASCII (El truco del +'0')

Una vez extraído el dígito matemático (ej. el número 5), no podemos enviarlo crudo al LCD. Debemos convertirlo en el carácter '5'. Sabiendo que el carácter '0' equivale al número decimal 48 en la tabla ASCII, al sumar 5 + '0' obtenemos 53, que es exactamente el código ASCII para el carácter '5'.

3. El Problema del Espejo

La aritmética de extracción saca los números del final hacia el principio (del menos significativo al más significativo). Si procesamos el número 1045, la extracción arroja '5', luego '4', luego '0', luego '1'. Al guardarlos en nuestro Arreglo de Caracteres, el texto dirá "5401". Debemos implementar un algoritmo de doble puntero para invertir el arreglo antes de colocar el sagrado terminador nulo '\0'.

ALGORITMO CUSTOM_ITOA: EXTRACCIÓN E INVERSIÓN 1. EXTRACCIÓN (Módulo 10) Valor = 1045 1045 % 10 = 5 -> '5' [0] 1045 / 10 = 104 104 % 10 = 4 -> '4' [1] 104 / 10 = 10 ... Y así sucesivamente. 2. ARREGLO AL REVÉS '5' '4' '0' '1' '\0' Intercambio de Bytes (Swap) El resultado final será "1045\0"

⚙️ Ejercicios Prácticos: Implementando `custom_itoa`

Ejercicio 1: El Motor de Conversión. Escribiremos una función defensiva que reciba un número uint32_t y un puntero a un arreglo de caracteres (buffer). Validaremos el cero absoluto, extraeremos los dígitos, los pasaremos a ASCII y rotaremos el arreglo usando índices simples.


#include <stdint.h>

/**
 * @brief Convierte un entero a String ASCII sin requerir stdio.h o sprintf.
 * @param valor  El número a convertir (Ej. El volumen de gas en mililitros).
 * @param buffer Puntero al arreglo de destino donde se guardará el texto.
 */
void custom_itoa(uint32_t valor, char* buffer) {
    uint8_t i = 0;
    
    // 1. CASO ESPECIAL: EL CERO ABSOLUTO
    // Si el número es 0, el bucle while no correría. Lo atajamos de frente.
    if (valor == 0) {
        buffer[i++] = '0';
        buffer[i] = '\0';
        return;
    }
    
    // 2. EXTRACCIÓN DE DÍGITOS (ORDEN INVERSO)
    while (valor > 0) {
        uint8_t digito = valor % 10;           // Extrae el último dígito
        buffer[i++] = digito + '0';            // Convierte a ASCII y almacena
        valor /= 10;                           // Reduce el número original
    }
    
    // Inyectamos el terminador nulo sagrado
    buffer[i] = '\0';
    
    // 3. RUTINA DE INVERSIÓN (SWAP)
    // El arreglo dice "05451". Necesitamos que diga "15450".
    uint8_t inicio = 0;
    uint8_t fin = i - 1; // i está posicionado en el '\0', retrocedemos uno.
    
    while (inicio < fin) {
        char temp = buffer[inicio];        // Guardamos el primer carácter
        buffer[inicio] = buffer[fin];      // Sobrescribimos el primero con el último
        buffer[fin] = temp;                // Restauramos el último desde temp
        inicio++;
        fin--;
    }
}

// =====================================================================
// APLICACIÓN EN EL DESPACHADOR LP
// =====================================================================
void Actualizar_HMI_Local(uint32_t volumen_actual_ml) {
    
    // Reservamos 12 bytes estáticos. Un uint32_t no puede superar los
    // 10 dígitos decimales (4,294,967,295), más el '\0'.
    char buffer_pantalla[12]; 
    
    // ¡Adiós a los 15KB de peso muerto! Llamamos a nuestra rutina en C puro.
    custom_itoa(volumen_actual_ml, buffer_pantalla);
    
    // El 'buffer_pantalla' ahora contiene "15450\0"
    // Listo para inyectarse al driver del LCD I2C.
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Hito Logrado: Erradicación total de la dependencia de <stdio.h> para el formateo de datos.

Con la implementación de custom_itoa, el código fuente de tu Despachador de Gas LP es ahora 100% portable. Puedes compilar este exacto archivo en un NXP Kinetis, migrarlo la semana siguiente a un STM32 Cortex-M, y luego probarlo en un simple Arduino, y el comportamiento será matemáticamente idéntico y predecible a nivel de ciclo de reloj. Estás dominando la esencia de la arquitectura Bare-Metal: sin cajas negras, sin latencias sorpresivas y conservando cada byte valioso de tu memoria Flash.

📝 Resumen del Día