简体   繁体   中英

Error using TIM1 for PWM on STM32F0

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM