AnsweredAssumed Answered

Problem with timer initialization (TIM1)

Question asked by dan on Sep 4, 2015
Latest reply on Sep 15, 2015 by dan
Dear all,

I want to use TIM1 CH3N  to drive a buzzer with different frequencies. I have tried to program TIM1 on channel 3N as below (the corresponding pin is already configured as AF_PP at 50 MHz):



void buzz(uint32_t freq, uint32_t t, uint32_t duty_cycle) {
  // Turn on peripheral clock for the buzzer only when it is needed.
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

  // Initialize the timer TIM1 on channel 3N timer with the given frequency
  // and duty cycle.
  TIM_TimeBaseInitTypeDef TIM_InitStruct;
  TIM_OCInitTypeDef TIM_OCStruct;
  TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

  // Reset all timers to their default values.
  TIM_DeInit(TIM1);

  uint32_t period = 0;

  if (freq == 0)
    // DC is not allowed, so just assume frequency is 1Hz.
    period = (SystemCoreClock / 1) - 1;
  else
    period = (SystemCoreClock / freq) - 1;

  // Configure TIM1 internal timer.
  TIM_InitStruct.TIM_Prescaler         = period;
  TIM_InitStruct.TIM_CounterMode       = TIM_CounterMode_Up;
  TIM_InitStruct.TIM_Period            = period;
  TIM_InitStruct.TIM_ClockDivision     = 0;
  TIM_InitStruct.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM1, &TIM_InitStruct);

  // TIM1 on channel 3N configuration in PWM mode.
  TIM_OCStruct.TIM_OCMode       = TIM_OCMode_Timing;
  TIM_OCStruct.TIM_OutputState  = TIM_OutputState_Enable;
  TIM_OCStruct.TIM_OutputNState = TIM_OutputNState_Enable;
  TIM_OCStruct.TIM_Pulse        = (period + 1) * duty_cycle / 100;
  TIM_OCStruct.TIM_OCPolarity   = TIM_OCPolarity_High;
  TIM_OCStruct.TIM_OCNPolarity  = TIM_OCNPolarity_High;
  TIM_OCStruct.TIM_OCIdleState  = TIM_OCIdleState_Set;
  TIM_OCStruct.TIM_OCNIdleState = TIM_OCNIdleState_Set;
  TIM_OC3Init(TIM1, &TIM_OCStruct);

  // Automatic output enable, Break, dead time and lock configuration.
  TIM_BDTRInitStructure.TIM_OSSRState       = TIM_OSSRState_Enable;
  TIM_BDTRInitStructure.TIM_OSSIState       = TIM_OSSIState_Enable;
  TIM_BDTRInitStructure.TIM_LOCKLevel       = TIM_LOCKLevel_OFF;
  TIM_BDTRInitStructure.TIM_DeadTime        = 1;
  TIM_BDTRInitStructure.TIM_Break           = TIM_Break_Enable;
  TIM_BDTRInitStructure.TIM_BreakPolarity   = TIM_BreakPolarity_High;
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

  TIM_CCPreloadControl(TIM1, ENABLE);
  TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
  TIM_Cmd(TIM1, ENABLE);
  TIM_CtrlPWMOutputs(TIM1, ENABLE);

  TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
  TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);

  // Buzz for t ms.
  delay_ms(t);

  // Disable TIM1 internal timer.
  TIM_DeInit(TIM1);
  TIM_CCPreloadControl(TIM1, DISABLE);
  TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE);
  TIM_Cmd(TIM1, DISABLE);
  TIM_CtrlPWMOutputs(TIM1, DISABLE);

  // Turn off the buzzer's peripheral clock to save some power.
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, DISABLE);
}

But the code doesn't work at all and nothing happens on the buzzer side. Can anybody give a hint if there is any problem?

Regards,

Dan.

Outcomes