cancel
Showing results for 
Search instead for 
Did you mean: 

2 channels of DMA won't work

ap.1
Associate II

Hello, I'm trying to use 2channels of DMA , one for PWM in timer1 and one for reading adc1 using timer3 .

dma c2 should give ccr the amount from a uint string[1000](which i deleted from this code for simplifiing to be easier to read) and dma c1 for reading adc1 when timer3 update event acure but THE PROBLEM IS: dma works only either for pwm or for adc , with changing of prescale and arr of timer3 its change and work for other one if psc=719&arr=10 0 in timer3 only pwm work and if psc =11 and arr=200 only adc work , and if psc=60000 and arr=600 (wich i want this) none of the work whats the problem ??

p.s. both of them work perfectly if i dont start other one with hal_start_dma

#define AvarageNum 30
uint32_t adc_resualt[1*AvarageNum];
float sensor1,sensor2,sensor3,sensor4;

pwm on timer1 and adc with dam and timer3 start:

MX_GPIO_Init();
  MX_TIM3_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_TIM1_Init();
 
	HAL_TIM_Base_Start(&htim3); 
	HAL_ADC_Start_DMA(&hadc1,adc_resualt,AvarageNum);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,0);
	HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)1999, 1);
 
 
  while (1)
  {
			if (sensor1>2000){		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,1);
	}
	else{					HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,0);
	}
  }
  /* USER CODE END 3 */
}

timer 3 init :

static void MX_TIM3_Init(void)
{
 
  /* USER CODE BEGIN TIM3_Init 0 */
 
  /* USER CODE END TIM3_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
 
  /* USER CODE BEGIN TIM3_Init 1 */
 
  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 719;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 100;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */
 
  /* USER CODE END TIM3_Init 2 */
 
}

timer1 init:

static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
 
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

dma init:

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);
  /* DMA1_Channel2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 6, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
}

adc timer3 callback which read adc :

void	HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc3){
	uint32_t sum1=0 , sum2=0 , sum3=0 , sum4=0;
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,1);
	for(int i=0 ; i<AvarageNum ; i+=1){
		sum1+= adc_resualt[i];
	}
	sensor1=sum1/AvarageNum;
	}

1 ACCEPTED SOLUTION

Accepted Solutions
ap.1
Associate II

Hello for anyone wondering or having the same problem I did a step by step progress for writing code again and it did worked I think the problem was with either keil or some of my convertings in the code wasnt correct in c and keil didnt give me warning or error for them. both channel of dma work fine .

View solution in original post

6 REPLIES 6

No idea what STM32 part you're talking about.

Check the Reference Manual related to DMA units/channels and relationship to triggering sources.

ADC reads unlikely to be 32-bit wide.

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

stm32f103c8

I looked for it but couldn't find anything useful

LCE
Principal

Wasn't there something like:

put DMA_init function before timer init?

ap.1
Associate II

hi tnx for comment but I already tried that and its didn't work

You appear to try to use one timer (TIM3) for two different purposes (PWM generation using DMA, and ADC trigger).

It sounds plausible, but this may be the case when Cube gets into your way. This can be expected if you try to do anything out of normal, i.e. what you cannot click simply in CubeMX - individual pieces of Cube then may start to interact in an unexpected way.

You may be better off ditching Cube and writing your own program.

If you want to salvage the Cube one, start with reading and checking the DMA, TIM and ADC registers' content.

JW

ap.1
Associate II

Hello for anyone wondering or having the same problem I did a step by step progress for writing code again and it did worked I think the problem was with either keil or some of my convertings in the code wasnt correct in c and keil didnt give me warning or error for them. both channel of dma work fine .