cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f103 adc dma hangs mcu

sarunas
Associate
Posted on July 26, 2016 at 15:19

Hello,

I ran into a problem when trying to configure ADC DMA on STM32F103 microcontroller. I am able to get the data from ADC, however I am unable to get into the main loop of the program. I tried changing ADC sample cycles and clock frequency, however, it did not help. If I stop dma interrupts, it works normally (not ADC of course). If I break the program it is always atvoid HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma). I guess it is always getting called and overloads the cpu. Here is the code of mine:


/* Includes ------------------------------------------------------------------*/

#include ''stm32f1xx_hal.h''


/* USER CODE BEGIN Includes */

/* USER CODE END Includes */


/* Private variables ---------------------------------------------------------*/

ADC_HandleTypeDef hadc1;

DMA_HandleTypeDef hdma_adc1;


/* USER CODE BEGIN PV */

/* USER CODE END PV */


/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_DMA_Init(void);

static void MX_ADC1_Init(void);


/* USER CODE BEGIN PFP */

/* USER CODE END PFP */


/* USER CODE BEGIN 0 */

__IO uint32_t ADC_val[2];

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);

int irl = 0;

/* USER CODE END 0 */


int main(void)

{


/* USER CODE BEGIN 1 */

/* USER CODE END 1 */


/* MCU Configuration----------------------------------------------------------*/


/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();


/* Configure the system clock */

SystemClock_Config();


/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_DMA_Init();

MX_ADC1_Init();


/* USER CODE BEGIN 2 */

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_val, 4);

HAL_ADC_Start_IT(&hadc1);

/* USER CODE END 2 */


/* Infinite loop */

/* USER CODE BEGIN WHILE */

while(1){ 

HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);

HAL_Delay(100);

HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);

HAL_Delay(100);

}

/* USER CODE END WHILE */


/* USER CODE BEGIN 3 */

/* USER CODE END 3 */


}


/** System Clock Configuration

*/

void SystemClock_Config(void)

{


RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

RCC_PeriphCLKInitTypeDef PeriphClkInit;


RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;

HAL_RCC_OscConfig(&RCC_OscInitStruct);


RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);


PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;

PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;

HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);


HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);


HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);


/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}


/* ADC1 init function */

void MX_ADC1_Init(void)

{


ADC_ChannelConfTypeDef sConfig;


/**Common config 

*/

hadc1.Instance = ADC1;

hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;

hadc1.Init.ContinuousConvMode = ENABLE;

hadc1.Init.DiscontinuousConvMode = DISABLE;

hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.NbrOfConversion = 2;

HAL_ADC_Init(&hadc1);


/**Configure Regular Channel 

*/

sConfig.Channel = ADC_CHANNEL_1;

sConfig.Rank = 1;

sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;

HAL_ADC_ConfigChannel(&hadc1, &sConfig);


/**Configure Regular Channel 

*/

sConfig.Channel = ADC_CHANNEL_2;

sConfig.Rank = 2;

HAL_ADC_ConfigChannel(&hadc1, &sConfig);


}


/** 

* Enable DMA controller clock

*/

void MX_DMA_Init(void) 

{

/* DMA controller clock enable */

__HAL_RCC_DMA1_CLK_ENABLE();


/* DMA interrupt init */

HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);


}


/** Configure pins as 

* Analog 

* Input 

* Output

* EVENT_OUT

* EXTI

*/

void MX_GPIO_Init(void)

{


GPIO_InitTypeDef GPIO_InitStruct;


/* GPIO Ports Clock Enable */

__GPIOD_CLK_ENABLE();

__GPIOA_CLK_ENABLE();

__GPIOB_CLK_ENABLE();


/*Configure GPIO pins : BUTTON1_Pin BUTTON2_Pin */

GPIO_InitStruct.Pin = BUTTON1_Pin|BUTTON2_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_PULLUP;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/*Configure GPIO pin : FREE_INPUT_Pin */

GPIO_InitStruct.Pin = FREE_INPUT_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(FREE_INPUT_GPIO_Port, &GPIO_InitStruct);


/*Configure GPIO pins : LED1_Pin LED2_Pin */

GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/*Configure GPIO pins : BUZZER_Pin FREE_OUTPUT_Pin */

GPIO_InitStruct.Pin = BUZZER_Pin|FREE_OUTPUT_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOB, LED1_Pin|LED2_Pin|BUZZER_Pin|FREE_OUTPUT_Pin, GPIO_PIN_RESET);


}


/* USER CODE BEGIN 4 */

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){




}

/* USER CODE END 4 */


#ifdef USE_FULL_ASSERT


/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t* file, uint32_t line)

{

/* USER CODE BEGIN 6 */

/* USER CODE END 6 */


}


#endif

and I include stm32cubemx picture of Clock configuration. I did only minor changes and also only in User Code space.
1 REPLY 1
Posted on July 26, 2016 at 18:17

If interrupts aren't cleared no foreground code execution will occur, ie it will continually tail-chain.

What is your estimated sample rate? 888 KHz? I'd suspect the processor to saturate at a few hundred KHz, lower with more baggage.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..