cancel
Showing results for 
Search instead for 
Did you mean: 

TIM + ADC + DMA for Stm32f410rb

Malum.1
Associate

Hello, I would like to trigger a ADC conversion using a Timer and store the value using DMA. There are several examples online on how to do this but the common denomination in all the examples is that the ADC trigger is set to "Timer x Trigger out event" but the regular conversion mode for Stm32f410rb does not seem to have this. It only supports external trigger source by Timer 1 Capture Compare 1 event. The injected mode can be triggered by "Timer x Trigger out event" but it seems to not have support for DMA witch will be required for the application.

I don't know if the problem lies in the generation of the "Timer 1 Capture Compare 1 event" or if the event is for some reason is not triggering the ADC/DMA conversion/transfer.

If I understand the documentation somewhat correctly the "Timer 1 Capture Compare 1 event" is generated when the TIM1 CNT is equal to the counter register. And since the counter register is a constant value the events should come at a constant rate, but nothing seems to happen.

I have tried several different Settings for the Timers and ADC but i cant seem to understand what is wrong with it. Any help is greatly appreciated!

#define ADC_BUF_SIZE 8

uint16_t ADC_buffer[8];

/* USER CODE BEGIN 2 */

HAL_ADC_Start_DMA(&hadc1, (uint32_t*) ADC_buffer, ADC_BUF_SIZE);

HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);

HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_1);

HAL_TIM_Base_Start(&htim1);

static void MX_ADC1_Init(void) {

/* USER CODE BEGIN ADC1_Init 0 */

/* USER CODE END ADC1_Init 0 */

ADC_ChannelConfTypeDef sConfig = { 0 };

/* USER CODE BEGIN ADC1_Init 1 */

/* USER CODE END ADC1_Init 1 */

/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

*/

hadc1.Instance = ADC1;

hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

hadc1.Init.Resolution = ADC_RESOLUTION_12B;

hadc1.Init.ScanConvMode = DISABLE;

hadc1.Init.ContinuousConvMode = DISABLE;

hadc1.Init.DiscontinuousConvMode = DISABLE;

hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;

hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.NbrOfConversion = 1;

hadc1.Init.DMAContinuousRequests = ENABLE;

hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;

if (HAL_ADC_Init(&hadc1) != HAL_OK) {

Error_Handler();

}

sConfig.Channel = ADC_CHANNEL_8;

sConfig.Rank = 1;

sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {

Error_Handler();

}

/* USER CODE BEGIN ADC1_Init 2 */

/* USER CODE END ADC1_Init 2 */

}

/**

 * @brief TIM1 Initialization Function

 * @param None

 * @retval None

 */

static void MX_TIM1_Init(void) {

/* USER CODE BEGIN TIM1_Init 0 */

/* USER CODE END TIM1_Init 0 */

TIM_ClockConfigTypeDef sClockSourceConfig = { 0 };

TIM_MasterConfigTypeDef sMasterConfig = { 0 };

TIM_OC_InitTypeDef sConfigOC = { 0 };

TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = { 0 };

/* USER CODE BEGIN TIM1_Init 1 */

/* USER CODE END TIM1_Init 1 */

htim1.Instance = TIM1;

htim1.Init.Prescaler = 50000;

htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

htim1.Init.Period = 10000;

htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim1.Init.RepetitionCounter = 0;

htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

if (HAL_TIM_Base_Init(&htim1) != HAL_OK) {

Error_Handler();

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) {

Error_Handler();

}

if (HAL_TIM_OC_Init(&htim1) != HAL_OK) {

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig)

!= HAL_OK) {

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_TIMING;

sConfigOC.Pulse = 10;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {

Error_Handler();

}

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

sBreakDeadTimeConfig.DeadTime = 0;

sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig)

!= HAL_OK) {

Error_Handler();

}

/* USER CODE BEGIN TIM1_Init 2 */

/* USER CODE END TIM1_Init 2 */

}

/**

 * Enable DMA controller clock

 */

static void MX_DMA_Init(void) {

/* DMA controller clock enable */

__HAL_RCC_DMA2_CLK_ENABLE();

/* DMA interrupt init */

/* DMA2_Stream0_IRQn interrupt configuration */

HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

}

1 REPLY 1

Check if TIM1_BDTR.MOE is set.

JW