AnsweredAssumed Answered

STM32 while loop problem (using ADC DMA)

Question asked by Maxime Benchemoul on Feb 20, 2018
Latest reply on Feb 20, 2018 by AvaTar

Hi everyone,

 

I'm trying to get working a very simple program on my Nucleo STM32L452RE-P but I have some unexpected problems...

I'm using CubeMX with Atollic TrueStudio V9.0. I configured the ADC in DMA mode and also the DAC in DMA mode. The aim: read values on the ADC and write them on the DAC.

 

Basically, my main.c looks like:

 

#define ADC1_Buffer_Size ((uint32_t) 8192)
#define DAC1_Buffer_Size ((uint32_t) 8192)

 

uint32_t ADC1_Buffer[ADC1_Buffer_Size];
uint8_t flag_adc_complete = 0;
uint8_t flag_adc_calibration = 0;
uint8_t flag_init = 0;
uint8_t flag_while = 0;
uint8_t flag_callback = 0;
uint8_t incr = 0;

 

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_DAC1_Init(void);
static void MX_TIM6_Init(void);

 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
   flag_callback = 1;
   flag_adc_complete = 1;
   HAL_ADC_Stop_DMA(&hadc1);
   HAL_TIM_Base_Start(&htim6);
   HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);
   HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, ADC1_Buffer, ADC1_Buffer_Size, DAC_ALIGN_12B_R);
   flag_callback = 0;
}

 

int main(void)
{
   flag_init = 1;
   HAL_Init();
   SystemClock_Config();
   MX_GPIO_Init();
   MX_DMA_Init();
   MX_ADC1_Init();
   MX_DAC1_Init();
   MX_TIM6_Init();

   flag_adc_calibration = 1;
   if(HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK){
      Error_Handler();
   }
   flag_adc_calibration = 0;

   if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC1_Buffer, ADC1_Buffer_Size) != HAL_OK){
      Error_Handler();
   }

   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
   HAL_Delay(1000);
   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);

   flag_init = 0;
   while (1)
   {
      flag_while = 1;
      if(flag_adc_complete == 1){
         while(incr < 255){
            incr++;
         }
         incr = 0;
         flag_adc_complete = 0;
      }
      flag_while = 0;
   }
}

 

At the beginning, I tried this program without anything in the while loop and the program worked well: after filling ADC1_Buffer once, the values were written on the DAC continuously. I checked it on an oscilloscope.

 

Then I wanted to read the buffer using STM Studio. I add a for loop inside the main while(1) loop to read each item of the buffer through a temporary variable but it didn't work. So I removed the code because I thought I was doing it wrong...

Then I add this small counter which increment the incr variable up to 255, only to debug the program.

I expected to visualize this counter on STM Studio and I realized that my program didn't go in the main while(1) loop.

 

Actually, I got the impression that the program acts really weirdly. As you can see I put many flags to check the evolution of the program on STM Studio. 

flag_init is set to 1 when I reset the board and is never reset.

flag_adc_complete is set to 1 quickly (too quickly...) after reseting the board and is never reset.

flag_adc_calibration and flag_callback are never set to 1.

flag_while is unadressed.

incr is not incremented.

 

However the LED (GPIOB, PIN13 set during 1000ms before the while) works well...

 

If someone can help me, it could be very nice. I'm going mad, it should not be as complicated...

Do you think it could be a problem with STM Studio? In CubeMX I activated the debug "trace asynchronous sw". In STM Studio I selected ST-Link SWD and I display all data and acquire only variables used by visible viewers. All the other settings are let by default.

 

Thank you very much!!

 

Maxime

Outcomes