I'm trying to isolate this as much as possible (by commenting out the working TIM3 code for comparison). I've got PWM to work fine on TIM3, but have not seen anything on TIM1. Originally, the issue was pointed out in the comments that some of the TIM_OCInitStructure. calls were missing (OutputNState), but I have them all in there and am still not seeing any signal. Does anyone see anything else missing in the code?

void TIM_TIMER_Init(void)
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

//  RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM3EN, ENABLE);   //timer 3
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);   //timer 1
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseStructure.TIM_Period = 4799;  // PER = F_timer / F_pwm - 1
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    // Initialize TIMx
//  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    // Start count on TIMx
//  TIM_Cmd(TIM3, ENABLE);
    TIM_Cmd(TIM1, ENABLE);

void TIM_PWM_Init(void)
    TIM_OCInitTypeDef   TIM_OCInitStructure;

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;   // PWM1/PWM2 = set/clear on compare match
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;

    TIM_OCInitStructure.TIM_Pulse = 959;    // 20% Duty Cycle on ch. 1
//  TIM_OC1Init(TIM3, &TIM_OCInitStructure);
//  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
    TIM_OCInitStructure.TIM_Pulse = 1919;   // 40% Duty Cycle on ch. 2
//  TIM_OC2Init(TIM3, &TIM_OCInitStructure);
//  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_OCInitStructure.TIM_Pulse = 2879;   // 60% Duty Cycle on ch. 3
//  TIM_OC3Init(TIM3, &TIM_OCInitStructure);
//  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_OCInitStructure.TIM_Pulse = 3839;   // 80% Duty Cycle on ch. 4
//  TIM_OC4Init(TIM3, &TIM_OCInitStructure);
//  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC4Init(TIM1, &TIM_OCInitStructure);
    TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);

//"using convenience methods instead of CMSIS"
void TIM_PINS_Init(void)
    GPIO_InitTypeDef    GPIO_InitStructure;

//  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);  //enabling port C
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  //enabling port A 

    // Alternative Functions for pins
//  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_0);  // PC6
//  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_0);  // PC7
//  GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_0);  // PC8
//  GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_0);  // PC9

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2);    // PA8
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_2);    // PA9
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_2);   // PA10
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_2);   // PA11

    // Set pins
//  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

//  GPIO_Init(GPIOC, &GPIO_InitStructure);  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

////////////////// Original Question //////////////////

Does anyone see a problem with this bit of code?

TIM_OCInitTypeDef   TIM_OCInitStructure;

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

    TIM_OCInitStructure.TIM_Pulse = 959;    // 20% Duty Cycle on ch. 1
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

The problem is with

TIM_OC1Init(TIM1, &TIM_OCInitStructure);

The error is

assert_param() failed: file "../system/src/stm32f0-stdperiph/stm32f0xx_tim.c", line 811. Looking that up that line is:

  if((TIMx == TIM1) || (TIMx == TIM15) || (TIMx == TIM16) || (TIMx == TIM17))
    assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); // <- line 811

The TIM_OC1Init() function seems to work for TIM3, but not TIM1. I've seen others in this forum use TIM_OC1Init() for TIM1, so I'm not sure what the issue is for me. Isn't this how I set ch.1?

  • \$\begingroup\$ I believe it's complaining because you haven't defined TIM_OutputNState in your TIM_OCInitStructure. \$\endgroup\$
    – brhans
    Jan 18, 2017 at 22:01
  • \$\begingroup\$ if i comment out the last two lines, this executes fine. so i'm confused why this is an issue for TIM1 \$\endgroup\$ Jan 18, 2017 at 22:25
  • \$\begingroup\$ I would imagine it's explained in the datasheet/ref-manual somewhere, but it looks as though whoever wrote that code in the peripheral library decided that you have to give TIM_OutputNState a value if you're using TIM1/15/16/17. Just figure out what is should be and do it... \$\endgroup\$
    – brhans
    Jan 18, 2017 at 22:31
  • 1
    \$\begingroup\$ Timers 1, 15, 16, 17 have the option to have both positive-logic & inverted/negative-logic outputs on individual pins, whereas Timers 2, 3, 14 only have the positive-logic output pins. That's why there's a difference and it doesn't complain when you use TIM3 - it doesn't have a TIM_OutputNState while TIM1 does. \$\endgroup\$
    – brhans
    Jan 18, 2017 at 22:42
  • \$\begingroup\$ I guess you need to have TIM_OCInitStructure.TIM_OutputNState set to True for this configuration. Is it set to True ? \$\endgroup\$
    – MathiasE
    Jan 23, 2017 at 5:46

1 Answer 1


Adding TIM_CtrlPWMOutputs(TIM1, ENABLE); to the end of TIM_TIMER_Init() got all the PWM's on TIM1 going.

Interestingly, only TIM_OutputNState matters (Enable/Disable doesn't matter). TIM_OCNIdleState, TIM_OCNPolarity, and TIM_OCIdleState can be removed and there is no effect. Not sure I understand that since they are right under the original assert_param() errors from the original post, but anyways...


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.