0

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, 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?

Bobby Digital
  • 45
  • 1
  • 8
  • Just a guess, could it be because you pass the same control structure to timer 3 and then to timer 1? – Weather Vane Jan 18 '17 at 20:14
  • i was curious about that too. if i comment out the tim3 stuff the error is the same – Bobby Digital Jan 18 '17 at 21:10
  • Seems that you have to define a `TIM_Output_Compare_N_State` for Timer TIM1, try to add `TIM__OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;` or `TIM__OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;` before calling `TIMOC1Init` for `TIM1`. – gmug Jan 19 '17 at 08:50

1 Answers1

0

This is strange that you program fails on line IS_TIM_OUTPUTN_STATE with the code you give, of course it may be STL error but it sounds improbable. So try to change TIM_OutputNState_Disable on TIM_OutputNState_Enable.

If you catch assert the program falls into infinite loop and the following setting code does not executed, so no pwm signal generates. Also you may try to configure timer with undefined USE_FULL_ASSERT, bad policy but at least it will not cause falling to assert.

In terms of code, you can try to add TIM_CtrlPWMOutputs(TIM1, ENABLE); after configuring and enabling timer. And your functions seems strange for me, cause you either call TIM_PWM_Init() before enabling rcc (that's wrong) or after enabling timer, that is also strange.

I think that the easiest way to solve the problem is to copy-paste all the beautiful code from SPL examples (like "STM32F0xx_StdPeriph_Lib_V1.5.0\Projects\STM32F0xx_StdPeriph_Examples\TIM\TIM_7PWMOutputs") and then remove the excess.

Yuriy
  • 701
  • 4
  • 18
  • TIM_CtrlPWMOutputs(TIM1, ENABLE); did it, thank you! I added that line to the end of TIM_TIMER_Init() and everything performed as expected. Can't thank you enough! //////// Digging some more, 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 ///////// Thanks for the SPL examples. New to STM32 so had not heard of it. I downloaded the STM32CubeF0 and will check it out. – Bobby Digital Jan 23 '17 at 23:03
  • can you post a link to the SPL examples you had in mind? i'm not sure i'm seeing exactly what you were talking about. – Bobby Digital Jan 24 '17 at 00:38
  • STM32 series (STM32F0, STM32F1, ...) each has its own Standard Peripheral Library (your code as I see uses this library), they can be found [here](http://www.st.com/en/embedded-software/stm32-standard-peripheral-libraries.html?querycriteria=productId=LN1939). And inside library folder there is folder "Projects" in which you can find folder with examples ("STM32F0xx_StdPeriph_Examples" in your case). STM32CubeFX uses HAL instead SPL, so your current code won't work with Cube. – Yuriy Jan 24 '17 at 07:05