Skip to main content
Graduate
January 18, 2025
Question

STM32F401 ADC VrefInt and Vbat read issue

  • January 18, 2025
  • 4 replies
  • 1162 views

During simple task I need to measure Vrefint and Vbat, so, I open CubeMX and configure ADC to read Vrefint and Vbat

LoMoMoMo_0-1737192445199.png

Than I setup a DMA to read values...

LoMoMoMo_1-1737192522442.png

I write a really simple program:

/* USER CODE BEGIN PD */
#define	ADC_BUF_SIZE 20
/* USER CODE END PD */

/* USER CODE BEGIN PV */
uint32_t	adc_buffer	[ADC_BUF_SIZE];
/* USER CODE END PV */


int main(void)
{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_ADC1_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */

 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 HAL_ADC_Start_DMA (&hadc1, adc_buffer, ADC_BUF_SIZE);

 HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
 HAL_Delay (200);
		
 HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
 HAL_Delay (200);
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

But I faced with really strange issue

When I configure Rank1 and Rank2 as Vrefint and run my program I get such results (i.e. ref value is 1492)

(value stored at 0x1FFF 7A2A close to this value, so, reading is correct)

 

LoMoMoMo_2-1737192841020.png

When I configure Rank1 and Rank2 as Vbat and run my program I get such results (i.e. Vbat value is 1021)

LoMoMoMo_3-1737192955429.png

But when I configure Rank1 as Vbat and Rank2 as Vrefint I get such values (also I can configure Rank1 as Vrefint and Rank2 as Vbat):

LoMoMoMo_4-1737193134439.png

i.e. Vbat is 1021 (as previously) and Vrefint is 656 (previously 1492)

I try to change sampling time - doesn't help

I try to change resolution of ADC - doesn't help

I try to disable DMA - doesn't help

I try to use Enable/Disable Continuous Conversion Mode - doesn't help

I try to disable DMA and read ADC with polling mode - doesn't help

I try to use manual channel selection Vrefint like this

 sConfig.Channel = ADC_CHANNEL_VREFINT;
 sConfig.Rank = 1;
 sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

than run ADC, get result in polling mode, than change ADC channel to Vbat

 sConfig.Channel = ADC_CHANNEL_VBAT;
 sConfig.Rank = 1;
 sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }

and Run ADC again in polling mode - doesn't help

I try to add pause for 10ms, 100ms, 1 seconds between conversions - doesn't help

 

I can remove Vbat from measuring and add more ADC channels to sequence (like IN0, IN1, Vrefint, IN4) - in this situation I get Vrefint 1492, but when I add Vbat to such sequence (i.e. IN0, Vbat, IN1, Vrefint, IN4) I get Vrefint as ~600, or some other values, but never 1492

Firstly I try it on my own PCB (STM32F401RCT) and faced with this problem, but now I run NUCLEO-F401RE board and see the same problem...

I think I'm doing something wrong, but I doesn't understanding what I missing in such simple task...

    This topic has been closed for replies.

    4 replies

    LoMo-MoMoAuthor
    Graduate
    January 18, 2025

    CubeMX project file

    LoMo-MoMoAuthor
    Graduate
    January 20, 2025

    I try just the same project / firmware for NUCLEO-L476RG demo board

    only Vbat measuring (1306)

    LoMoMoMo_1-1737367409130.png

    only Vref measuring (1434)

    LoMoMoMo_2-1737367527777.png

    Vrefint (1434) and Vbat (1305) measured together in a raw

    LoMoMoMo_3-1737367681382.png

    So, the same project/software works correctly for F476 and doesn't work for F401

    How to ask some official guys from STM about such situation?

    Super User
    January 20, 2025

    This is consequence of a bizarre limitation in some (most?) 'F4, that you need a software intervention - switching on/off ADC_CCR.TSVREFE and ADC_CCR.VBATE - between measuring VBAT and VREFINT (and internal temperature sensor).

    JW

     

    LoMo-MoMoAuthor
    Graduate
    January 21, 2025

    Previously I try manual switching, but it doesn't help

    But now I know where to look at :)

    Thanks!

    January 21, 2025

    Despite adjustments to settings like sampling time and resolution, the problem persists. Have you encountered similar issues with ADC channels on the STM32F401, and what solutions have worked for you?

    LoMo-MoMoAuthor
    Graduate
    January 21, 2025

    I will try it today :)