AnsweredAssumed Answered

Timer3 not working on STM32F4

Question asked by Jean Paul Talledo Vilela on Sep 25, 2017
Latest reply on Sep 25, 2017 by Jive Tihs

Hi

I am using extensive use of timers on my project. Currently Timer1 works with Timer 8 in Master/Slave Mode, Timer2 also is the trigger for ADC /DMA Reads, Timer4,5,7, are using for timing purposes.

 

Currently I am adding Timer 3 to work similar to Timer 8, be triggered by Timer 1 but I am not able to get the Timer 3 to work as expected. When debugging, I can see Timer3 contents are always 0 after calling the Std Library Timer Functions. I am looking at address 0x40000400.  All the register including the configuration for PWM output are zero when I access the Watch Window on my IAR Compiler environment.

 

Here is the code to configure Timer 1,8 and 3.

 

    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure1;
    TIM_OCInitTypeDef  TIM_OCInitStructure1;
    
    // TIM1 clock enable
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
 
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    
    //Changing Interrupt on Up Count
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2;
    TIM_TimeBaseStructure.TIM_Period = pwmPeriodCnt;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
 
    // Timer config:
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // just enables outputs
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0; // initial CCRx value
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // here, High means OC is active-high
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; // both should go low assuming OCPolarity is active high
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
    
    // must init all three OCx units
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    
      
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;  //TIM_OCMode_PWM1; // PWM1: OC active if CNT < CCR; PWM2: OC active if CNT >= CCR
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // just enables outputs
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // no N channel
    TIM_OCInitStructure.TIM_Pulse = 0;   //pwmPeriodCnt; // default; this will go off half way through - at the center of the on pulse
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // here, High means OC is active-high
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; // both should go low assuming OCPolarity is active high
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
       TIM_OC4Init(TIM1, &TIM_OCInitStructure);
        

 

    /* Automatic Output enable, Break, dead time and lock configuration*/
    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; // off state in run mode (MOE=1) - we want Enable
    TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; // off state in disable mode (MOE=0) - we want Enable
    TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; // may want to play with this for safety - otherwise, leave off - see spec
    TIM_BDTRInitStructure.TIM_DeadTime = 0; // this value is funky - call WriteDeadTime() below to set actual DT
    TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; // BDTR_BKE bit; not using
    TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; // BDTR_BKP bit - set High if break (stop outputs) is active low
    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; // this MUST be Disable; if not, after disabling outputs, they may automatically re-enable
    
    TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

 

    // update DT setting - above DT setup is just place holder
    UpdateDeadTime(deadTime);
    
    // setup TIM1 trigger output
    TIM_SelectOutputTrigger( TIM1, TIM_TRGOSource_Update );
    TIM_SelectMasterSlaveMode( TIM1, TIM_MasterSlaveMode_Enable );
    
    // prevent updating CCR regs while running (generates runt pulses)
    TIM_CCPreloadControl(TIM1, ENABLE);
    
    
    
    ////////////////////////// TIM8 SETUP ////////////////////////////////////////
    
    

 

    // setup TIM8 first, then cofigure trigger -

 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = pwmPeriodCnt*2-2;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
    
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //TIM_OCMode_Toggle;  
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // just enables outputs
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // no N channel
    TIM_OCInitStructure.TIM_Pulse = pwmPeriodCnt;  //1343; //pwmPeriodCnt;   //pwmPeriodCnt; // default; this will go off half way through - at the center of the on pulse
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // here, High means OC is active-high
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; // both should go low assuming OCPolarity is active high
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
       TIM_OC2Init(TIM8, &TIM_OCInitStructure); // note that we're using CC2 of TIM8 - this is b/c only CC2-CC4 of TIM8 can be used for the injected channel trigger
    
    // setup for singel shot mode
    TIM_SelectOnePulseMode( TIM8, TIM_OPMode_Single );
    
    // setup TIM8 as slave with trigger; note: if TIM8 slave triggers on TIM1 master, then we
    // need to select ITR0 - see table 70 on pg 396 of the chip manual.
    TIM_SelectInputTrigger( TIM8, TIM_TS_ITR0 ); // selects TIM1 as trigger
    TIM_SelectSlaveMode( TIM8, TIM_SlaveMode_Trigger ); // The counter starts at a rising edge of the trigger TRGI
    
    // enable outputs (may not be needed unless using PC7 debug pin but test if removing
    // this call - may also control output trigger to ADC...?)
    TIM_CtrlPWMOutputs(TIM8, ENABLE);
        
        
        
        
        
    //Timer 3 Setup
    // setup TIM3 first, then cofigure trigger - note: TIM3 CH1 can be probed on PA6
    // if setup for it - this has been implemented, but may be commented out.
    RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure1);
    TIM_TimeBaseStructure1.TIM_Prescaler = 0;
    TIM_TimeBaseStructure1.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure1.TIM_Period = pwmPeriodCnt*2-2; //
    TIM_TimeBaseStructure1.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure1.TIM_RepetitionCounter = 0;
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure1);
    
    
        
    TIM_OCInitStructure1.TIM_OCMode = TIM_OCMode_PWM1;  //TIM_OCMode_Toggle;  //TIM_OCMode_PWM1; // PWM1: OC active if CNT < CCR; PWM2: OC active if CNT >= CCR
    TIM_OCInitStructure1.TIM_OutputState = TIM_OutputState_Enable; // just enables outputs
    TIM_OCInitStructure1.TIM_OutputNState = TIM_OutputNState_Disable; // no N channel
    TIM_OCInitStructure1.TIM_Pulse = pwmPeriodCnt;  //1343; //pwmPeriodCnt;   //pwmPeriodCnt; // default; this will go off half way through - at the center of the on pulse
    TIM_OCInitStructure1.TIM_OCPolarity = TIM_OCPolarity_High; // here, High means OC is active-high
    TIM_OCInitStructure1.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStructure1.TIM_OCIdleState = TIM_OCIdleState_Reset; // both should go low assuming OCPolarity is active high
    TIM_OCInitStructure1.TIM_OCNIdleState = TIM_OCIdleState_Reset;
       TIM_OC1Init(TIM3, &TIM_OCInitStructure1);
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    
    // setup for singel shot mode
    TIM_SelectOnePulseMode( TIM3, TIM_OPMode_Single );
    
    // setup TIM3 as slave with trigger; note: if TIM3 slave triggers on TIM1 master, then we
    TIM_SelectInputTrigger( TIM3, TIM_TS_ITR0 ); // selects TIM1 as trigger
    TIM_SelectSlaveMode( TIM3, TIM_SlaveMode_Trigger ); // The counter starts at a rising edge of the trigger TRGI
    TIM_ARRPreloadConfig(TIM3, ENABLE);

Outcomes