AnsweredAssumed Answered

STM32F4 PWM+DMA problem

Question asked by zap.LX on Sep 19, 2013
Latest reply on Sep 19, 2013 by Clive One
Hello,
I've been trying to set up a 800kHz PWM signal with its duty cycles being transfered via DMA to the capture compare register. Well, it just doesn't work, not a single transfer is happening and I just can't figure out why.

Heres the code:

#include <stm32f4xx.h>
#include "main.h"
 
 
 
uint16_t timerValues[48];
 
int main(void)
{
 
 
 
    create_testpattern(); //fill timerValues[]
 
    init_DMA();
    init_TIM();
 
    userbutton_init();
 
    GPIO_SetBits(GPIOD, GPIO_Pin_13);
    while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)); //wait for user button
    GPIO_ResetBits(GPIOD, GPIO_Pin_13);
 
    TIM_Cmd(TIM3, ENABLE);
    DMA_Cmd(DMA1_Stream7, ENABLE);
    while(!DMA_GetCmdStatus(DMA1_Stream7)); //wait till stream is enabled
    TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE);
 
 
 
 
 
 
 
 
    while(1);
 
 
}
 
void DMA1_Stream7_IRQHandler(void) {
 
  DMA_ClearITPendingBit(DMA1_Stream7, DMA_IT_TCIF1);
  GPIO_SetBits(GPIOD, GPIO_Pin_13);
  DMA_Cmd(DMA1_Stream7, DISABLE);
 
}
 
void init_DMA(void){
 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
 
  DMA_InitTypeDef DMA_InitStruct;
 
  DMA_InitStruct.DMA_BufferSize       = 48;
  DMA_InitStruct.DMA_Channel         = DMA_Channel_5;
  DMA_InitStruct.DMA_DIR           = DMA_DIR_MemoryToPeripheral;
  DMA_InitStruct.DMA_FIFOMode       = DMA_FIFOMode_Disable;
  DMA_InitStruct.DMA_FIFOThreshold     = DMA_FIFOThreshold_HalfFull;
  DMA_InitStruct.DMA_Memory0BaseAddr     = (uint32_t)&timerValues[0];
  DMA_InitStruct.DMA_MemoryBurst       = DMA_MemoryBurst_Single;
  DMA_InitStruct.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
  DMA_InitStruct.DMA_MemoryInc       = DMA_MemoryInc_Enable;
  DMA_InitStruct.DMA_Mode         = DMA_Mode_Normal;
  DMA_InitStruct.DMA_PeripheralBaseAddr   = (uint32_t)&TIM3->CCR3 ;
  DMA_InitStruct.DMA_PeripheralDataSize   = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStruct.DMA_PeripheralInc     = DMA_PeripheralInc_Disable;
  DMA_InitStruct.DMA_Priority       = DMA_Priority_Medium;
 
  DMA_Init(DMA1_Stream7, &DMA_InitStruct);
 
  DMA_ITConfig(DMA1_Stream7, DMA_IT_TC, ENABLE);
 
 
}
 
 
void init_TIM(void){
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE);
 
  TIM_DeInit(TIM3);
 
  GPIO_InitTypeDef GPIO_InitStruct;
 
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
  GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);
 
 
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
 
  TIM_TimeBaseStruct.TIM_Prescaler = 0;
  TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStruct.TIM_Period = 103;
  TIM_TimeBaseStruct.TIM_ClockDivision = 0;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
 
  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
 
  TIM_OCInitTypeDef TIM_OCInitStruct;
 
  TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStruct.TIM_Pulse = 95;
  TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
  TIM_OCInitStruct.TIM_OutputNState = TIM_OutputState_Disable;
  TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High;
  TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  TIM_OC3Init(TIM3, &TIM_OCInitStruct);
 
 
  /* --- Interrupt DMA --- */
 
  NVIC_InitTypeDef NVIC_InitStructure;
 
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream7_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 
  NVIC_Init(&NVIC_InitStructure);
 
 
  TIM_DMACmd(TIM3, TIM_DMA_Update, DISABLE);
 
 
}

I am watching the signal with my logic analyzer after pressing the user button, but CCR3 always contains the pre-configured value (CCR3 = 95), there are no changes happening.

Any suggestions?

-Alex

Outcomes