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?
Best Answer
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...