cancel
Showing results for 
Search instead for 
Did you mean: 

high frequency PWM

girtor
Associate II
Posted on April 24, 2013 at 21:18

Hi, want to generate a 24MHZ 50%DC PWM, I have follow this example ,but I can't get more than 500Khz, please help me.

void TIM_Config(void)

{

/* -----------------------------------------------------------------------

    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles.

    In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),

    since APB1 prescaler is different from 1.

      TIM3CLK = 2 * PCLK1

      PCLK1 = HCLK / 4

      => TIM3CLK = HCLK / 2 = SystemCoreClock /2

    To get TIM3 counter clock at 28 MHz, the prescaler is computed as follows:

       Prescaler = (TIM3CLK / TIM3 counter clock) - 1

       Prescaler = ((SystemCoreClock /2) /28 MHz) - 1

    To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows:

       ARR = (TIM3 counter clock / TIM3 output clock) - 1

           = 665

    TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%

    TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%

    TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%

    TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%

    Note:

     SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.

     Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()

     function to update SystemCoreClock variable value. Otherwise, any configuration

     based on this variable will be incorrect.

  ----------------------------------------------------------------------- */

  GPIO_InitTypeDef GPIO_InitStructure;

  /* TIM3 clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* GPIOC and GPIOB clock enable */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB, ENABLE);

  /* GPIOC Configuration: TIM3 CH1 (PC6) and TIM3 CH2 (PC7) */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;

  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(GPIOC, &GPIO_InitStructure);

  /* GPIOB Configuration:  TIM3 CH3 (PB0) and TIM3 CH4 (PB1) */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

  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 TIM3 pins to AF2 */

  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);

  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM3);

}

void PWM_Setup(void)

{

    /* Compute the prescaler value */

  PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 28000000) - 1;

  /* Time base configuration */

  TIM_TimeBaseStructure.TIM_Period = 665;

  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;

  TIM_TimeBaseStructure.TIM_ClockDivision = 0;

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;

  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel2 */

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

  TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel3 */

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

  TIM_OC3Init(TIM3, &TIM_OCInitStructure);

  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel4 */

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

  TIM_OC4Init(TIM3, &TIM_OCInitStructure);

  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM3, ENABLE);

  /* TIM3 enable counter */

  TIM_Cmd(TIM3, ENABLE);

}

thx in advance

#pwm
8 REPLIES 8
Posted on April 24, 2013 at 21:31

Well it's going to depend on the processor we're talking about, and the speed you're running it at.

For an F4 running at 168 MHz you aren't going to get 24 MHz at 50/50, you could get 3/4 (43/57) or reverse.

Running at 144 MHz you could get 24 MHz at 50/50 with a timer on APB2 (AHB/2), Prescaler = 0, Period = 6 - 1, Width = 3

[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/STM32F%20TIM8%20PWM&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=302]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FSTM32F%20TIM8%20PWM&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=302

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
girtor
Associate II
Posted on April 24, 2013 at 23:12

hi Mr clive1, thanks for your quick answer, the board is STM32F4-discovery, I tried the examples of the links, but I get a triangular waveform at 42Mhz and if I slow down the frequency near to 900Khz then I get a square waveform with gibbs phenomenon, what is happening?

excuse me for my english, it is no so good

Posted on April 25, 2013 at 01:16

Your scope isn't any good? I picked the wrong pin?

I'll slap a 100 MHz scope on it tomorrow, I don't imagine it'll be perfectly square, but should be serviceable.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
girtor
Associate II
Posted on April 25, 2013 at 04:27

Hi, the oscilloscope is RIGOL DS1052E, im taking the signal from PA8

girtor
Associate II
Posted on April 25, 2013 at 05:45

Hi, the oscilloscope is RIGOL DS1052E, im taking the signal from PA8

zzdz2
Associate II
Posted on April 25, 2013 at 12:52

You may want to watch these:

http://www.youtube.com/watch?v=OiAmER1OJh4

http://www.youtube.com/watch?v=9GqfZMcrAFY

Posted on April 25, 2013 at 18:44

At 42 MHz it spends most of it's time slewing the signal, at 21 MHz the square wave is fine. The PA8 trace is about 2'' long, I can't get good/clean connectivity of the scope probe to the signal and ground. This is with a 100 MHz Tektronix TDS220 with a x10 non-switchable probe,with a flying ground lead.

Ideally you'd want a suitably routed trace, and a BNC take off point. Some of the EVAL series board have these, often for the ADC, but might be attached to a counter.

There are probably other timer/pin combinations that would be better, but even PA8 has demonstrably better than 900 KHz bandwidth.

@knik, Thanks, I hadn't really though much about the probe itself.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
girtor
Associate II
Posted on April 25, 2013 at 23:32

Hi, thank you so much Mr knik for the video, i think that my problem are the probes, Mr clive1 thank you so much for testing the code, im going to see who can borrow me a probe

thx a lot