STM32F103RC Wrong ADC Readings on Vrefint and TempSensor Channels
Hi,
The ADC test has only 2 channels: Vrefint and TempSensor. The following ADC result (convertedData) is read out through DMA:
tick = 1s - convertedData[0] = 113968573 convertedData[1] = 0
tick = 2s - convertedData[0] = 113837503 convertedData[1] = 0
tick = 3s - convertedData[0] = 96339657 convertedData[1] = 0
tick = 4s - convertedData[0] = 113837502 convertedData[1] = 0
tick = 5s - convertedData[0] = 113837503 convertedData[1] = 0
tick = 6s - convertedData[0] = 96405193 convertedData[1] = 0
tick = 7s - convertedData[0] = 113837503 convertedData[1] = 0
tick = 8s - convertedData[0] = 113837502 convertedData[1] = 0
tick = 9s - convertedData[0] = 96405192 convertedData[1] = 0 Where convertedData[0] is the ADC reading of Vrefint which should be 4095, the other is that of TempSensor which should not be 0.
The ADC configuration:



The code:
/* USER CODE BEGIN 2 */
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, convertedData, 2);
HAL_Delay(1);
startTick = HAL_GetTick();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (dmaTransferStatus == DMA_COMPLETED)
{
Vrefint = convertedData[0] * 3300 / 4095; /* VREF = VDDA = 3300mV */
Vsense = convertedData[1] * 3300 / 4095;
Tmcu = ((1430 - Vsense) / 4.3) + 25; /* Temperature (in °C) = {(V_25 - V_SENSE ) / Avg_Slope} + 25 */
dmaTransferStatus = DMA_NOT_STARTED;
}
if ((HAL_GetTick() - startTick) > 1000)
{
tick++;
startTick = HAL_GetTick();
printf("tick = %ds - convertedData[0] = %d convertedData[1] = %d\n",
tick, convertedData[0], convertedData[1]);
convertedData[0] = 0;
convertedData[1] = 0;
HAL_ADC_Start_DMA(&hadc1, convertedData, 2);
dmaTransferStatus = DMA_NOT_COMPLETED;
}
}
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
dmaTransferStatus = DMA_COMPLETED;
}
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart5, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 4 */
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 2;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_2;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
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);
}
Any suggestions and comments would be appreciated
Regards
Chao
