1
\$\begingroup\$

I am using STM32F030F4P6 when I call this Function my ADC starts successfully and I can read ADC value in ADC callback but my MCU hangs at this function line what is the problem? My code is generated by st32mcubemx and my IDE is IAR. I have a problem with this line. My program print "OK1" and ADC run successfully but my MCU doesn't print "OK2". This is a part of my main code generated by cubeMX:

  /* USER CODE BEGIN 2 */  
  uint8_t ret;
  printf("OK1!\r\n");
  ret = HAL_ADC_Start_IT(&hadc);
  if(ret != HAL_OK) printf("ERROR Start ADC\r\n");
  else printf("ADC start sucess!\r\n");
  printf("OK2!\r\n");
  /* USER CODE END 2 */

And this is my ADC init:

/* Includes ------------------------------------------------------------------*/
#include "adc.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

ADC_HandleTypeDef hadc;

/* ADC init function */
void MX_ADC_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};

  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
  */
    hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  hadc.Init.ContinuousConvMode = ENABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */
    /* ADC1 clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**ADC GPIO Configuration    
    PA4     ------> ADC_IN4 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* ADC1 interrupt Init */
    HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(ADC1_IRQn);
  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  }
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{

  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspDeInit 0 */

  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC1_CLK_DISABLE();

    /**ADC GPIO Configuration    
    PA4     ------> ADC_IN4 
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4);

    /* ADC1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(ADC1_IRQn);
  /* USER CODE BEGIN ADC1_MspDeInit 1 */

  /* USER CODE END ADC1_MspDeInit 1 */
  }
} 

This is my adc callback:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  if(hadc->Instance == ADC1)
  {
    adc_val = HAL_ADC_GetValue(hadc);
    Vin = adc_val*0.001;
    printf("ADC val:%d Vin:%f\r\n",adc_val,Vin);
  }
}

And this is my error callback: At this, I receive ADC ERR:2 means HAL_ADC_ERROR_OVR I am getting the ADC value in callback but this happen.

void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
{
  uint32_t adc_error;
  printf("ADC ERR:%d\r\n",hadc->ErrorCode);
}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Your callback functions are being called from the ADC interrupt. It's almost certain that you can't do printf from an interrupt, and that's what's causing your code to hang. \$\endgroup\$
    – brhans
    Dec 25 '19 at 7:56
  • \$\begingroup\$ OK, when I comment on the printf and get the result in the live watch window my MCU hangs too. \$\endgroup\$
    – OnlyStar
    Dec 25 '19 at 9:41
  • 1
    \$\begingroup\$ Time to add some Breakpoints and step through the code? \$\endgroup\$
    – Tyler
    Dec 25 '19 at 13:54
0
\$\begingroup\$

What happens is that the printf in the conversion completion callback is still printing when the next interrupt happens so it can't execute until printf is done and therefore the result is not read in time and overrun happens. So it is usually not a good idea to call printf in an interrupt context, unless you have written it yourself to make it re-entrant and make it write to a buffer, and still it might be too slow.

\$\endgroup\$
1
  • \$\begingroup\$ OK, when I comment on the printf and get the result in the live watch window my MCU hangs too. \$\endgroup\$
    – OnlyStar
    Dec 25 '19 at 9:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.