cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L152 wrong time period of the pwm signal!

sommer2
Associate II
Posted on October 19, 2017 at 15:17

Hello

I use the STM32l152RCT6 Discovery-Board. I use the PWM over the DMA. Everything works well! But if I call my functionvStartDMA() 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 is2x time longer than the 0xFF pulse. Attached is a photo with the measuredPWMsignal. It should be a signal with 50% duty cycle.

0690X00000608hmQAA.png

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();
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

#dma-problem #timer-interrupts #tim-pwm-dma-stm32 #stm32l-discovery #pwm
3 REPLIES 3
Posted on October 19, 2017 at 17:01

The peripheral register is 16-bit wide, use appropriate buffers and DMA settings. For constant period use the Update as the trigger, not the phase you move around.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
sommer2
Associate II
Posted on October 20, 2017 at 10:33

Hello Clive One

Thank you for your reply. I changed the settings and the DMAbuffers to 16-bit.

What do you mean use the Update as the trigger? Is the following line not responsible for a constant period?

TimerInitStructure.TIM_Period = 0xFFFF;�?

How do I have to change the settings for the Update as the trigger?

Thanks

sommer2
Associate II
Posted on October 23, 2017 at 12:11

Can nobody help me?

Thanks in advance!