2017-10-19 06:17 AM
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.
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
2017-10-19 08:01 AM
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.
2017-10-20 01:33 AM
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
2017-10-23 03:11 AM
Can nobody help me?
Thanks in advance!