get battery reference voltage

This commit is contained in:
2025-11-09 17:58:54 +01:00
parent d59d3bc009
commit 5f1141399f

66
main.c
View File

@ -76,13 +76,13 @@ int main(void)
PORTA.PIN0CTRL = PORT_PULLUPEN_bm; // Pull-up enabled
leds_off(); // Ensure all LEDs off at startup
battery_level_indicator(); // TODO: Implement
bool bLedEnabledOld = bLedEnabled;
eModeCurrent = ANIMATION_BLINK; // Set the mode to start with
while (true)
{
battery_level_indicator();
bBtnPressed = handleSwitch(); // Check switch state
// Light LEDs while button is pressed
@ -162,6 +162,7 @@ static inline void switchMode(void)
*/
static void configureLowPower(void)
{
return;
// Set unused pins as outputs LOW to prevent floating inputs
// Floating inputs can cause extra current consumption
PORTA.DIRSET = PIN4_bm | PIN5_bm; // Set PA4, PA5 as outputs if unused
@ -248,15 +249,72 @@ static inline void leds_on(void)
setPWM_PA2(255U);
}
/**
* @brief Read battery voltage using internal 1.1V reference
* @return Estimated battery voltage in millivolts
*/
uint16_t readBatteryVoltage(void)
{
// Enable ADC
ADC0.CTRLA = ADC_ENABLE_bm;
// Select internal voltage reference as input
ADC0.MUXPOS = ADC_MUXPOS_INTREF_gc;
// Use VCC as reference (default)
ADC0.CTRLC = ADC_PRESC_DIV4_gc; // Prescaler for 5MHz/4 = 1.25MHz ADC clock
// Start conversion
ADC0.COMMAND = ADC_STCONV_bm;
// Wait for conversion complete
while (!(ADC0.INTFLAGS & ADC_RESRDY_bm))
;
uint16_t adcResult = ADC0.RES;
// Disable ADC to save power
ADC0.CTRLA = !ADC_ENABLE_bm;
// Calculate VCC voltage
// V_battery = 1.1V × 1023 / ADC_result
// Result in millivolts: 1100 × 1023 / ADC_result
uint32_t voltage_mv = (1100UL * 1023UL) / adcResult;
return (uint16_t)voltage_mv;
}
/**
* @brief Battery monitoring
*/
static void battery_level_indicator(void)
{
// TODO: Implement
VPORTA.OUT |= (PA6_SET_MASK | PA7_SET_MASK); // green + red OFF
}
uint16_t voltage = readBatteryVoltage();
// 1S LiPo voltage ranges:
// Good: >=3700mV
// Low: >=3500mV
// VPORTA.OUT &= ~(PA6_SET_MASK | PA7_SET_MASK); // Turn off both LEDs first
if (voltage >= 3700)
{
// Green ON, Red OFF - Good battery
VPORTA.OUT &= ~PA6_SET_MASK; // Green ON (active low)
}
else if (voltage >= 3500)
{
// Both ON (yellow/orange) - Medium battery
VPORTA.OUT &= ~(PA6_SET_MASK | PA7_SET_MASK);
}
else
{
// Green OFF, Red ON - Low battery
VPORTA.OUT &= ~PA7_SET_MASK; // Red ON (active low)
}
VPORTA.OUT &= ~(PA6_SET_MASK | PA7_SET_MASK);
}
/**
* @brief Handle momentary switch input on PA0
*