2022-01-04 04:15 AM
Hi folks,
I want to start ADC conversions on 2 regular channels of ADC1 block only after the voltage on one of the channels exceeds a certain limit, hence I'm using a watchdog feature.
After the watchdog will be triggered, I need to store 5 consequent values from each channel. Here is the relevant peace of code that I have so far:
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef *hadc)
{
HAL_ADC_Stop_IT(&hadc1); // stop watchdog interrupts
uint32_t adc_values[10] = {0};
HAL_ADC_Start_DMA(&hadc1, adc_values, 10); // read values from each channel after a watchdog has been triggered
HAL_ADC_Stop_DMA(&hadc1); // prevents continuous overwriting
uint32_t A4_val = 0;
uint32_t A5_val = 0;
A4_val = adc_values[1]; // values from channel A4
A5_val = adc_values[0]; // values from channel A5
printf("A4 channel value is %lu\n", A4_val);
printf("A5 channel value is %lu\n", A5_val);
A4_val = adc_values[3];
A5_val = adc_values[2];
printf("A4 channel value is %lu\n", A4_val);
printf("A5 channel value is %lu\n", A5_val);
A4_val = adc_values[5];
A5_val = adc_values[4];
printf("A4 channel value is %lu\n", A4_val);
printf("A5 channel value is %lu\n", A5_val);
A4_val = adc_values[7];
A5_val = adc_values[6];
printf("A4 channel value is %lu\n", A4_val);
printf("A5 channel value is %lu\n", A5_val);
A4_val = adc_values[9];
A5_val = adc_values[8];
printf("A4 channel value is %lu\n", A4_val);
printf("A5 channel value is %lu\n", A5_val);
printf("--------------\n");
}
The problem is that this code works only up to a certain Sampling Time value and if I increase it to the maximum, then DMA starts to confuse values between channels or even outputs 0s.
It looks like I'm missing something, could anyone tell me how to combine watchdog with DMA properly?
Solved! Go to Solution.
2022-01-04 05:26 AM
> HAL_ADC_Stop_DMA(&hadc1); // prevents continuous overwriting
You should wait until DMA stops itself (assuming you haven't set DMA to be circular).
It's not the best idea to printf() inside an interrupt.
JW
2022-01-04 05:26 AM
> HAL_ADC_Stop_DMA(&hadc1); // prevents continuous overwriting
You should wait until DMA stops itself (assuming you haven't set DMA to be circular).
It's not the best idea to printf() inside an interrupt.
JW
2022-01-04 06:03 AM
Thanks a lot. I've moved all the printing to the main while loop and configured DMA using HAL_ADC_ConvCpltCallback. That helped, thanks
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef *hadc)
{
if (Watchdog_enable)
{
HAL_ADC_Stop_IT(&hadc1); // stop watchdog interrupts
HAL_ADC_Start_DMA(&hadc1, adc_values, 10); // read values from each channel after a watchdog has been triggered
DMA_enable = TRUE; // allow DMA start
Watchdog_enable = FALSE; // disable subsequent watchdog interrupts
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (DMA_enable)
{
HAL_ADC_Stop_IT(&hadc1); // stop DMA interrupts
HAL_ADC_Stop_DMA(&hadc1); // prevents continuous DMA overwriting
Print_enable = TRUE; // allow printing the results
}
}