Skip to main content
franck2
Associate III
November 21, 2014
Question

Pb generating 2 PMW

  • November 21, 2014
  • 22 replies
  • 4079 views
Posted on November 21, 2014 at 12:04

The original post was too long to process during our migration. Please click on the attachment to read the original post.
    This topic has been closed for replies.

    22 replies

    Tesla DeLorean
    Guru
    November 21, 2014
    Posted on November 21, 2014 at 18:56

    Less blind, and having eaten breakfast... Stuck the scope on this one

    // STM32 PMW @4MHz (PA9) and @1MHz (PA3) STM32F3-Discovery - sourcer32@gmail.com
    /**************************************************************************************/
    #include ''stm32f3_discovery.h''
    #include ''stm32f30x.h''
    /**************************************************************************************/
    static void TIM_Config(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    uint16_t TimerPeriod = 0;
    uint16_t ChannelPulse = 0;
    /* GPIOA & GPIOB Clocks enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    /* GPIOA & GPIOB Configuration: Channel 3 (TIM2) and Channel 2 (TIM15) as alternate function push-pull */
    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_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_3; // TIM2_CH3 (PA9), TIM15_CH2 (PA3)
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_10); // TIM2 PA9 AF10
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_9); // TIM15 PA3 AF9
    /* Compute the value to be set in ARR regiter to generate signal frequency at 1MHz */
    TimerPeriod = (SystemCoreClock / 1000000);
    /* Compute CCR value to generate a duty cycle at 50% for channel */
    ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10);
    /* Tim15 clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure);
    /* Channel Configuration in PWM mode - fully qualify TIM15 is special */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_Pulse = ChannelPulse;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // Want the Positive
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // not the negative
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
    TIM_OC2Init(TIM15, &TIM_OCInitStructure); // TIM15_CH2 - PA3
    /* Tim15 counter enable */
    TIM_Cmd(TIM15, ENABLE);
    /* Tim15 Main Output Enable - TIM15 is special on STM32F3 */
    TIM_CtrlPWMOutputs(TIM15, ENABLE);
    /*----------------------------------------------------------------------- */
    /* Compute the value to be set in ARR regiter to generate signal frequency at 4MHz */
    TimerPeriod = (SystemCoreClock / 4000000);
    /* Compute CCR value to generate a duty cycle at 50% for channel */
    ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10);
    /* Tim2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    /* Channel Configuration in PWM mode */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_Pulse = ChannelPulse;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM_OC3Init(TIM2, &TIM_OCInitStructure); // TIM2_CH3 - PA9
    /* Tim2 Counter Enable */
    TIM_Cmd(TIM2, ENABLE);
    }
    /**************************************************************************************/
    int main(void)
    {
    /*!< At this stage the microcontroller clock setting is already configured,
    this is done through SystemInit() function which is called from startup
    file (startup_stm32f30x.s) before to branch to application main.
    To reconfigure the default setting of SystemInit() function, refer to
    system_stm32f30x.c file
    */
    /* TIM Configuration */
    TIM_Config();
    /* Infinite loop */
    while (1);
    }
    /**************************************************************************************/
    #ifdef USE_FULL_ASSERT
    /**
    * @brief Reports the name of the source file and the source line number
    * where the assert_param error has occurred.
    * @param file: pointer to the source file name
    * @param line: assert_param error line source number
    * @retval None
    */
    void assert_failed(uint8_t* file, uint32_t line)
    {
    /* User can add his own implementation to report the file name and line number,
    ex: printf(''Wrong parameters value: file %s on line %d
    
    '', file, line) */
    /* Infinite loop */
    while (1)
    {
    }
    }
    #endif

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    franck2
    franck2Author
    Associate III
    November 21, 2014
    Posted on November 21, 2014 at 19:19

    Scope verdict: Tim15_Ch2 still dead!

    franck2
    franck2Author
    Associate III
    November 21, 2014
    Posted on November 21, 2014 at 19:27

    Scope probe check and working fine....

    ________________

    Attachments :

    Screen_2014-11-21_07-26-27.jpeg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I14R&d=%2Fa%2F0X0000000bi0%2FJne6cqueKuo_MA9TgvpA.yz5HvKTm1Jorm2p0Qxoafc&asPdf=false
    Tesla DeLorean
    Guru
    November 21, 2014
    Posted on November 21, 2014 at 19:32

    Sorry my scope isn't that fancy, but definitely getting 1 MHz on PA3 of an STM32F3-DISCO, don't know what PA3 is wired too on a NUCLEO, USART output from ST-LINK?

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    franck2
    franck2Author
    Associate III
    November 21, 2014
    Posted on November 21, 2014 at 19:42

    Nucleo Scheme seems you're right...USART

    ________________

    Attachments :

    MB1136.pdf : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I14z&d=%2Fa%2F0X0000000bi1%2FEduQJZTz6YufThU84vKo9y22eZVjIjSr51VEWLWkq3E&asPdf=false
    Tesla DeLorean
    Guru
    November 21, 2014
    Posted on November 21, 2014 at 19:55

    PA2 should be viable, it's not clashing with an output.

    // STM32 PMW @4MHz (PA9) and @1MHz (PA2) STM32F3-Discovery - sourcer32@gmail.com
    /**************************************************************************************/
    #include ''stm32f3_discovery.h''
    #include ''stm32f30x.h''
    /**************************************************************************************/
    static void TIM_Config(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    uint16_t TimerPeriod = 0;
    uint16_t ChannelPulse = 0;
    /* GPIOA & GPIOB Clocks enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    /* GPIOA & GPIOB Configuration: Channel 3 (TIM2) and Channel 1 (TIM15) as alternate function push-pull */
    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_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_2; // TIM2_CH3 (PA9), TIM15_CH1 (PA2)
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_10); // TIM2 PA9 AF10
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_9); // TIM15 PA2 AF9
    /* Compute the value to be set in ARR regiter to generate signal frequency at 1MHz */
    TimerPeriod = (SystemCoreClock / 1000000);
    /* Compute CCR value to generate a duty cycle at 50% for channel */
    ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10);
    /* Tim15 clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure);
    /* Channel Configuration in PWM mode - fully qualify TIM15 is special */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_Pulse = ChannelPulse;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // Want the Positive
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // not the negative
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
    TIM_OC1Init(TIM15, &TIM_OCInitStructure); // TIM15_CH1 - PA2
    /* Tim15 counter enable */
    TIM_Cmd(TIM15, ENABLE);
    /* Tim15 Main Output Enable - TIM15 is special on STM32F3 */
    TIM_CtrlPWMOutputs(TIM15, ENABLE);
    /*----------------------------------------------------------------------- */
    /* Compute the value to be set in ARR regiter to generate signal frequency at 4MHz */
    TimerPeriod = (SystemCoreClock / 4000000);
    /* Compute CCR value to generate a duty cycle at 50% for channel */
    ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10);
    /* Tim2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    /* Channel Configuration in PWM mode */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_Pulse = ChannelPulse;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM_OC3Init(TIM2, &TIM_OCInitStructure); // TIM2_CH3 - PA9
    /* Tim2 Counter Enable */
    TIM_Cmd(TIM2, ENABLE);
    }
    /**************************************************************************************/
    int main(void)
    {
    /*!< At this stage the microcontroller clock setting is already configured,
    this is done through SystemInit() function which is called from startup
    file (startup_stm32f30x.s) before to branch to application main.
    To reconfigure the default setting of SystemInit() function, refer to
    system_stm32f30x.c file
    */
    /* TIM Configuration */
    TIM_Config();
    /* Infinite loop */
    while (1);
    }
    /**************************************************************************************/
    #ifdef USE_FULL_ASSERT
    /**
    * @brief Reports the name of the source file and the source line number
    * where the assert_param error has occurred.
    * @param file: pointer to the source file name
    * @param line: assert_param error line source number
    * @retval None
    */
    void assert_failed(uint8_t* file, uint32_t line)
    {
    /* User can add his own implementation to report the file name and line number,
    ex: printf(''Wrong parameters value: file %s on line %d
    
    '', file, line) */
    /* Infinite loop */
    while (1)
    {
    }
    }
    #endif

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    franck2
    franck2Author
    Associate III
    November 21, 2014
    Posted on November 21, 2014 at 20:07

    Mad...Still dead!

    So I'll try with TIM1_CH1. At first I didn't want to use it, being a powerful one....but it's friday....so....No way!

    franck2
    franck2Author
    Associate III
    November 21, 2014
    Posted on November 21, 2014 at 20:20

    I should do something wrong as I didn't get any PMW either with Timer15, or even now Timer1. Scope is ok. Probe also. I've checked probe channel 2.

    So it must be something obvious....

    franck2
    franck2Author
    Associate III
    November 21, 2014
    Posted on November 21, 2014 at 20:23

    My new code program with Timer 1 CH1 and what the scope gave me:

    // STM32 PMW @4MHz (PA9) and @1MHz (PA2)

    /**************************************************************************************/

    #include ''stm32f30x.h''

    /**************************************************************************************/

    static void TIM_Config(void)

    {

    GPIO_InitTypeDef GPIO_InitStructure;

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    TIM_OCInitTypeDef TIM_OCInitStructure;

    uint16_t TimerPeriod = 0;

    uint16_t ChannelPulse = 0;

    /* GPIOA & GPIOC Clocks enable */

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOC, ENABLE);

    /* GPIOA & GPIOC Configuration: Channel 3 (TIM2) and Channel 1 (TIM1) as alternate function push-pull */

    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_InitStructure.GPIO_Pin = GPIO_Pin_9 ; // TIM2_CH3 (PA9)

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_10); // TIM2 PA9 AF10

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ; // TIM1_CH1 (PC0)

    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_2); // TIM1 PC0 AF2

    /* Compute the value to be set in ARR regiter to generate signal frequency at 1MHz */

    TimerPeriod = (SystemCoreClock / 1000000);

    /* Compute CCR value to generate a duty cycle at 50% for channel */

    ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10);

    /* Tim15 clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    /* Time Base configuration */

    TIM_TimeBaseStructure.TIM_Prescaler = 0;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1;

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    /* Channel Configuration in PWM mode - */

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;

    TIM_OCInitStructure.TIM_Pulse = ChannelPulse;

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // Want the Positive

    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // not the negative

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;

    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;

    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

    TIM_OC1Init(TIM1, &TIM_OCInitStructure); // TIM1_CH1 - PC0

    /* Tim15 counter enable */

    TIM_Cmd(TIM1, ENABLE);

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

    /* Compute the value to be set in ARR regiter to generate signal frequency at 4MHz */

    TimerPeriod = (SystemCoreClock / 4000000);

    /* Compute CCR value to generate a duty cycle at 50% for channel */

    ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10);

    /* Tim2 clock enable */

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);

    /* Time Base configuration */

    TIM_TimeBaseStructure.TIM_Prescaler = 0;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1;

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    /* Channel Configuration in PWM mode */

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;

    TIM_OCInitStructure.TIM_Pulse = ChannelPulse;

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

    TIM_OC3Init(TIM2, &TIM_OCInitStructure); // TIM2_CH3 - PA9

    /* Tim2 Counter Enable */

    TIM_Cmd(TIM2, ENABLE);

    }

    /**************************************************************************************/

    int main(void)

    {

    /*!< At this stage the microcontroller clock setting is already configured,

    this is done through SystemInit() function which is called from startup

    file (startup_stm32f30x.s) before to branch to application main.

    To reconfigure the default setting of SystemInit() function, refer to

    system_stm32f30x.c file

    */

    /* TIM Configuration */

    TIM_Config();

    /* Infinite loop */

    while (1);

    }

    /**************************************************************************************/

    #ifdef USE_FULL_ASSERT

    /**

    * @brief Reports the name of the source file and the source line number

    * where the assert_param error has occurred.

    * @param file: pointer to the source file name

    * @param line: assert_param error line source number

    * @retval None

    */

    void assert_failed(uint8_t* file, uint32_t line)

    {

    /* User can add his own implementation to report the file name and line number,

    ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */

    /* Infinite loop */

    while (1)

    {

    }

    }

    #endif

    ________________

    Attachments :

    Screen_2014-11-21_08-22-44.jpeg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I14k&d=%2Fa%2F0X0000000bhy%2F.0fXpGd0u86TaaaGCBmJjorPSurDQKiav92Bpymdo6Y&asPdf=false
    Tesla DeLorean
    Guru
    November 21, 2014
    Posted on November 21, 2014 at 21:07

     GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_2); // TIM1 PC0 AF2

    Should be GPIO_PinSource0, but the datasheet I'm looking at doesn't show it connecting to TIM1
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..