AnsweredAssumed Answered

STM32L152 wrong time period of the pwm signal!

Question asked by sommer.remo on Oct 19, 2017
Latest reply on Oct 23, 2017 by sommer.remo

Hello 

 

I use the STM32l152RCT6 Discovery-Board. I use the PWM over the DMA. Everything works well! But if I call my function vStartDMA() with the PWM values 0xFF and 0x00 the result of the pwm pulses are wrong. The pwm pulse 0xFF is correct, but the pulse of the 0x00 value is 2x time longer than the 0xFF pulse. Attached is a photo with the measured PWM signal. It should be a signal with 50% duty cycle.

Do I have wrong settings from the DMA or the used timer? Where could be the problem?   

 

Thanks in advance!

Remo

void vInitPWM(void) {
     GPIO_InitTypeDef GPIO_InitStructure;
     TIM_TimeBaseInitTypeDef TimerInitStructure;
     TIM_OCInitTypeDef OutputChannelInit;
     NVIC_InitTypeDef NVIC_InitStructure;

     // GPIO
     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
     GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_TIM2);

     // TIMER
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
     TimerInitStructure.TIM_Prescaler = 0;
     TimerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TimerInitStructure.TIM_Period = 0xFFFF;
     TimerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
     TIM_TimeBaseInit(TIM2, &TimerInitStructure);

     //PWM CHANNEL

     OutputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
     OutputChannelInit.TIM_Pulse = 0;
     OutputChannelInit.TIM_OutputState = TIM_OutputState_Enable;
     OutputChannelInit.TIM_OCPolarity = TIM_OCPolarity_Low;

     TIM_OC4Init(TIM2, &OutputChannelInit);
     TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);

     TIM_ARRPreloadConfig(TIM2, ENABLE);
    
     TIM_CCxCmd(TIM2, TIM_Channel_4, TIM_CCx_Enable);
     TIM_Cmd(TIM2, ENABLE);
    
     // DMA
     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
     TIM_DMACmd(TIM2, TIM_DMA_CC4, ENABLE);
     DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);

     // NVIC for DMA
     NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
}

 

void vStartDMA(uint8_t *PtrDataToSend, uint16_t LengthOfData) {
     /* DMA Channel7 Configuration ----------------------------------------------*/
     DMA_InitTypeDef DMAInitStructure;

     if (!DMA_BUSY) {
          DMA_BUSY = TRUE;
          DMAInitStructure.DMA_DIR                               = DMA_DIR_PeripheralDST,
          DMAInitStructure.DMA_BufferSize                    = LengthOfData,
          DMAInitStructure.DMA_MemoryBaseAddr               = (uint32_t) PtrDataToSend,
          DMAInitStructure.DMA_MemoryDataSize           = DMA_MemoryDataSize_Byte,
          DMAInitStructure.DMA_MemoryInc                     = DMA_MemoryInc_Enable,
          DMAInitStructure.DMA_Mode                               = DMA_Mode_Normal,
          DMAInitStructure.DMA_PeripheralBaseAddr     = (uint32_t) & TIM2->CCR4,
          DMAInitStructure.DMA_PeripheralDataSize      = DMA_PeripheralDataSize_Byte,
          DMAInitStructure.DMA_PeripheralInc                = DMA_PeripheralInc_Disable,
          DMAInitStructure.DMA_Priority                     = DMA_Priority_VeryHigh,
          DMAInitStructure.DMA_M2M                               = DMA_M2M_Disable;

          DMA_Cmd(DMA1_Channel7, DISABLE);
          DMA_Init(DMA1_Channel7, &DMAInitStructure);
          DMA_Cmd(DMA1_Channel7, ENABLE);
          TIM_DMACmd(TIM2, TIM_DMA_CC4, ENABLE);
     }
}

 

void DMA1_Channel7_IRQHandler()
  {
       disableInterrupts();
      
    //NoInterrupts lock;
    DMA_ClearITPendingBit(DMA1_IT_TC7);
    DMA_Cmd(DMA1_Channel7, DISABLE);

    DMA_BUSY = FALSE;
       enableInterrupts();
  }

Attachments

Outcomes