Skip to main content
JFRAN.1
Associate
May 14, 2021
Solved

Hi, I have an application with STM32G431RB, using both ADCs. How can I tell which one of the two ADCs called an interruption like this: void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)

  • May 14, 2021
  • 5 replies
  • 1546 views

..

This topic has been closed for replies.
Best answer by JFRAN.1

Hello, thanks a lot for your answers, I implement it in a different way with your recommendations and is now working fine:

void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)

{

// Voltage1 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2); // L1 VOLTAGE

if (hadc->Instance == ADC1)

{

Line1[0] += ADC1->JDR1; // Gets L1 Current. ADC1 Channel 1. PA0 pin

Line1[1] += ADC1->JDR2; // Gets L1 Voltage. ADC1 Channel 9. PC3 pin

Line1[2] += ADC1->JDR3; // Gets IGBT Temperature. ADC1 Channel 7. PC1 pin

Line1[3] += ADC1->JDR4; // Gets BUS Voltage. ADC1 Channel 2. PA1 pin

samples1++;

if (samples1 >= L1_SAMP)

{

samples1 = 0;

CalcLine1AVG();

}

HAL_ADCEx_InjectedStop_IT(&hadc1);

}

else if (hadc->Instance == ADC2)

{

Line2[0] += ADC2->JDR1; // Gets L1 Voltage. ADC1 Channel 9. PC3 pin

HAL_ADCEx_InjectedStop_IT(&hadc2);

samples2++;

if (samples2 >= L2_SAMP)

{

samples2 = 0;

CalcLine2AVG();

}

}

}

5 replies

TDK
May 14, 2021

Check if the value of hadc->Instance is ADC1 or ADC2.

"If you feel a post has answered your question, please click ""Accept as Solution""."
JFRAN.1
JFRAN.1Author
Associate
May 14, 2021

Hello TDK, thanks a lot for your answer, I don'T know what is wrong or if I didn't undestood you; but I tried what you said and it didn't worked. ADC1 is triggered with a PWM signal generated by timer 1 and ADC2 is is triggered with a PWM signal generated by timer 8. I have something like this:

HAL_ADCEx_InjectedStart_IT(&hadc1); // Enables ADC1 to start convertion when timer 1 triggered it

HAL_ADCEx_InjectedStart_IT(&hadc2); // Enables ADC2 to start convertion when timer 8 triggered it

void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)

{

HAL_UART_Transmit_IT(&huart2, "CALLED \r\n", 9); //Just to know if enters here

if (hadc->Instance == ADC1)

{

Line1[0] += ADC1->JDR1; // Gets L1 Current. ADC1 Channel 1. PA0 pin

Line1[1] += ADC1->JDR2; // Gets L1 Voltage. ADC1 Channel 9. PC3 pin

Line1[2] += ADC1->JDR3; // Gets IGBT Temperature. ADC1 Channel 7. PC1 pin

samples1++;

HAL_UART_Transmit_IT(&huart2, "PROCESSED1\r\n", 11); //Just to know if enters here

HAL_ADCEx_InjectedStop_IT(&hadc1);

}

else if (hadc->Instance == ADC2)

{

Line2[0] += ADC2 ->JDR1; // Gets L1 Current. ADC1 Channel 1. PA0 pin

Line2[1] += ADC2->JDR2; // Gets L1 Voltage. ADC1 Channel 9. PC3 pin

samples2++;

HAL_UART_Transmit_IT(&huart2, "PROCESSED2\r\n", 11); //Just to know if enters here

HAL_ADCEx_InjectedStop_IT(&hadc1);

}

}

I have a signal connected to EXTI15 to simulate. When I run the code it prints "CALLED". It indicates that injected conversion was complete. But never prints "PROCESSED1", neither "PROCESSED2". If I take out the if statement: if (hadc->Instance == ADC1)

it works fine (and I can see the converted values), but I need some way to know wich one of the two ADCs called the interruption.

TDK
May 14, 2021

That is what I suggested.

> It didn't worked.

> But never prints "PROCESSED1", neither "PROCESSED2" 

If by "didn't worked" you mean it's not outputting PROCESSED1 or PROCESSED2:

You're calling HAL_UART_Transmit_IT multiple times in succession. The later ones have no effect because the peripheral is still busy processing the first call. You could use blocking mode instead but doing long things within an interrupt is not ideal.

Use a better method to determine what the code is doing. Set a breakpoint in HAL_ADCEx_InjectedConvCpltCallback and step through. Verify hadc->Instance refers to ADC1 or ADC2.

Also:

else if (hadc->Instance == ADC2)
{
...
HAL_ADCEx_InjectedStop_IT(&hadc1);
}

You're using the wrong hadc here, which suggests it either isn't needed or your code won't work the way you intend.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Piranha
Principal III
May 15, 2021

And if ADC1 and ADC2 have different interrupt priorities or UART functions are also called from any other interrupt with different priority, then, because HAL bloatware is not interrupt safe, such code will mess up UART state completely...

JFRAN.1
JFRAN.1AuthorBest answer
Associate
May 18, 2021

Hello, thanks a lot for your answers, I implement it in a different way with your recommendations and is now working fine:

void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)

{

// Voltage1 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2); // L1 VOLTAGE

if (hadc->Instance == ADC1)

{

Line1[0] += ADC1->JDR1; // Gets L1 Current. ADC1 Channel 1. PA0 pin

Line1[1] += ADC1->JDR2; // Gets L1 Voltage. ADC1 Channel 9. PC3 pin

Line1[2] += ADC1->JDR3; // Gets IGBT Temperature. ADC1 Channel 7. PC1 pin

Line1[3] += ADC1->JDR4; // Gets BUS Voltage. ADC1 Channel 2. PA1 pin

samples1++;

if (samples1 >= L1_SAMP)

{

samples1 = 0;

CalcLine1AVG();

}

HAL_ADCEx_InjectedStop_IT(&hadc1);

}

else if (hadc->Instance == ADC2)

{

Line2[0] += ADC2->JDR1; // Gets L1 Voltage. ADC1 Channel 9. PC3 pin

HAL_ADCEx_InjectedStop_IT(&hadc2);

samples2++;

if (samples2 >= L2_SAMP)

{

samples2 = 0;

CalcLine2AVG();

}

}

}