cancel
Showing results for 
Search instead for 
Did you mean: 

ADC with DMA is not working accurate(Low values) for Internal temperature sensor channel and VBAT channel, VREF with zephyr RTOS in STM32H7

DhirajThakur
Associate II

Hi,

we are using ADC with DMA for internal ADC channel like internal Temperature sensor, VBAT, VREF but we are facing issue related to accuracy please help me on this Configuration:

ADC channel:

   adc_channel_config_t ADC3_temp_config = {
        .channel       = ADC_CHANNEL_TEMPSENSOR,
        .rank          = ADC_REGULAR_RANK_8,
        .sampling_time = ADC_SAMPLETIME_810CYCLES_5,
    };
   adc_channel_config_t ADC3_vbat_config = {
        .channel       = ADC_CHANNEL_VBAT,
        .rank          = ADC_REGULAR_RANK_9,
        .sampling_time = ADC_SAMPLETIME_8CYCLES_5,
    };
        uC_AtoD_HAL::adc_channel_config_t ADC3_vref_config = {
        .channel       = ADC_CHANNEL_VREFINT,
        .rank          = ADC_REGULAR_RANK_10,
        .sampling_time = ADC_SAMPLETIME_8CYCLES_5,
};
 
DMA :
dma_channel_config_t ADC3_dma_config = {
        .channel = 2, // Channel 0 - ADC1, Channel 1 - ADC2, Channel 2 - ADC3, In H7 this parameter is used as a
                      // instance number
        .stream          = DMA1_Stream3,
        .src_data_width  = DMA_PDATAALIGN_WORD,
        .dest_data_width = DMA_MDATAALIGN_WORD
    };
 
ADC register for internal:
    ADC_Common_TypeDef *adc_common = ADC3_COMMON_REGISTER(pADC3Handler);
    adc_common->CCR |= ADC_CCR_TSEN | ADC_CCR_VREFEN | ADC_CCR_VBATEN;
 
Code:
For temperature:
#define TS_CAL1_TEMP 30.0f
#define TS_CAL2_TEMP 110.0f
#define TS_CAL1_ADDR ((uint16_t*)0x1FF1E820) // 30°C
#define TS_CAL2_ADDR ((uint16_t*)0x1FF1E840) // 110°C
uint16_t TS_CAL1 = *TS_CAL1_ADDR;
uint16_t TS_CAL2 = *TS_CAL2_ADDR;
LOG_DBG("TS_CAL1: %d, TS_CAL2: %d\n", TS_CAL1, TS_CAL2);
uint32_t TS_DATA = 0;
for (int i = 0; i < NUM_OF_CHANNEL_BUFFERS_ADC3; i++)
{
TS_DATA += MCUTemperature[i];
}
TS_DATA = TS_DATA / NUM_OF_CHANNEL_BUFFERS_ADC3;

float McuTemperature = 
(float_t)(((TS_CAL2_TEMP - TS_CAL1_TEMP) / (float_t)(TS_CAL2 - TS_CAL1)) * (TS_DATA - TS_CAL1)) + TS_CAL1_TEMP;
 
For Vref:
#define VREFIN_CAL ((uint16_t*)0x1FF1E860)
uint16_t Vrefin_Cal_Value = *VREFIN_CAL;
uint32_t VREF_DATA = 0;
for (int i = 0; i < NUM_OF_CHANNEL_BUFFERS_ADC3; i++)
{
VREF_DATA += Vrefint_volt[i];
}
VREF_DATA = VREF_DATA / NUM_OF_CHANNEL_BUFFERS_ADC3;
float vref = 3.3 * (Vrefin_Cal_Value /VREF_DATA );
vref = (vref / 65535) * VREF_DATA;
 
for Vbat:
    uint32_t Vbat_DATA = 0;
    for (int i = 0; i < NUM_OF_CHANNEL_BUFFERS_ADC3; i++)
    {
      Vbat_DATA += BatteryVoltage[i];
    }
    Vbat_DATA = Vbat_DATA / NUM_OF_CHANNEL_BUFFERS_ADC3;

   LOG_DBG("Vbat Raw count : %d\n",Vbat_DATA );

  BatteryVoltage = (Vbat_DATA * 4.0 * 3.3) / 65535.0;
 
Please let me know any configuration is miss 
Thanks in Advance
 


3 REPLIES 3
TDK
Super User

A few things:

  • Are you calibrating the ADC before using it? You need to.
  • What chip are you using?
  • What raw ADC values do you get?
  • What vbat//vrefint/temperature values do you get and, if not obvious, why do you think they're incorrect?
  • You're using 130 for the upper end temperature instead of 110 as the comments say.
If you feel a post has answered your question, please click "Accept as Solution".

Are you calibrating the ADC before using it? You need to.

ANS: Yes

What chip are you using?

ANS: STM32H743ZIVET6

What raw ADC values do you get?

ANS: During debugging we could read the below calibration values and ADC raw count.

TS_CAL2 = 16287, TS_CAL1 = 12805.

Temperature raw count = 2877

Vbat raw count = 2760

 

You're using 130 for the upper end temperature instead of 110 as the comments say.

ANS:

#define TS_CAL1_TEMP 30.0f
#define TS_CAL2_TEMP 110.0f
 
What vbat//vrefint/temperature values do you get and, if not obvious, why do you think they're incorrect?
ANS:
We are using 16bit ADC 
For temperature,

As per the Datasheet of STM32H743ZI, an internal MCU temperature sensor connected to ADC3_INP18 channel is factory calibrated and below are the calibration values stored into the MCU internal Flash.

DhirajThakur_0-1749794370052.jpeg

 

Below formula will be used for actual temperature calculation. Where TS_DATA is the actual temperature sensor output value converted by ADC. also mention this formula in code above 

DhirajThakur_1-1749794370053.jpeg

 

At room temperature, it is expected to get the value of TS_DATA between TS_CAL1 & TS_CAL2 or near around TS_CAL1.  But we are getting TS_DATA = 2877 & calculated temperature = -198.098

For Vbat,

ADC count for Vbat/4  = 2760, formula used to calculate battery volt = 4 * 3.3 * Vbat raw count / 65535 , where 4 is multiplying factor for ADC count Vbat /4,  3.3 V is VDDA, 65535 is for 16 bit ADC resolution.

Hence Calculated Vbat = 0.56V

Measured Vbat pin voltage on STM32H743ZI Nucleo board is 3.25V. 

 

Are you calibrating the ADC before using it? You need to.

ANS: Yes

What chip are you using?

ANS: STM32H743ZIVET6

What raw ADC values do you get?

ANS: During debugging we could read the below calibration values and ADC raw count.

TS_CAL2 = 16287, TS_CAL1 = 12805.

Temperature raw count = 2877

Vbat raw count = 2760

 

You're using 130 for the upper end temperature instead of 110 as the comments say.

ANS:

#define TS_CAL1_TEMP 30.0f
#define TS_CAL2_TEMP 110.0f
 
What vbat//vrefint/temperature values do you get and, if not obvious, why do you think they're incorrect?
ANS:
We are using 16bit ADC 
For temperature,

As per the Datasheet of STM32H743ZI, an internal MCU temperature sensor connected to ADC3_INP18 channel is factory calibrated and below are the calibration values stored into the MCU internal Flash.

DhirajThakur_0-1749796419620.jpeg

 

 

Below formula will be used for actual temperature calculation. Where TS_DATA is the actual temperature sensor output value converted by ADC. also mention this formula in code above 

DhirajThakur_1-1749796419603.jpeg

 

 

At room temperature, it is expected to get the value of TS_DATA between TS_CAL1 & TS_CAL2 or near around TS_CAL1.  But we are getting TS_DATA = 2877 & calculated temperature = -198.098

For Vbat,

ADC count for Vbat/4  = 2760, formula used to calculate battery volt = 4 * 3.3 * Vbat raw count / 65535 , where 4 is multiplying factor for ADC count Vbat /4,  3.3 V is VDDA, 65535 is for 16 bit ADC resolution.

Hence Calculated Vbat = 0.56V

Measured Vbat pin voltage on STM32H743ZI Nucleo board is 3.25V.