STM32F407 Analog Watchdog too slow
Hello, I am working on a project in which the AWD must react quickly (less than 500 us).
But when using the oscilloscope, it takes around 70 ms to react.
The project is big, so i can't give everything, but the ADC are configured like following :
uint32_t adc_value[4];
// Some code...
static void MX_ADC1_Init(void)
{
ADC_MultiModeTypeDef multimode;
ADC_InjectionConfTypeDef sConfigInjected;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/**Configure the ADC multi-mode
*/
multimode.Mode = ADC_DUALMODE_INJECSIMULT;
multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/**Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
*/
sConfigInjected.InjectedChannel = ADC_CHANNEL_14;
sConfigInjected.InjectedRank = 1;
sConfigInjected.InjectedNbrOfConversion = 3;
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONVEDGE_NONE;
sConfigInjected.ExternalTrigInjecConv = ADC_INJECTED_SOFTWARE_START;
sConfigInjected.AutoInjectedConv = DISABLE;
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
sConfigInjected.InjectedOffset = 0;
if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
*/
sConfigInjected.InjectedChannel = ADC_CHANNEL_7;
sConfigInjected.InjectedRank = 2;
if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
*/
sConfigInjected.InjectedChannel = ADC_CHANNEL_15;
sConfigInjected.InjectedRank = 3;
if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
static void MX_ADC2_Init(void)
{
ADC_AnalogWDGConfTypeDef AnalogWDGConfig;
ADC_InjectionConfTypeDef sConfigInjected;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc2.Init.Resolution = ADC_RESOLUTION_12B;
hadc2.Init.ScanConvMode = ENABLE;
hadc2.Init.ContinuousConvMode = ENABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
hadc2.Init.DMAContinuousRequests = DISABLE;
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
/* Configure the Analog Watchdog */
AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_INJEC;
AnalogWDGConfig.HighThreshold = 0x7FF;
AnalogWDGConfig.LowThreshold = 0x0;
AnalogWDGConfig.Channel = ADC_CHANNEL_6;
AnalogWDGConfig.ITMode = ENABLE;
if (HAL_ADC_AnalogWDGConfig(&hadc2, &AnalogWDGConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure the injected channel */
sConfigInjected.InjectedChannel = ADC_CHANNEL_6;
sConfigInjected.InjectedRank = 1;
sConfigInjected.InjectedNbrOfConversion = 1;
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONVEDGE_NONE;
sConfigInjected.ExternalTrigInjecConv = ADC_INJECTED_SOFTWARE_START;
sConfigInjected.AutoInjectedConv = ENABLE;
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
sConfigInjected.InjectedOffset = 0;
if (HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_ADCEx_InjectedStart(&hadc2);
HAL_ADC_Start_IT(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1, adc_value, sizeof(adc_value));
}What i want is to have the Analog watchdog always ready to call the interruption without the need to call a function every x us. (I know it's working, I tried, but calling a function more than 1000 times per second is a waste of resources and slow the program)
I already did some tests, I know the Analog Watchdog works, I enabled the continuous mode and for the ADC 2 the AutoInjectedConv (if I enable it on the ADC 1, the injected channels don't work anymore...), but the ADC doesn't seem to do a conversion just after the previous one finished or the Analog Watchdog doesn't constantly watch... I'm not sure what is the problem, but the reaction time is too slow...
I often read that something like this was possible, so I suppose it's my code which have a problem, something I don't do correctly...
If you have questions about something, just ask.