AnsweredAssumed Answered

STM32F4 TIM1 One Shot Mode configuration

Question asked by Tang.Robert.002 on Nov 29, 2016
Latest reply on Dec 23, 2016 by Tang.Robert.002
Greetings,


I am trying to achieve the following with TIM1 and TIM1_CH1:
1. Generate X number of PWM pulses after an event.
2. Idle state of PWM output should be low.
3. Pulse output should be high immediately after PWM pulse train initiated.
4. Pulse output should be low after compare match.
5. Duty of PWM is to be around 30%.


I've got TIM1_CH1 outputting X number of pulses after an event. However, I can't seem to work out how to configure the timer module to achieve the above requirements. 


The code below sends out 10 pulses on PA8 each time the User button is pushed on a STM32F4 discovery board. I set my oscilloscope to trigger on the rising edge on PA1 and look at the output of PA8 on another channel. It satisfies all the above requirements, except from the idle state of PWM output (which is high, but I require this to be low).


I have tried changing TIM_OCIdleState but does not seem to change the idle state of the PWM output.


Ultimately I'm looking at creating a device to trigger other devices. The other devices are to be triggered on rising edge and must be accurately synchronised when the event happens (in the code below, it is the User push button).  


Suggestions?

#include "stm32f4xx.h"
#include <stdbool.h>


void delay(uint32_t delay)
{
    uint32_t i;
    while(delay--)
    {
        for(i = 0; i < 30000; i++)
            __asm__("nop");
    }
}


void gpio_cfg(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
 
    /* Setup PA8 as PWM1 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
    
    /* Setup PA1 as sync */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    /* Setup push button */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
 
void pwm_cfg(void)
{    
    TIM_OCInitTypeDef TIM_OCInitStructure;


    TIM_OCStructInit(&TIM_OCInitStructure);    
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 30;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    
    TIM_OC1PolarityConfig(TIM1, TIM_OCPolarity_High);
    
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM1, ENABLE);


    TIM_CtrlPWMOutputs(TIM1, ENABLE);
}


void pwm_start(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;    
    
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);


    TIM_TimeBaseStructure.TIM_RepetitionCounter = 10 - 1; //Send 10 pulses
    TIM_SelectOnePulseMode(TIM1, TIM_OPMode_Single);


    TIM_TimeBaseStructure.TIM_Period = (100-1);
    TIM_TimeBaseStructure.TIM_Prescaler = (42000-1);
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);   
     
    TIM_Cmd(TIM1, ENABLE);
}


int main(void)
{
    /* Initialise system */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //4 bits for pre-emption priority 0 bits for subpriority
 
    /* Initialise peripherals */
    gpio_cfg();     
    pwm_cfg();
     
    while(true)
    {
        if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0))
        {         
            GPIO_SetBits(GPIOA, GPIO_Pin_1);
            pwm_start();
            delay(500); //blocking delay, approx 500ms with Keil and no code optimisation
            GPIO_ResetBits(GPIOA, GPIO_Pin_1);
        }
    }
}

Outcomes