cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 DMA issue

zhaowhong
Associate III

Hello

My current requirement is to generate an FSK waveform with two frequencies around 3-5 MHz, a rate of about 700K, and output a square wave using PWM. The method involves switching frequencies by updating ARR and CCR using two timers—one for PWM output and the other for frequency switching (updating ARR and CCR). The main issue is updating ARR and CCR simultaneously since these addresses are not contiguous, and various methods tried have failed. See if the approach below works.

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)

{

if(htim_base->Instance==TIM1)

{

/* USER CODE BEGIN TIM1_MspInit 0 */

 

/* USER CODE END TIM1_MspInit 0 */

/* Peripheral clock enable */

__HAL_RCC_TIM1_CLK_ENABLE();

 

/* TIM1 DMA Init */

/* TIM1_TRIG Init */

hdma_tim1_trig.Instance = DMA1_Stream1;

hdma_tim1_trig.Init.Request = DMA_REQUEST_TIM1_TRIG;

hdma_tim1_trig.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_tim1_trig.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_tim1_trig.Init.MemInc = DMA_MINC_ENABLE;

hdma_tim1_trig.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

hdma_tim1_trig.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

hdma_tim1_trig.Init.Mode = DMA_CIRCULAR;

hdma_tim1_trig.Init.Priority = DMA_PRIORITY_VERY_HIGH;

hdma_tim1_trig.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

if (HAL_DMA_Init(&hdma_tim1_trig) != HAL_OK)

{

Error_Handler();

}

 

__HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_TRIGGER],hdma_tim1_trig);

 

/* USER CODE BEGIN TIM1_MspInit 1 */

/* 手动配置TIM1 CCR的DMA流 */

hdma_tim1_ccr.Instance = DMA1_Stream2;

hdma_tim1_ccr.Init.Request = DMA_REQUEST_TIM1_TRIG;

hdma_tim1_ccr.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_tim1_ccr.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_tim1_ccr.Init.MemInc = DMA_MINC_ENABLE;

hdma_tim1_ccr.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

hdma_tim1_ccr.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

hdma_tim1_ccr.Init.Mode = DMA_CIRCULAR;

hdma_tim1_ccr.Init.Priority = DMA_PRIORITY_VERY_HIGH;

hdma_tim1_ccr.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

if (HAL_DMA_Init(&hdma_tim1_ccr) != HAL_OK)

{

Error_Handler();

}

 

 

// 使能TIM3的触发DMA请求

TIM3->DIER |= TIM_DIER_TDE;

__HAL_LINKDMA(htim_base, hdma[TIM_DMA_ID_TRIGGER], hdma_tim1_ccr);

/* USER CODE END TIM1_MspInit 1 */

}
I use TIM3 as the master timer and TIM1 as the slave timer, with TIM3 triggering DMA.

Can the STM32H7 trigger two DMAs simultaneously with one event? I see that in STM32CubeIDE, it's one-to-one by default. Is it possible to manually add two DMA streams to modify ARR and CCR simultaneously?

 

6 REPLIES 6
AScha.3
Super User

Hi,

which H7 ? (there is more than one...)

If your H7 can...read in rm of it :

-- could use the dmamux , H743 ->

AScha3_0-1761222150278.png

-- in Cube see:

AScha3_1-1761222231126.png

-- or use MDMA :

AScha3_2-1761222285054.png

 

If you feel a post has answered your question, please click "Accept as Solution".
MasterT
Lead

What CCR value is? If its ARR/ 2, than use PWM output toggle, and update only ARR with /2 lower values (higher frequencies) 

yes

CCR value is  ARR/ 2,However, I need to update both ARR and CCR simultaneously. Despite trying various methods, I haven't achieved simultaneous updates of ARR and CCR, resulting in issues during the switching of the output square wave.

Hello  

What effect does this Setting?

I don't see a reason to use two DMA channels. Even some timers doesn't have x30 address assign (RCR), shouldn't be any issue to transfer "null-dummy" data.  Study this example.

 

Hello

My requirement is to output PWM with a 2μs timer update for ARR and CCR. I want ARR and CCR to update simultaneously, but after trying many approaches, I couldn't achieve simultaneous updates for ARR and CCR. Updating ARR and CCR inside the timer interrupt affects the current PWM output.

I considered using DMA, but DMA typically updates either ARR or CCR, and these two addresses are not contiguous. Are there any better solutions to achieve simultaneous updates for ARR and CCR?