Question
STM32H7 + Zephyr: ADC + DMA giving wrong (low) values for Internal temperature, VBAT, VREF
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;
#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;
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
