How the ADC works in F103RC
I've been confused for days and am unable to make the ADC work on F103RC and have to seek for help.
The test consists of ADC1 with 6 channels, an UART for printf and an I/O port that drives an LED.
The ADC configuration:





The test code:
/* USER CODE BEGIN PD */
#define DMA_NOT_COMPLETED 0
#define DMA_COMPLETED 1
#define DMA_NOT_STARTED 2
#define VREFINT_CHAN 0
#define TEMP_SENSOR_CHAN 1
/* USER CODE END PD */
/* USER CODE BEGIN PV */
uint8_t dmaTransferStatus = DMA_NOT_STARTED;
uint16_t convertedData[2] = { 0 };
int Vrefint =0;
int Tmcu = 0;
int Vsense = 0;
int tick = 0;
uint32_t startTick;
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
/* USER CODE END PFP */
int main(void)
{
HAL_Init();
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_UART5_Init();
/* USER CODE BEGIN 2 */
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)convertedData, 2);
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[VREFINT_CHAN] * 3300 / 4096;
Vsense = convertedData[TEMP_SENSOR_CHAN] * 3300 / 4096;
Tmcu = (1430 - Vsense) / 4.3 + 25;
dmaTransferStatus = DMA_NOT_STARTED;
printf("tick = %ds - Vrefint = %d Tmcu = %d\n", tick, Vrefint, Tmcu);
}
if ((HAL_GetTick() - startTick) > 1000)
{
tick++;
startTick = HAL_GetTick();
// if (dmaTransferStatus == DMA_NOT_STARTED)
{
convertedData[VREFINT_CHAN] = 0;
convertedData[TEMP_SENSOR_CHAN] = 0;
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)convertedData, 2);
dmaTransferStatus = DMA_NOT_COMPLETED;
}
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_15);
}
}
/* USER CODE END 3 */
}
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
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 = 6;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
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();
}
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();
}
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_3;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
static void MX_DMA_Init(void)
{
__HAL_RCC_DMA1_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
dmaTransferStatus = DMA_COMPLETED;
}
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart5, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 4 */
When call HAL_ADC_Start_DMA(&hadc1, (uint32_t *)convertedData, 2), It complets a conversion every 3 seconds:
tick = 0s - Vrefint = 1185 Tmcu = 34
tick = 3s - Vrefint = 1185 Tmcu = 34
tick = 6s - Vrefint = 1185 Tmcu = 34
tick = 9s - Vrefint = 1185 Tmcu = 34
tick = 12s - Vrefint = 1185 Tmcu = 34
tick = 15s - Vrefint = 1185 Tmcu = 34
tick = 18s - Vrefint = 1185 Tmcu = 34
Is this because the ADC only calls its complete- callback function when all 6 channels complete their conversions, so it needs to be triggered 3 times(each time two channnels get triggered), and the results presented are actually correct?
When call HAL_ADC_Start_DMA(&hadc1, (uint32_t *)convertedData, 6), the ADC calls its complete- callback function every second, and gave the following result which I completely don't have any clue:
tick = 0s - Vrefint = 1184 Tmcu = 34
tick = 1s - Vrefint = 1747 Tmcu = -28
tick = 2s - Vrefint = 1745 Tmcu = 81
tick = 3s - Vrefint = 1185 Tmcu = 34
tick = 4s - Vrefint = 1738 Tmcu = -26
tick = 5s - Vrefint = 1639 Tmcu = 81
tick = 6s - Vrefint = 1184 Tmcu = 34
tick = 7s - Vrefint = 1739 Tmcu = -26
tick = 8s - Vrefint = 1638 Tmcu = 81
tick = 9s - Vrefint = 1185 Tmcu = 34
tick = 10s - Vrefint = 1746 Tmcu = -27
tick = 11s - Vrefint = 1598 Tmcu = 81
tick = 12s - Vrefint = 1185 Tmcu = 34
tick = 13s - Vrefint = 1737 Tmcu = -25
tick = 14s - Vrefint = 1636 Tmcu = 81
tick = 15s - Vrefint = 1185 Tmcu = 34
tick = 16s - Vrefint = 1612 Tmcu = -41
tick = 17s - Vrefint = 1590 Tmcu = 81
tick = 18s - Vrefint = 1185 Tmcu = 34
tick = 19s - Vrefint = 1735 Tmcu = -25
tick = 20s - Vrefint = 1598 Tmcu = 81
tick = 21s - Vrefint = 1185 Tmcu = 34
tick = 22s - Vrefint = 1612 Tmcu = -41
tick = 23s - Vrefint = 1590 Tmcu = 81
tick = 24s - Vrefint = 1185 Tmcu = 34
tick = 25s - Vrefint = 1611 Tmcu = -41
tick = 26s - Vrefint = 1639 Tmcu = 81
tick = 27s - Vrefint = 1185 Tmcu = 34
tick = 28s - Vrefint = 1611 Tmcu = -41
tick = 29s - Vrefint = 1597 Tmcu = 81
tick = 30s - Vrefint = 1185 Tmcu = 34
The above result has a fixed pattern:
1. it repeats every 6 seconds
2. in the 6-second data patterns, the results from the 1st second and the 4th second are expected results
Uncomment the code at line 54, the result does not change.
Anyone could let me know anything wrong with my configuration or in my code? And what's happenning in the tests?
Any suggestions or replies would be highly appreciated.
Regards
Chao
