cancel
Showing results for 
Search instead for 
Did you mean: 

Generate a single pulse of 12ns with stm32u5

lucascalam
Visitor

Hi there.

I’m trying to generate a 12 ns pulse for a time-of-flight (ToF) application.

I’m using an STM32U5 microcontroller, and I’d like to know whether one of the general-purpose timers (TIM2/TIM3/TIM4/TIM5) can produce a pulse that narrow. With a 160 MHz timer clock, the time resolution is about 6 ns, so in principle it seems feasible, but I may be overlooking something.

Thanks!

12 REPLIES 12
T_Hamdi
ST Employee

hello @lucascalam 

To generate a pulse of about 12 ns using an STM32U5 timer running at 160 MHz, you can:

  • Set the timer prescaler to 1 (no division) for a timer tick of 6.25 ns.
  • Use PWM mode or Output Compare mode.
  • Set the pulse width to 2 timer ticks (12.5 ns), which is the closest achievable width to 12 ns.

This will produce a pulse very close to 12 ns directly from the timer hardware without CPU intervention.

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Hamdi Teyeb

Hi @T_Hamdi , thanks a lot for your answer. Do you know if there is any example I can use as a guide?

> This will produce a pulse very close to 12 ns directly from the timer hardware without CPU intervention.

This time would correspond to 2 single-cycle (pipelined) core instructions.
In other words, this is not achievable by the core itself.

Another option would be external hardware.

hello @Ozone 

 using the STM32U5 timer hardware running at 160 MHz, you can generate a pulse of approximately 12.5 ns (2 timer ticks) via PWM or Output Compare mode without CPU intervention. This is achievable because the timer operates independently of the CPU pipeline.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Hamdi Teyeb

Yes, I understood that.
My point is, there is no alternative based upon core performance alone.

lucascalam
Visitor

I am using something like this:


void WHGPIO_PinOutSendPulse1(void) {
    LL_TIM_EnableCounter(TIM2);
}

void WHGPIO_InitPinOutSendPulse(void) {
    
    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);

    LL_GPIO_InitTypeDef gpio_init = {0};
    gpio_init.Pin = LL_GPIO_PIN_1;
    gpio_init.Mode = LL_GPIO_MODE_ALTERNATE;
    gpio_init.Alternate = LL_GPIO_AF_1;       // TIM2_CH2 → AF1 on PA1
    gpio_init.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
    gpio_init.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    gpio_init.Pull = LL_GPIO_PULL_NO;

    LL_GPIO_Init(GPIOA, &gpio_init);

    LL_TIM_DisableCounter(TIM2);
    LL_TIM_OC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_OCPOLARITY_HIGH);

    LL_TIM_SetPrescaler(TIM2, 0);
    LL_TIM_SetAutoReload(TIM2, 200);
    LL_TIM_OC_SetCompareCH2(TIM2, 1);

    LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_OCMODE_PWM1);

    LL_TIM_OC_EnablePreload(TIM2, LL_TIM_CHANNEL_CH2);
    LL_TIM_EnableARRPreload(TIM2);

    LL_TIM_SetOnePulseMode(TIM2, LL_TIM_ONEPULSEMODE_SINGLE);

    LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);

    LL_TIM_GenerateEvent_UPDATE(TIM2);
}


void main() {
    WHGPIO_InitPinOutSendPulse();
    while(1) {
        WHGPIO_PinOutSendPulse1();
    }
}

I obtained the results shown in the attached images. From the first graph, we can see that the pulse width is significantly larger than 12 ns. The second graph shows the interval between pulses, which is about 1.25 µs. This is expected, since the auto-reload value is set to 200 ticks, and 200 × 6.25 ns = 1.25 µs. So, while the frequency appears to be configured correctly, the pulse width does not.

T_Hamdi
ST Employee

hello @lucascalam 

To achieve a pulse width of approximately 12 ns, you need to increase the compare value in your code from:

LL_TIM_OC_SetCompareCH2(TIM2, 2);

 each timer tick corresponds to about 6.25 ns at 160 MHz, setting the compare register to 2 will produce a pulse width close to 12.5 ns, effectively doubling the pulse duration from 6.25 ns to approximately 12 ns.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Hamdi Teyeb
lucascalam
Visitor

hello @T_Hamdi .

Thanks for your answer. The problem is that even when the compare value is set to 1, the pulse width that I get is more than 50ns, as the image that I attached on the previous reply. Do you have any idea why the pulse is always longer than the expected 6ns (or 12ns in case the compare value is set to 2 ticks) ?

T_Hamdi
ST Employee

hello @lucascalam 

To understand why your pulse width is longer than expected, you should first check the actual timer clock frequency. If the timer runs at a lower frequency than 160 MHz, each timer tick will be longer, which increases the pulse width.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Hamdi Teyeb