2013-09-01 10:04 AM
i'm tryng to simply get 50Hz PWM out of 4 pin, timer used is TIM4, pins are D10, D11, D12 and D13.
but i get a fixed HIGH.. code: int init_pwm2(int pwm_freq) { GPIO_InitTypeDef GPIO_InitStruct; /*Enable or disable the AHB peripheral clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); /*Configure GPIO pin */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOD, &GPIO_InitStruct); /* Connect TIM4 pins to AF2 */ GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_2); GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_2); GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2); GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2); NVIC_InitTypeDef NVIC_InitStructure; /* Enable the TIM4 gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // Calculates the timing. This is common for all channels uint32_t clk = RCC_Clocks.HCLK_Frequency; // 72MHz -> system core clock. This is default on the stm32f3 discovery //RCC_Clocks.PCLK1_Frequency; uint32_t tim_freq = 2e6; // in Hz (2MHz) Base frequency of the pwm timer uint32_t prescaler = ((clk / tim_freq) - 1); // Calculate the period for a given pwm frequency // int pwm_freq = 200; // in Hz uint32_t pwm_period = tim_freq/pwm_freq; // 2MHz / 200Hz = 10000 // For 50Hz we get: 2MHz / 50Hz = 40000 // Calculate a number of pulses per millisecond. // Not used in this rutine but I put it here just as an example uint32_t ms_pulses = (float)pwm_period / (1000.0/pwm_freq); // for 200Hz we get: 10000 / (1/200 * 1000) = 2000 // Enable the TIM1 peripherie RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE ); // Setup the timing and configure the TIM1 timer TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructInit(& TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = prescaler; TIM_TimeBaseStructure.TIM_Period = pwm_period - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // Initialise the timer channels TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = ms_pulses/2; // preset pulse width 0..pwm_period TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // Pulse polarity // TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; // These settings must be applied on the timer 1. TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; // Setup four channels // Channel 1, pin PD10? TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); // Channel 2, pin PD11? TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); // Channel 3, pin PD12? TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // Channel 4, pin PD13? TIM_OC4Init(TIM4, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); // Starup the timer //TIM_ARRPreloadConfig(TIM1, DISABLE); TIM_ARRPreloadConfig(TIM4, DISABLE); TIM_CtrlPWMOutputs(TIM4, ENABLE); TIM_Cmd(TIM4 , ENABLE); // The PWM is running now. The pulse width can be set by // TIM1->CCR1 = [0..pwm_period] -> 0..100% duty cycle // // For example: // int pulse_width = 3000; // TIM4->CCR1 = pulse_width; // // The firmware offers a API to do this: //TIM_SetCompare1(TIM4 , pulse_width); // This is a wrapper for TIM4->CCR1, the same as TIM4->CCR1=pulse_width; return pwm_period; } #stm32f3-pwm #pwm-ppm-tim42013-09-01 11:27 AM
RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE ); // What APB?
2013-09-06 02:40 AM
you are right, also some error here and there 8like using pin 10 and 11 instad of 14 and
Finally this is the working code:GPIO_InitTypeDef GPIO_InitStruct;
/*Enable or disable the AHB peripheral clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
/*Configure GPIO pin */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Connect TIM4 pins to AF2 */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2 );
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2 );
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2 );
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2 );
NVIC_InitTypeDef NVIC_InitStructure;
/* Here you can enable the TIM4 gloabal Interrupt */
//NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//NVIC_Init(&NVIC_InitStructure);
uint16_t prescaler = (uint16_t) ((RCC_Clocks.HCLK_Frequency / 1000000) - 1);
// Shooting for 1 MHz, (1us)
uint32_t pwm_period = 20000;
// Enable the TIM4 peripherie
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
// Setup the timing and configure the TIM1 timer
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler = prescaler;
TIM_TimeBaseStructure.TIM_Period = pwm_period - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
// Initialise the timer channels
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 800;
// preset pulse width 0..pwm_period
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
// Pulse polarity
// TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
// These settings must be applied on the timer 1.
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
// Setup four channels
// Channel 1, pin PD10?
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable );
// Channel 2, pin PD11?
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable );
// Channel 3, pin PD12?
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable );
// Channel 4, pin PD13?
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable );
// Starup the timer
//TIM_ARRPreloadConfig(TIM1, DISABLE);
TIM_ARRPreloadConfig(TIM4, DISABLE);
TIM_CtrlPWMOutputs(TIM4, ENABLE);
TIM_Cmd(TIM4, ENABLE);