cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7: Is it possible to generate PWM signal based on external freq source (not clock src!) using timer's external input trigger?

Wowa
Associate III

Hello,

I've not much experience with all STM timer modes. I have a DDS-based freq source which produces meander wave. On base of this src I want to produce PWM signal using STM timer. As I understand, a regular way to do it is to pass the DDS src as external clock on timer's ETR pin and program PWM in a usual way.

But is it possible to clock the timer from internal src (which gives me 216 MHz clock max on STM32F7) and use DDS signal to start each PWM cycle using timer's external trigger input? I mean to force timer to start each PWM cycle on rising front of DDS impulse. Is such mode at all possible, or input trigger isn't designed for this kind of thing?

4 REPLIES 4

Yes. Set up the PWM as usually, set One-pulse mode by setting TIMx_CR1.OPM=1, set the required channel as input in respective CCMRx, set it as input to the slave-mode controller in TIMx_SMCR.TS and set the slave-mode controller to Trigger mode in TIMx_SMCR.SMS.

JW

Wowa
Associate III

Thank you for the guide! The matter is I'm not familiar with direct register programming, but used to deal with HAL instead. So I'm not sure how to implement your steps using HAL. Is it possible to configure it through HAL calls?

As for now, I have the following setup sequence:

    TIM_SlaveConfigTypeDef sSlaveConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_OC_InitTypeDef sConfigOC = {0};
 
    htim4.Instance = TIM4;
    htim4.Init.Prescaler = 0;
    htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim4.Init.Period = 65535;
    htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
      Error_Handler();
 
    if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
      Error_Handler();
 
    sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
    sSlaveConfig.InputTrigger = TIM_TS_ETRF;
    sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_NONINVERTED;
    sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
    sSlaveConfig.TriggerFilter = 0;
    if (HAL_TIM_SlaveConfigSynchro(&htim4, &sSlaveConfig) != HAL_OK)
      Error_Handler();
 
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
      Error_Handler();
 
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 10;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
    if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
      Error_Handler();

which was basically generated by CubeMX. Should I use HAL_TIM_OnePulse_Init() instead of PWM?

Then I start the DDS (having configured GPIO pin TIM4_ETR and having DDS signal on it) and try to run the timer by HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);

What modifications should I make in this scenario?

One more question: you say that we must put this channel in input mode. But then how do I get putput signal - can one channel act as input and output simultaneously?

>One more question: you say that we must put this channel in input mode. But then how do I get

>output signal - can one channel act as input and output simultaneously?

I misunderstood your question - you intend to use the TIMx_ETR pin as input, I thought you want to use a TIMx_CHx pin, at a different channel than the one used for output.

Sorry for the confusion.

I don't use Cube so can't help with it. But if you set it up and it does not work as you expect, read out and check/post content of TIM and relevant GPIO registers, for further discussion.

JW