board
Solar MPPT Power System
Public Unreviewedby TylerK
A 30 W solar battery charger with regulated 5 V and 3.3 V rails: an STM32G031 running perturb & observe MPPT and a CC/CV charge state machine, steering a TI LM5175 4-switch buck-boost through a single analog control input. Four-layer KiCad board, schematic and PCB generated from Python, with an electrothermal simulation run against the published board file.
main
TylerK
Replace discrete-analog board with MCU/IC redesign: STM32G031 P&O MPPT + CC/CV firmware, LM5175 buck-boost, INA180 curr…
e48ba30
1mo ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
/*
* app_main.c -- application entry point for the MPPT power system MCU.
*
* This file is the application layer that plugs into an STM32CubeMX/
* STM32CubeIDE-generated project: it assumes CubeMX has already generated
* main.c/main.h with SystemClock_Config(), MX_GPIO_Init(),
* MX_ADC1_Init() (3-channel scan: PA0/PA1/PA2), MX_TIM14_Init() (PWM on
* PA4, ~50kHz), MX_USART1_UART_Init() (115200 8N1 on PA9/PA10) and the
* peripheral handles hadc1/htim14/huart1, plus GPIO pin defines for
* LED1/LED2 (PA6/PA7) and MPPT_PGOOD/BIAS_PGOOD input pins -- see
* README.md for the exact CubeMX pin configuration table.
*
* app_main() replaces the body of CubeMX's generated `while(1)` loop in
* main.c (call it once from there instead of writing loop logic in-line).
*/
#include "main.h"
#include "board_config.h"
#include "charge_control.h"
#include "adc_sense.h"
#include "pwm_ref.h"
#include "uart_telemetry.h"
#include "status_led.h"
#define CONTROL_LOOP_PERIOD_MS 20U
#define TELEMETRY_PERIOD_MS 500U
void app_main(void) {
adc_filter_state_t adc_filt;
charge_control_t cc;
sensor_frame_t sensors;
uint32_t now = HAL_GetTick();
adc_sense_init(&adc_filt);
charge_control_init(&cc, now);
pwm_ref_init();
uart_telemetry_init();
status_led_init();
uint32_t next_control_ms = now;
uint32_t next_telemetry_ms = now;
for (;;) {
now = HAL_GetTick();
if ((int32_t)(now - next_control_ms) >= 0) {
next_control_ms = now + CONTROL_LOOP_PERIOD_MS;
adc_sense_read(&adc_filt, &sensors);
float setpoint = charge_control_update(&cc, &sensors, now);
pwm_ref_set_vbatt_setpoint(setpoint);
status_led_update(cc.state, now);
}
if ((int32_t)(now - next_telemetry_ms) >= 0) {
next_telemetry_ms = now + TELEMETRY_PERIOD_MS;
uart_telemetry_send(now, &sensors, &cc);
}
}
}