I am doing some development on a Weact STM32F411 black pill. Most of it has gone fine. However I am trying to read the voltage on the VBAT pin (backup 3V button cell) using the internal ADC, but I cannot get sensible readings.
It is only read once after reset, so register default values are assumed, and from the manual the STM32F411CE can put VBAT (/4) directly on to ADC #18 by setting VBATE. From the schematic, the ADC ref +/- are 3V3/0V on the board. The code is as follows (the peripheral clock for ADC1 on APB2 is already enabled).
... // peripheral clock already enabled
ADC->CCR |= 0b01 << 16; // ADC clock prescaler to /4 (should give 24MHz)
ADC1->CR1 |= 0b00 << 24; // 12 bit resolution
ADC1->CR2 |= 0b0 << 11; // right aligned
ADC1->SMPR1 |= 0b111 << 24; // ADC #18 sampling time 480 cycles
ADC1->SQR1 |= 0 << 20; // 1 conversion (n = L + 1)
ADC1->SQR3 |= 18 << 0; // conversion[0] is ADC #18
ADC1->CR2 |= 0b0 << 1; // continuous mode is off
ADC->CCR |= 0b1 << 22; // VBATE - backup battery voltage connected to #18
ADC1->CR2 |= 0b1 << 0; // ADC module is on
delayCycles(100); // short delay (100x NOP)
ADC1->CR2 |= ADC_CR2_SWSTART; // start conversion
while ((ADC1->SR & ADC_SR_EOC) != ADC_SR_EOC) {} // wait for conversion finish
U16 rawCounts = ADC1->DR;
...
(I'm aware that things like << 0 and 0 << n do nothing, it's just for readability).
The code runs once soon after start up and what I find is that whatever voltage (0 to 3.3V) is on the VBAT pin, I tend to get an ADC count reading of ~1010 give or take a few counts, which with a 12 bit ADC and /4 divider internally, gives around 3.2-3.3V.
Any suggestions appreciated.