2022-01-09 02:52 AM
Hey Guys,
I am working with the STM32L476RG Nucleo board (however my custom board has the L462 chip - I am hoping the solution will work for both chips) and I am trying to get multiple channels ADC interrupts to work without success.
My CubeMX setup is as follows:
My Code:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
p_value[indx] = HAL_ADC_GetValue(hadc);
indx = (indx + 1) % 2;
if((indx % 2) == 0) {
HAL_ADC_Start_IT(&hadc1);
}
}
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_USART2_UART_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
HAL_ADC_Start_IT(&hadc1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(5);
sprintf(msg, "ADC1: %hu\t\tADC2: %hu\r\n", p_value[0], p_value[1]);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
I am expecting to see the callback twice for each HAL_ADC_Start_IT() call but for some reason, it only calls it once. I am able to see only the first channel.
Any help is appreciated!
Thanks!
Almog
2022-01-09 06:36 AM
Update:
I have managed to read the two separate ADC1 channels by removing the HAL_ADC_Start_IT(&hadc1) at line 36 and placing it within the while(1) loop.
This method is semi-working in the way that I can see both channels behaving independently of each other which is what I wanted. However, now there is a different problem:
It looks like it's skipping an iteration.
I have 2 potentiometers connected to PC0 and PC1.
In my program, while changing the potentiometer value I can see that the one connected to PC1 (supposed to be channel 2) is changing p_value[0] and the other potentiometer on pin PC0 (supposed to be channel 1) is changing p_value[1].
CubeMX is configured that Channel 1 is rank 1 and Channel 2 is rank 2. If I understand correctly, the potentiometer connected to PC0 should be read first and placed in p_value[0] while the other potentiometer should be placed in p_value[1].
I can seem to find any resources that can help me configure my ADC to use interrupts with multiple channels.
As I understand it, while the ADC is in scan mode, once I call HAL_ADC_Start_IT(&hadc1), it does not stop until ALL channels have been read and after each channel, the EOC flag is up and an interrupt is called. Is that not the way?
Thanks for your help,
Almog
2022-01-09 07:58 AM
2.5 sampling cycles (plus conversion time) is not enough time for the CPU to interrupt and read out the value before the next conversion completes. Use DMA or a much slower sampling scheme.
2022-01-09 11:03 PM
Hey TDK,
Thanks for the reply.
Changing the sampling cycle count to 47.5 still produces the same results - One callback instead of 2 per HAL_ADC_Start_IT(&hadc1) call.
Is there anything else that needs to be changed?
Thanks
2022-01-09 11:08 PM
Hi @Community member ,
The STM32L4 ADC has only 1 data register (for ADC group regular), therefore when the ADC performs several successive conversions you have to fetch the data quickly enough before next data overwrites data registers.
Best regards
Philippe
2022-01-09 11:12 PM
Hi @ASter.2 (Community Member) ,
The STM32L4 ADC has only 1 data register (for ADC group regular), therefore when the ADC performs several successive conversions you have to fetch the data quickly enough before next data overwrites data registers.
You can find some examples in STM32L4 FW package:
Using ADC LL driver:
...\Firmware\Projects\NUCLEO-L476RG\Examples_LL\ADC\ADC_MultiChannelSingleConversion
Using ADC HAL driver:
...\Firmware\Projects\NUCLEO-L4R5ZI\Examples\ADC\ADC_Sequencer
Best regards
Philippe
2022-01-10 06:39 AM
Yes, use DMA or a much slower sampling scheme as suggested.