cancel
Showing results for 
Search instead for 
Did you mean: 

Functions in while loop are not working when ADC DMA conversion

AE104
Senior

Hello,

I successfully convert analog signals in to digital with ADC DMA mode. But when ADC is converting the analog signals, the functions in while loop are not working. It looks like that while loop is not operating. Do you have suggestions about the solution?

ADC Conversion:

volatile uint8_t convCompleted = 0;
 
int main(void)
...
	HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADCReadings_Evoked,50000);
 
	while(!convCompleted);
 
	HAL_ADC_Stop_DMA(&hadc1);
 
while (1)
 /* USER CODE BEGIN 3 */
		HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_RESET);
		HAL_Delay(1000);
		HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_SET);

7 REPLIES 7

Isn't the program looping in the

> while(!convCompleted);

?

I think so. How can I operate both while loops?

You can't. Don't wait in that loop.

JW

Do you have suggestions about the solution?

You use state machines. That's pretty standard method in microcontrollers, so you should be able to learn about it in books and courses (sorry I don't know any good starting point). Something like (a slightly exagerrated example):

enum {
  ADC_STATE_INIT,
  ADC_STATE_WAIT_CONVERSION,
  ADC_STATE_DONE,
} adcState = ADC_STATE_INIT;
 
enum {
  BLINKY_STATE_LOW,
  BLINKY_STATE_HIGH,
} blinkyState = BLINKY_STATE_LOW;
uint32_t blinkyT;
 
int main(void) {
  while(1) {
    switch(adcState) {
      case ADC_STATE_INIT:
        HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADCReadings_Evoked,50000);
        adcState = ADC_STATE_WAIT_CONVERSION;
        break;
      case ADC_STATE_WAIT_CONVERSION:
        if (convCompleted) {
          HAL_ADC_Stop_DMA(&hadc1);
          adcState = ADC_STATE_DONE;
        }
        break;
    }
    switch(blikyState) {
      case BLINKY_STATE_LOW:
        if (uint32_t_1ms_TickerVariable - blinkyT > 1000) {
          HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_SET);
          blinkyT = uint32_t_1ms_TickerVariable;
          blikyState = BLINKY_STATE_HIGH;
        }
        break;
      case BLINKY_STATE_HIGH:
        if (uint32_t_1ms_TickerVariable - blinkyT > 1000) {
          HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_RESET);
          blinkyT = uint32_t_1ms_TickerVariable;
          blikyState = BLINKY_STATE_LOW;
        }
        break;
    }
  }
}
 

You can use also a RTOS, exchanging perceived simplicity and coolness factor for memory and some performance loss.

JW

AE104
Senior

Thank you! Your state machine idea worked on the conversions. But it is still converting one at a time. I expect to get updated conversions in every cycle.

I don't know what do you want to achieve, and, quite honestly, I also don't care. Read the ADC and DMA chapters in RM and experiment - I'm talking about writing dozens of small test programs - to familiarise yourself with the hardware.

JW