2025-06-17 1:23 AM
I use the STM32CubeIDE Version: 1.18.1 and the stm32g030k8.
I have a hardware that uses a firmware. This firmware correctly returns the values of the ADC. The ADC is linked to a DMA.
Channel 4 == 2545 (this is a voltage divisor) 12.5 volts
Channel 10 == 1 (this is connected to a current shunt resistor) No current, then almost 0.
Channel Temperature == 929
Channel Vreference == 1506
I develop a new firmware with the very same hardware (not just same design but same device). I apply debug optimization. I use ADC1 with the DMA, first I use the ioc file to set up the ADC and then I copy the MX_ADC1_Initfrom the other stm32cubeide project.
Yet It does not return the same value from the external pins. Why is that?
Thanks for all.
Solved! Go to Solution.
2025-06-17 3:22 AM
Solved!
HAL_ADC_Start(&hadc1); and HAL_ADCEx_Calibration_Start(&hadc1); were missing on the new firmware.
If the ADC is not callibrated it will return values like 82 and 83 instead of 0.
2025-06-17 1:45 AM
Hello,
@carlesls2 wrote:
I have a hardware that uses a firmware. This firmware correctly returns the values of the ADC.
Firmware that you don't have the code source?
2025-06-17 2:20 AM
I have the code.
Let me copy it here.
This is the configuration for the ADC in the former project and it works.
/**
******************************************************************************
* @file $ADC.c
* @date $12/06/2024
* @brief
*
* @headerfile ${headerfile}
*
* @defgroup ${name}
* @{
* @ingroup ${name}
* @{
* @details
*
* @note
*
* @see
*
* @warning
*
* @bug
*
******************************************************************************
* @attention
*
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <HAL/ADC.h>
#include <stdio.h>
/* Private includes ----------------------------------------------------------*/
#include "APP_Config.h"
#include "main.h"
/* Private define ------------------------------------------------------------*/
//------------------------------------------------------------------------------
/* Set Debugger configurations
* This set, configure debugger systems
*/
#ifdef DEBUG
//#define DEBUG_RTT_ADC // Enable Segger RTT
#endif
//------------------------------------------------------------------------------
/* Set ADC conversions
* This set, configure ADC module
*/
#define ADC_CHANEL_NUMBER 4 //!< [uint8_t] number of channels ADC
#define ADC_SAMPLES 4 //!< [uint8_t] number of samples for the mean
#define DIGITAL_SCALE_12BITS ((uint32_t) 0xFFF) // Full-scale digital value with a resolution of 12 bits
#define VAR_CONVERTED_DATA_INIT_VALUE (DIGITAL_SCALE_12BITS + 1) // Init variable out of ADC expected conversion data range
#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 4) // Definition of ADCx conversions data table size
#define VDDA_APPLI (3300U) // [mV] Value of analog reference voltage (Vref+), connected to analog voltage
#define CHANNEL_VBAT 0 // Array Position
#define CHANNEL_CURRENT 1
#define CHANNEL_TEMPERATURE 2
#define CHANNEL_VREF 3
#define ADC_VBAT_OFFSET +000 //!< [uint8_t] [mV] Correction factor of voltage battery
#define ADC_VBAT_R1 10000 //!< [uint16_t] Div R1 resistor value
#define ADC_VBAT_R2 2200 //!< [uint16_t] Div R2 Shunt resistor value
#define ADC_MOTOR_SHUNT_OFFSET +0.0f //!< [uint8_t] Correction factor of current shunt voltage
#define ADC_SHUNT 0.01f //!< [uint8_t] Shunt resistor value
/* Private typedef -----------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/**
* @brief Array where the new value will be added.
*/
volatile uint16_t ADC_DMA_Buff[4];
volatile uint32_t ADC_Average_Buff[ADC_CHANEL_NUMBER];
volatile uint8_t ADC_Samples = 0;
volatile uint16_t VoltageReference_Dig =0; // [uint16_t] [ADC] Average sum for digital value
volatile uint16_t VoltageBattery_Dig =0; // [uint16_t] [ADC]
volatile uint16_t VoltageMotorShunt_Dig =0; // [uint16_t] [ADC]
volatile int16_t Temperature_Dig =0; // [ int16_t] [ADC]
volatile uint16_t VoltageBattery_Pin =0; // [ int16_t] [mV] Pin Voltage input to ADC
volatile uint16_t VoltageMotorShunt_Pin =0; // [ int16_t] [mV] Pin Voltage input to ADC
volatile uint16_t VoltageReference =0; //!< [uint16_t] [mV] ADC Voltage Reference Average
volatile int16_t VoltageBattery = 0; //!< [int16_t] [mV] Voltage Battery Average
volatile int16_t CurrentMotor =0; //!< [int16_t] [mA] Voltage Motor Shunt Average
volatile int16_t Temperature =0; //!< [ int16_t] [0.01ºC] Tj microcontroller Average temperature, ±º2C aucrany
volatile uint16_t VoltageBatteryVirtual =0; //!< [uint16_t] [mV] Voltage Battery Average
volatile int16_t CurrentMotorVirtual =0; //!< [uint16_t] [mA] Voltage Motor Shunt Average
volatile int16_t TemperatureVirtual =0; //!< [ int16_t] [0.01ºC] Tj microcontroller Average temperature, ±º2C aucrany
volatile float ConversionFloat_Auxiliar=0.0f;
/* Private function prototypes -----------------------------------------------*/
/* Private user code ---------------------------------------------------------*/
/**
* @brief This function's role is to initialise the 4 ADC's value
* which are:
* [CHANEL_VREF]
* [CHANEL_VBAT]
* [CHANEL_CURRENT]
* [CHANEL_TEMPERATURE]
*
*/
void HAL_ADC_Init_vars(void)
{
//--------------------------
for (uint8_t idx = 0; idx < ADC_CHANEL_NUMBER; idx++)
{
ADC_DMA_Buff[idx] = 0;
ADC_Average_Buff[idx] = 0;
}
ADC_Samples = 0;
VoltageReference_Dig = 0;
VoltageBattery_Dig = 0;
VoltageMotorShunt_Dig = 0;
Temperature_Dig = 0;
VoltageBattery_Pin = 0;
VoltageReference = 0;
VoltageBattery = 0;
CurrentMotor = 0.0;
Temperature = 0;
ConversionFloat_Auxiliar=0.0f;
//--------------------------
}// End HAL_ADC_Init_vars
/**
* @brief This is an interruption that occurs whenever the DMA is ready to deliver a new ADC value/sample
*
*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc1)
{
ADC_Average_Buff[CHANNEL_VREF] = ADC_DMA_Buff[CHANNEL_VREF];
ADC_Average_Buff[CHANNEL_VBAT] = ADC_DMA_Buff[CHANNEL_VBAT];
ADC_Average_Buff[CHANNEL_CURRENT] = ADC_DMA_Buff[CHANNEL_CURRENT];
ADC_Average_Buff[CHANNEL_TEMPERATURE] = ADC_DMA_Buff[CHANNEL_TEMPERATURE];
ADC_Average_Buff[CHANNEL_VREF] += ADC_DMA_Buff[CHANNEL_VREF];
ADC_Average_Buff[CHANNEL_VBAT] += ADC_DMA_Buff[CHANNEL_VBAT];
ADC_Average_Buff[CHANNEL_CURRENT] += ADC_DMA_Buff[CHANNEL_CURRENT];
ADC_Average_Buff[CHANNEL_TEMPERATURE] += ADC_DMA_Buff[CHANNEL_TEMPERATURE];
//-------------------------------------------------------------
if (ADC_Samples >= ADC_SAMPLES - 1)
{
//------------------------------
// Voltage Reference calculation
if (ADC_Average_Buff[CHANNEL_VREF] > 0)
{
VoltageReference_Dig = (uint16_t) ADC_Average_Buff[CHANNEL_VREF] / ADC_SAMPLES;
VoltageReference = (uint16_t) __LL_ADC_CALC_VREFANALOG_VOLTAGE( VoltageReference_Dig, LL_ADC_RESOLUTION_12B);
}
else
{
VoltageReference = VDDA_APPLI;
// WARNING: Measure error, action: pending.
}
//------------------------------
// Voltage Battery calculation
if (ADC_Average_Buff[CHANNEL_VBAT] > 0)
{
VoltageBattery_Dig = (uint16_t) ADC_Average_Buff[CHANNEL_VBAT]/ ADC_SAMPLES;
VoltageBattery_Pin = (uint16_t) __LL_ADC_CALC_DATA_TO_VOLTAGE( VoltageReference, VoltageBattery_Dig,LL_ADC_RESOLUTION_12B);
ConversionFloat_Auxiliar = (float) (VoltageBattery_Pin);
if (ConversionFloat_Auxiliar > 0)
{
ConversionFloat_Auxiliar = ((((ConversionFloat_Auxiliar / 1000) / ADC_VBAT_R2) * (ADC_VBAT_R2 + ADC_VBAT_R1)) * 1000)+ ADC_VBAT_OFFSET;
//ConversionFloat_Auxiliar /= 1000;
}
else
{
ConversionFloat_Auxiliar = 0;
}
VoltageBattery = (uint16_t)ConversionFloat_Auxiliar;
}
else
{
// WARNING: Measure error, action: pending.
}
//------------------------------
// Current Motor calculation
if (ADC_Average_Buff[CHANNEL_CURRENT] > 0) // index == 1
{
VoltageMotorShunt_Dig = (uint16_t) ADC_Average_Buff[CHANNEL_CURRENT] / ADC_SAMPLES;
VoltageMotorShunt_Pin = (uint16_t) __LL_ADC_CALC_DATA_TO_VOLTAGE( VoltageReference, VoltageMotorShunt_Dig,
LL_ADC_RESOLUTION_12B);
ConversionFloat_Auxiliar = (float) (VoltageMotorShunt_Pin);
if (ConversionFloat_Auxiliar > 0)
{
ConversionFloat_Auxiliar = (((ConversionFloat_Auxiliar / 1000)/ ADC_SHUNT) * 1000) + ADC_MOTOR_SHUNT_OFFSET;
}
else
{
ConversionFloat_Auxiliar = 0;
}
CurrentMotor = ConversionFloat_Auxiliar;
}
else
{
// WARNING: Measure error, action: pending.
}
//------------------------------
// Temperature calculation
if (ADC_Average_Buff[CHANNEL_TEMPERATURE] > 0)
{
Temperature_Dig = (uint16_t) ADC_Average_Buff[CHANNEL_TEMPERATURE] / ADC_SAMPLES;
Temperature = 100*(int16_t) __LL_ADC_CALC_TEMPERATURE(VoltageReference, Temperature_Dig, LL_ADC_RESOLUTION_12B);
}
else
{
// WARNING: Measure error, action: pending.
}
//------------------------------
// Initialization buffers
ADC_Samples = 0;
ADC_Average_Buff[CHANNEL_VREF] = 0;
ADC_Average_Buff[CHANNEL_VBAT] = 0;
ADC_Average_Buff[CHANNEL_CURRENT] = 0;
ADC_Average_Buff[CHANNEL_TEMPERATURE] = 0;
//------------------------------
//------------------------------
}
else
{
ADC_Samples++;
}
} // End HAL_ADC_ConvCpltCallback
/* Public user code ---------------------------------------------------------*/
//------------------------------------------------------------------------------
/**
* @brief Return Voltage Battery.
* @PAram None
* @retval [uint16_t] [mV] Voltage Battery
*/
uint16_t ADC_Voltage_Battery_Get(void){
return VoltageBattery;
}// End Voltage_Battery_Get
//------------------------------------------------------------------------------
/**
* @brief Set Voltage Battery Virtual
* @PAram Value
*/
void HAL_ADC_Voltage_Battery_Virtual_Set(uint16_t Value){
VoltageBatteryVirtual=Value;
}// End HAL_ADC_Voltage_Battery_Virtual_Set
//------------------------------------------------------------------------------
/**
* @brief Return Current Motor.
* @PAram None
* @retval [uint16_t] [mA] Motor Current
*/
int16_t HAL_ADC_Current_Motor_Get(void){
return CurrentMotor;
}// End HAL_ADC_Current_Motor_Get
//------------------------------------------------------------------------------
/**
* @brief Set Current Motor Virtual
* @PAram Value
*/
void HAL_ADC_Current_Motor_Virtual_Set(int16_t Value){
CurrentMotorVirtual=Value;
}// End HAL_ADC_Current_Motor_Virtual_Set
//------------------------------------------------------------------------------
/**
* @brief Return Temperature Average.
* @PAram None
* @retval [ int16_t] [0.01ºC] Microcontroller temperature
*/
int16_t HAL_ADC_Temperature_Get(void){
return Temperature;
}// End HAL_ADC_Temperature_Get
//------------------------------------------------------------------------------
/**
* @brief Set Temperature Virtual
* @PAram Value
*/
void HAL_ADC_Temperature_Virtual_Set(int16_t Value){
TemperatureVirtual=Value;
}// End HAL_ADC_Temperature_Virtual_Set
/**
* @brief This function's role is to connect the ADC to the DMA and to indicate the dedicated buffer to do it.
*
*/
void MX_ADC1_Start(void){
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_DMA_Buff, ADC_CHANEL_NUMBER);
HAL_ADC_Start(&hadc1);
}// End MX_ADC1_Start
/**
* @brief This function's role is to initialise the ADC peripheral and how it should behave.
*/
void MX_ADC1_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
//------------------------------------------------------
//------------------------------------------------------
//Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV128;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 4;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;
hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc1) != HAL_OK){
Error_Handler();
}
// Configure Regular Channel
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
Error_Handler();
}
//Configure Regular Channel
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
Error_Handler();
}
// Configure Regular Channel
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
Error_Handler();
}
// Configure Regular Channel
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){
Error_Handler();
}
//------------------------------------------------------
}//End MX_ADC1_Init
And this is the new project that is unable to write or produce a valid ADC value.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
/* USER CODE BEGIN PV */
#define ADC_BUF_SIZE (uint8_t)4
#define TX_BUF_SIZE (uint8_t)64
#define RX_BUF_SIZE (uint8_t)64
volatile uint8_t uart_tx_buffer[TX_BUF_SIZE];
volatile uint8_t uart_rx_buffer[RX_BUF_SIZE];
volatile uint16_t adc_data_buffer[ADC_BUF_SIZE];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART2) {
// Tx complete, optionally signal application task
}
}
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART2) {
// Process first half of uart_rx_buffer
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART2) {
// Process second half of uart_rx_buffer
for(uint8_t c_i = 0 ; c_i < TX_BUF_SIZE; c_i++)
{
uart_tx_buffer[c_i] = '\0';
}
uart_tx_buffer[0] = 'c';
uart_tx_buffer[1] = 'a';
uart_tx_buffer[2] = 'c';
uart_tx_buffer[3] = 'a';
HAL_UART_Transmit_DMA(&huart2, uart_tx_buffer, 5);
}
}
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
if (hadc->Instance == ADC1) {
// Process first half of adc_data_buffer
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
if (hadc->Instance == ADC1) {
// Process second half of adc_data_buffer
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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 */
// Start UART RX DMA in circular mode
HAL_UART_Receive_DMA(&huart2, uart_rx_buffer, RX_BUF_SIZE);
// Start ADC DMA in circular mode
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_data_buffer, ADC_BUF_SIZE);
// If ADC is triggered by a timer:
// HAL_TIM_Base_Start(&htimx); // Or HAL_TIM_PWM_Start() if using PWM trigger
// For UART TX, you'll trigger it as needed:
// HAL_UART_Transmit_DMA(&huartx, uart_tx_buffer, tx_length);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief ADC1 Initialization Function
* @PAram None
* @retval None
*/
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV64;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 4;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;
hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
// Configure Regular Channel
// sConfig.Channel = ADC_CHANNEL_4;
// sConfig.Rank = ADC_REGULAR_RANK_1;
// sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
// Error_Handler();
// }
// //Configure Regular Channel
// sConfig.Channel = ADC_CHANNEL_10;
// sConfig.Rank = ADC_REGULAR_RANK_2;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
// Error_Handler();
// }
// // Configure Regular Channel
// sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
// sConfig.Rank = ADC_REGULAR_RANK_3;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
// Error_Handler();
// }
// // Configure Regular Channel
// sConfig.Channel = ADC_CHANNEL_VREFINT;
// sConfig.Rank = ADC_REGULAR_RANK_4;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
// Error_Handler();
// }
/* USER CODE END ADC1_Init 2 */
}
/**
* @brief USART2 Initialization Function
* @PAram None
* @retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
}
/**
* @brief GPIO Initialization Function
* @PAram None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @PAram file: pointer to the source file name
* @PAram line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
2025-06-17 3:22 AM
Solved!
HAL_ADC_Start(&hadc1); and HAL_ADCEx_Calibration_Start(&hadc1); were missing on the new firmware.
If the ADC is not callibrated it will return values like 82 and 83 instead of 0.