Skip to main content
Explorer
November 28, 2024
Solved

Can PWM settings affect other timer settings?

  • November 28, 2024
  • 2 replies
  • 1077 views

 

 

 

#include "Main.h"

#define MAX_Intensity 1600

static volatile uint16_t Intensity = 10;

void Timer4_Configuration(void)
{
	TIM_TimeBaseInitTypeDef TIM_BaseStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

	TIM_BaseStructure.TIM_Prescaler = 1 - 1;
	TIM_BaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_BaseStructure.TIM_Period = MAX_Intensity - 1;
	TIM_BaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM4, &TIM_BaseStructure);
	TIM_Cmd(TIM4, ENABLE);
}

void PWM_Configuration()
{
	TIM_OCInitTypeDef TIM_OCStructure;
	TIM_OCStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCStructure.TIM_Pulse = 0;

	TIM_OC1Init(TIM4, &TIM_OCStructure);
	TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);

	TIM_OC2Init(TIM4, &TIM_OCStructure);
	TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
	
	TIM_OC3Init(TIM4, &TIM_OCStructure);
	TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
	
	TIM_OC4Init(TIM4, &TIM_OCStructure);
	TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);

}

void GPIO_PWM_Configuration()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

	GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4);

	GPIO_InitStructure.GPIO_Pin = ALL_LEDS;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void TIM2_Configuration(u32 Intervalms)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

	TIM_TimeBaseStructure.TIM_Prescaler = 16000-1;
	TIM_TimeBaseStructure.TIM_Period 	 = Intervalms-1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	TIM_Cmd(TIM2, ENABLE);

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

	NVIC_Init(&NVIC_InitStructure);
}


int main(void)
{
	

	GPIO_PWM_Configuration();
 
	Timer4_Configuration();
	
	PWM_Configuration();
	
	TIM2_Configuration(500);
	
	while(1)
	{
	}
}



void TIM2_IRQHandler()
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
	{
		if(Intensity > MAX_Intensity)
		{
			Intensity = 10;
		}
		TIM4->CCR1 = Intensity;
		TIM4->CCR2 = Intensity;
		TIM4->CCR3 = Intensity;
		TIM4->CCR4 = Intensity;

		Intensity = Intensity * 2;
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

 

 

 

The code above is the example I am referring to. However, the Timer2 interrupt does not occur in this code. However, if you change the Timer2Configuration function call to before the PWM_Configuration function call, the interrupt operates normally. I can't find the cause of this behavior, so I'm asking a question.

i'm conducting practice using STM32F407G-DISC1.

 

    This topic has been closed for replies.
    Best answer by SabTuna
    int main(void)
    {
     GPIO_PWM_Configuration();
     TIM2_Configuration(500);
     Timer4_Configuration();
     PWM_Configuration();
     while(1)
     {
     }
    }

    Try like this.

    2 replies

    ST Employee
    November 28, 2024

    Hello @treeset, welcome to ST community, 

    I think that the part in the TIM2 configuration that makes it work is the NVIC configuration, it's mandatory to configure the NVIC before enabling interrupts 

    SabTunaAnswer
    Visitor II
    November 28, 2024
    int main(void)
    {
     GPIO_PWM_Configuration();
     TIM2_Configuration(500);
     Timer4_Configuration();
     PWM_Configuration();
     while(1)
     {
     }
    }

    Try like this.

    treesetAuthor
    Explorer
    November 29, 2024

    If you make this modification, PWM will operate normally. However, I think it is strange that it works normally even though I simply changed the calling order. Do you know what the cause is?

    Visitor II
    December 3, 2024

    The issue occurs because the NVIC_PriorityGroupConfig() function, which sets the interrupt priority grouping, must be called before any interrupt configurations; if you call PWM_Configuration() before TIM2_Configuration(), it's possible that PWM_Configuration() or functions it invokes alter the NVIC settings, overwriting the priority settings for TIM2 and preventing its interrupt from occurring; by moving the NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); call to the very beginning of main()—before any other configurations—you ensure that the priority grouping is set correctly before any interrupts are configured, which resolves the issue.