dpetican
dpetican

Reputation: 831

STM32L0 ADC Problem converting multiple channels using DMA

I'm trying to convert 3 ADC channels using DMA. But the variables don't seem to change when I watch them in the debugger. I know the conversion complete callback is executed because I breakpointed it. So this suggests that the DMA transfer is not executing and the buffer is not being filled. I'm using stm32cube to initialize my project. I've trimmed the generated code. Thanks.

ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;

uint32_t uwADC8ConvertedValue = 0;
uint32_t uwADC10ConvertedValue = 0;
uint32_t uwADC11ConvertedValue = 0;
uint32_t adcBuffer[3];

/* USER CODE BEGIN 0 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *AdcHandle) {
    uwADC8ConvertedValue = adcBuffer[0];
    uwADC10ConvertedValue = adcBuffer[1];
    uwADC11ConvertedValue = adcBuffer[2];
}
/* USER CODE END 0 */

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_RTC_Init();
  MX_ADC_Init();
  MX_USART2_UART_Init();
  MX_USART5_UART_Init();
  MX_TIM2_Init();

  /* USER CODE BEGIN 2 */
    HAL_TIM_Base_Start_IT(&htim2);
  HAL_ADC_Start_IT(&hadc);
    HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    HAL_UART_Transmit(&huart2, TxBuffer, 15, 5000);
  GPIO_PinState userPBstate = OFF;

    while (1)
  {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
        HAL_GPIO_TogglePin(MODEM_PW_GPIO_Port, MODEM_PW_Pin);
        HAL_GPIO_TogglePin(CAM1_LD_GPIO_Port, CAM1_LD_Pin);
        HAL_GPIO_TogglePin(CAM1_PW_GPIO_Port, CAM1_PW_Pin);
        HAL_Delay(100);

        userPBstate = HAL_GPIO_ReadPin(USER_PB_GPIO_Port, USER_PB_Pin);
        if (userPBstate == ON) {
            HAL_UART_Transmit(&huart2, (uint8_t *)"User button pressed!\n\r", 22, 5000);
        }
        else {
            HAL_UART_Transmit(&huart2, (uint8_t *)"User button NOT pressed!\n\r", 26, 5000);
        }

    }       
  /* USER CODE END 3 */

}

/* ADC init function */
static void MX_ADC_Init(void)
{

  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
    */
  hadc.Instance = ADC1;
  hadc.Init.OversamplingMode = DISABLE;
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ContinuousConvMode = ENABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.DMAContinuousRequests = ENABLE;
  hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerFrequencyMode = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure for the selected ADC regular channel to be converted. 
    */
  sConfig.Channel = ADC_CHANNEL_8;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure for the selected ADC regular channel to be converted. 
    */
  sConfig.Channel = ADC_CHANNEL_10;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure for the selected ADC regular channel to be converted. 
    */
  sConfig.Channel = ADC_CHANNEL_11;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/** 
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}

Upvotes: 0

Views: 2824

Answers (1)

unalignedmemoryaccess
unalignedmemoryaccess

Reputation: 7441

User custom code:

 /* USER CODE BEGIN 2 */
    HAL_TIM_Base_Start_IT(&htim2);
  HAL_ADC_Start_IT(&hadc);
    HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
  /* USER CODE END 2 */

should be:

 /* USER CODE BEGIN 2 */
    HAL_TIM_Base_Start_IT(&htim2);
    HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
  /* USER CODE END 2 */

If you want to use DMA mode, then do not use interrupt mode.

Upvotes: 2

Related Questions