1
#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);
}

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);
    }
}

int main(void)
{
    GPIO_PWM_Configuration();
            
    Timer4_Configuration();
    
        // Do not work
    PWM_Configuration();
    TIM2_Configuration(500);
    
        // Do work
    //TIM2_Configuration(500);
        //PWM_Configuration();
    
    while(1)
    {
    }
}


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 TIM2_Configuration 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.

STM32F407G-DISC1

I called the printf function for debugging, but an interrupt occurred in any order.

4
  • 2
    TIM_TimeBaseInitTypeDef TIM_BaseStructure; if you use local structures you need zero them before use as other fields may contain garbage values TIM_TimeBaseInitTypeDef TIM_BaseStructure = {}; Other structures as well. Commented Dec 6, 2024 at 9:56
  • Yuo need to clear the flag at the beginning of the interrupt handler as it has to propagate through the bus. If it does not - you will enter the interrupt again and again .... Commented Dec 6, 2024 at 9:58
  • The basic answer is no, one timer cannot mess with another. There is a chaining feature where one timer can send a signal to another to start or stop it etc, but the recipient has to be specifically configured to act on that. So you have some other problem. Commented Dec 6, 2024 at 10:14
  • @0___________ I would say that's probably the bug, or at least it is a bug - you could post that as the answer. Commented Dec 6, 2024 at 11:40

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.