简体   繁体   English

在STM32F0上将TIM1用于PWM时出错

[英]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). 我试图尽可能地隔离它(通过注释掉工作的TIM3代码以进行比较)。 I've got PWM to work fine on TIM3, but have not seen anything on TIM1. 我的PWM在TIM3上可以正常工作,但在TIM1上却没有看到任何东西。 Originally, the issue was pointed out in the comments that some of the TIM_OCInitStructure. 最初,该问题是在某些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: assert_param()失败:文件“ ../system/src/stm32f0-stdperiph/stm32f0xx_tim.c”,行811。在该行上查找:

  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. TIM_OC1Init()函数似乎适用于TIM3,但不适用于TIM1。 I've seen others in this forum use TIM_OC1Init() for TIM1, so I'm not sure what the issue is for me. 我已经看到该论坛中的其他人将TIM_OC1Init()用于TIM1,所以我不确定问题出在我身上。 Isn't this how I set ch.1? 这不是我设置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. 奇怪的是,您使用给出的代码在IS_TIM_OUTPUTN_STATE行上编程失败,当然这可能是STL错误,但听起来不太可能。 So try to change TIM_OutputNState_Disable on TIM_OutputNState_Enable. 因此,尝试在TIM_OutputNState_Enable上更改TIM_OutputNState_Disable。

If you catch assert the program falls into infinite loop and the following setting code does not executed, so no pwm signal generates. 如果捕获断言,则程序将陷入无限循环,并且不会执行以下设置代码,因此不会生成pwm信号。 Also you may try to configure timer with undefined USE_FULL_ASSERT, bad policy but at least it will not cause falling to assert. 您也可以尝试使用未定义的USE_FULL_ASSERT配置计时器,这是错误的策略,但至少不会导致断言。

In terms of code, you can try to add TIM_CtrlPWMOutputs(TIM1, ENABLE); 在代码方面,您可以尝试添加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. 而且您的函数对我来说似乎很奇怪,因为您要么在启用rcc之前调用TIM_PWM_Init()(这是错误的),要么在启用计时器之后调用,这也很奇怪。

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. 我认为解决该问题的最简单方法是从SPL示例(例如“ STM32F0xx_StdPeriph_Lib_V1.5.0 \\ Projects \\ STM32F0xx_StdPeriph_Examples \\ TIM \\ TIM_7PWMOutputs”)中粘贴所有漂亮的代码,然后删除多余的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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