2014-07-06 06:59 AM
hi guys, i create a program to generate pwm signals in stm32f407 i did it in past for another timer but when i wanna do it for timer1 i doesn.t work.
here is my code :#include <stm32f4xx.h>
void
InitializeTimer1(
int
period = 1000)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
TIM_TimeBaseInitTypeDef timerInitStructure;
timerInitStructure.TIM_Prescaler = 1000;
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_Period = period;
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
timerInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &timerInitStructure);
TIM_Cmd(TIM1, ENABLE);
}
void
initializeGPIO()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitTypeDef gpioStructure;
gpioStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_13 |GPIO_Pin_14;
gpioStructure.GPIO_Mode = GPIO_Mode_AF;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &gpioStructure);
}
void
InitializePWMChannel1()
{
TIM_OCInitTypeDef outputChannelInit = {0,};
outputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
outputChannelInit.TIM_Pulse = 300;
outputChannelInit.TIM_OutputState = TIM_OutputState_Enable;
outputChannelInit.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM1, &outputChannelInit);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);
}
int
main()
{
InitializeTimer1();
initializeGPIO();
InitializePWMChannel1();
for
(;;)
{}
}
can any body help me , what's wrong with my code ?? any helpappreciate
2014-07-06 07:29 AM
Prescale and Period values are N-1
For TIM1 and TIM8 /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE);2014-07-07 11:13 PM
hiclive1
i wrote the same code for timer 4 and pd12,pd13,pd14 and it worked without this :
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
what this code exactly does ?
and why TIM1 and 8 's
Prescale and Period values are N-1 ??
is there any document to help me about timer ??2014-07-08 04:14 AM
There is the Reference Manual for the part, that provides a lot of detail about the inner workings. You might also want to look at the source code for the peripheral library, as this will provide additional insight.
TIM1 and TIM8 are Advanced Timers, they have more features and controls. Enabling the PWM outputs is one of those features. ALL the timers are programmed with N-1 numbers. If you want 1000 steps, 0-999 then you need to program 999 not 1000, this is because building the comparator for N-1 is far simpler and more efficient than one for N.2014-07-12 03:03 AM
thanks clive for your information , i could generate 7 different pwm channel and now i want to capture 7 input pwm channel in stm32f407 discovery boar , i generate same pulse width for each out put channel in fact in the end i want to get this input pwm s and doing some calculation on them and generate appropriate pwm. but i'v got familiar with some code which i don't have any idea about them and i wanna know whats them any help would be appreciated .
1-/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);
2-
TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);
and another question about frequency. when i set the prescaler for 1 timer to :
(SystemCoreClock / 1000000)-1
it means that i set the frequency to 168000000/(
(SystemCoreClock / 1000000)-1
) or it depends on the amount of frequency that allocated to for example timer 4??2014-07-12 05:02 AM
1) The timer is gated and reset by an external source
2) This control comes from the filtered Channel 2 input 3) You are attempting to compute what value (divisor) would be need to arrive at a 1 MHz clock for the time base give the input TIMCLK. If the APB2 is SYSCLK/2, TIMCLK = SYSCLK, on APB1 if APB1 is SYSCLK/4, TIMCLK = SYSCLK/2 168,000,000 / 1,000,000 = 168 168,000,000 / 168 = 1,000,000 Prescaler = 168 - 1; // N-12014-07-12 05:43 AM
thanks clive.
you'r always helpful. ok i understand some things and now i wrote some code thanks to''Benjamin '' and you in from this thread :
/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/STM32%20Discovery%2c%20RC%20Receiver%2c%20PWM%20Input&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=288
, and all i want is to get the value of pulse width that i generated with timer 2 (PA3) by timer 4 (PB6) and send this value by usart to my pc and watch the result, because as i mentioned i want to generate pwm same as from the one i capture at the time but i doesn't work any help would be grate . thanks a lot#include ''stm32f4xx.h''
#include ''stm32f4xx_gpio.h''
#include ''stm32f4xx_rcc.h''
#include ''stm32f4xx_tim.h''
#include ''stm32f4xx_syscfg.h''
#include ''stm32f4xx_exti.h''
#include ''misc.h''
int
ch1, ch2, ch3, ch4;
TIM_ICInitTypeDef TIM_ICInitStructure;
//===================================
void
TIM_Config(
void
);
/* Private functions ---------------------------------------------------------*/
void
init_usart(
void
){
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
}
void
LED_STATUS()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void
InitializeTimer4(
int
period = 1000)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_TimeBaseInitTypeDef timerInitStructure;
timerInitStructure.TIM_Prescaler = (uint16_t) (((SystemCoreClock / 1000000) / 2) - 1);
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_Period = period;
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
timerInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &timerInitStructure);
TIM_Cmd(TIM2, ENABLE);
TIM_CtrlPWMOutputs(TIM2, ENABLE);
}
void
initializeGPIOA()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitTypeDef gpioStructure;
gpioStructure.GPIO_Pin = GPIO_Pin_3 ;
gpioStructure.GPIO_Mode = GPIO_Mode_AF;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioStructure);
}
void
InitializePWMChannel1()
{
TIM_OCInitTypeDef outputChannelInit = {0,};
outputChannelInit.TIM_OCMode = TIM_OCMode_PWM1;
outputChannelInit.TIM_Pulse = 900;
outputChannelInit.TIM_OutputState = TIM_OutputState_Enable;
outputChannelInit.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM2, &outputChannelInit);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2);
}
void
init(
void
)
{
TIM_Config();
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);
/* Select the TIM4 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM4, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);
TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);
TIM_ITConfig(TIM4, TIM_IT_CC3, ENABLE);
TIM_ITConfig(TIM4, TIM_IT_CC4, ENABLE);
}
//===================================== main function
union
{
int
value; int8_t byte[4];}inttobyte;
int
main(
void
)
{
init_usart();
LED_STATUS();
init();
InitializeTimer4();
initializeGPIOA();
InitializePWMChannel1();
GPIO_SetBits(GPIOD,GPIO_Pin_12);
while
(
true
){
inttobyte.value = ch1;
for
(
int
i = 1 ; i < 4 ; i++)
{
USART_SendData(USART2,inttobyte.byte[i]);
}
}
return
0;
}
void
TIM_Config(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* TIM4 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* GPIOB clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* TIM4 chennel2 configuration : PB.07 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8| GPIO_Pin_9 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect TIM pin to AF2 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_TIM4);
/* Enable the TIM4 global 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);
/* Time base configuration - SystemCoreClock = 168000000 for 168 MHz board ABP1 @ 42 MHz (DIV4) */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (((SystemCoreClock / 1000000) / 2) - 1);
// Shooting for 1 MHz, (1us)
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
// Maximal
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
}
void
TIM4_IRQHandler(
void
)
{
GPIO_SetBits(GPIOD,GPIO_Pin_13);
if
(TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
ch1 = TIM_GetCapture1(TIM4);
}
if
(TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
ch2 = TIM_GetCapture2(TIM4);
}
if
(TIM_GetITStatus(TIM4, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);
ch3 = TIM_GetCapture3(TIM4);
}
if
(TIM_GetITStatus(TIM4, TIM_IT_CC4) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_CC4);
ch4 = TIM_GetCapture4(TIM4);
}
}
2014-07-12 06:39 AM
PWM Input mode requires one TIM per signal.
With the example settings you provided earlier, this would be CH2, with the paired CCR1/CCR2 holding period and duty. If you need to use all four channels for independent signals, you'd need to use Input Capture mode, and NOT reset the timer2014-07-12 08:21 AM
thanks clive but unfortunately i'm beginner in time stuff
what you mean by CH2 and CCR1/CCR2how can i set input channel instead of reset the timer ??can you make a short example please ?2014-07-12 10:03 AM
You need to read the manuals, beginners and professional both need to do some basic reading to understand how things work.
You input the signal on channel 2 of the timer, and the capture/compare registers of channel 1 & 2 hold the period and duty measurements, as they pair together in a manner described in the manual. Here's an example for PWM Input, for a Servo Channel 4 Channel Input Capture (for F0 but applicable across other parts)