Una función en C es un bloque de código encapsulado que realiza una tarea específica. En sistemas embebidos, usamos funciones para crear una Hardware Abstraction Layer (HAL). En lugar de escribir GPIOA->ODR |= (1 << 5); en medio de tu máquina de estados, escribes Abrir_Valvula_Gas();. Si mañana cambias tu microcontrolador de un MC9S08 a un STM32, solo modificas el interior de esa función; tu lógica principal permanece intacta.
Un microcontrolador opera con lógica de 3.3V y puede suministrar un máximo de 20mA. Una electroválvula de Gas LP industrial requiere 24V y puede consumir más de 1 Amperio (1000mA). Si conectas la válvula directamente al microcontrolador, el silicio se evaporará instantáneamente. Necesitamos una Etapa de Potencia.
Para controlar la válvula, la función en C enviará una señal de 3.3V a un transistor MOSFET de nivel lógico. El MOSFET actúa como un interruptor de alta potencia que deja fluir los 24V hacia la bobina. Además, toda bobina genera un pico de voltaje destructivo al apagarse (fuerza contraelectromotriz). Es imperativo colocar un Diodo Flyback en paralelo a la válvula para absorber este impacto y proteger la electrónica.
Ejercicio 1: Encapsulamiento del Actuador. Diseñaremos las funciones que ocultan la manipulación directa de los registros del STM32. Utilizaremos nombres semánticos que dejen claro qué ocurre físicamente en la tubería.
#include <stdint.h>
#include <stdbool.h>
// Simulación de los registros de un STM32 para el Puerto A
#define GPIOA_ODR (*((volatile uint32_t *)0x40020014)) // Output Data Register
#define PIN_VALVULA 5 // Asumimos que el Gate del MOSFET está en el PIN 5
/**
* @brief Abre la electroválvula de gas.
* @detail Energiza el pin enviando 3.3V al gate del MOSFET.
*/
void Abrir_Valvula_Principal(void) {
// Usamos el operador bit a bit OR (|) para poner el bit 5 en 1
// sin alterar el estado de los demás pines del puerto A.
GPIOA_ODR |= (1 << PIN_VALVULA);
}
/**
* @brief Cierra la electroválvula de gas.
* @detail Corta la energía bajando el pin a 0V. La válvula es Normalmente Cerrada.
*/
void Cerrar_Valvula_Principal(void) {
// Usamos el operador AND (&) y el operador NOT (~) para poner
// el bit 5 en 0, garantizando el corte de flujo.
GPIOA_ODR &= ~(1 << PIN_VALVULA);
}
/**
* @brief Verifica el estado eléctrico actual de la válvula.
* @return true si la válvula está recibiendo señal de apertura.
*/
bool Obtener_Estado_Valvula(void) {
// Aplicamos una máscara para leer solo el bit de interés
if (GPIOA_ODR & (1 << PIN_VALVULA)) {
return true; // Abierta
} else {
return false; // Cerrada
}
}
Hito Logrado: Creación de la capa HAL (Hardware Abstraction Layer) para actuadores.
Al implementar estas funciones, lograste aislar la lógica de tu negocio (el switch de ayer) de la electrónica física. Si en la Fase 4 decides usar un Optoaislador inversor, donde enviar un `0` lógico significa abrir la válvula, no tendrás que buscar en todo tu código y cambiar la lógica matemática. Solamente cambiarás la instrucción dentro de la función Abrir_Valvula_Principal(). Esta es la base de un firmware escalable y fácil de auditar.