Skip to main content
parth kothiya
Associate III
March 5, 2020
Solved

STM32F1 TIMER OPM exampe code.

  • March 5, 2020
  • 9 replies
  • 2333 views

i want to use timer in one pulse mode is there any sample code for TIMER OPM mode.

This topic has been closed for replies.
Best answer by berendi

It is an external signal, isn't it?

EXTI interrupts are not really useful for synchronization, because interrupt latency is variable, maybe between 10-40 cycles, depending on the timing w.r.t. other interrupts in the system.

Exact synchronization down to a system clock cycle can be achieved by using a timer trigger input, which can be the timer CH1, CH2, or ETR pin.

I've changed the above code a bit, using the timer in downcounting mode, so that the compare register can be set to a fixed value, which is the number of cycles before the downcounter reaches 0, to start the pulse. The reload (ARR) value should be the sum of Toff and Ton, minus the adjustment required because of the 2 cycles trigger latency. It can be changed anytime, when the new Toff value becomes available.

TIM3->ARR = 0xFFFF; // set it to Toff + Ton - 3, as the trigger takes 2 cycles to have an effect
TIM3->SMCR =
 TIM_SMCR_TS_2|TIM_SMCR_TS_1|TIM_SMCR_TS_0| // TS=111: External Trigger input (ETRF)
 TIM_SMCR_SMS_2|TIM_SMCR_SMS_1; // SMS=110: Trigger Mode - The counter starts at a rising edge of the trigger TRGI
TIM3->CCR3 = 360 - 1; // start the pulse 360 cycles ( = 10 μs ) before the counter reaches 0
TIM3->CCMR2 |=
 TIM_CCMR2_OC3M_2|TIM_CCMR2_OC3M_1; // 110: PWM mode 1
TIM3->CCER |= TIM_CCER_CC3E; // Enable PWM output on channel 3
TIM3->CR1 |= TIM_CR1_OPM | TIM_CR1_DIR; // enable one pulse mode, downcounting

9 replies

dbgarasiya
Senior
March 5, 2020

what your requirement , you want to generate delay ?

parth kothiya
Associate III
March 6, 2020

total time of pulse(on+off) is (10ms = 10,000 us).

now pulse on time is fix let say 10 us.

now i need to very off time between( 0-9,990 us).

for example: OFF-ON-OFF , ON-OFF, OFF-ON (here total time 10ms on time fix 10us)

and every 10 ms external interrupt comes so i need to reset counter back to 0 for synchronous operation with external interrupt.

that is my requirement.

waclawek.jan
Super User
March 5, 2020

OPM is exactly the same as any other time mode, except that you set TIMx_CR1.OPM bit before enabling the timer.

That tells the timer to disable itself after having counted one cycle up to TIMx_ARR.

JW

parth kothiya
Associate III
March 6, 2020

can i write code using HAL driver or it need LL driver for it ?

because here i found it need LL driver.

total time of pulse(on+off) is (10ms = 10,000 us).

now pulse on time is fix let say 10 us.

now i need to very off time between( 0-9,990 us).

for exampe: OFF-ON-OFF , ON-OFF, OFF-ON (here total time 10ms on time fix 10us)

and every 10 ms external interrupt comes so i need to reset counter back to 0 for synchronous operation with external interrupt.

that is my requirement.

berendi
Principal
March 6, 2020

Neither HAL nor LL is documented in sufficient detail for such everyday requirements.

There is an example of one-pulse mode in the TIMx functional description chapters of the reference manual. I have simplified it a bit, using the timer ETR pin as a trigger as it is somewhat easier as using the timer channels, and configured channel 3 as PWM output, because that's where I happen to have a LED connected.

Timer and GPIO should be enabled in RCC beforehand, and the trigger and PWM pin should be configured as alternate function input and output respectively.

Set the length of the pulse. This value will result in a 10 μs pulse if the timer clock is 36 MHz.

TIM3->ARR = 360;

Set trigger source ETR and slave mode trigger mode

TIM3->SMCR =
 TIM_SMCR_TS_2|TIM_SMCR_TS_1|TIM_SMCR_TS_0| // TS=111: External Trigger input (ETRF)
 TIM_SMCR_SMS_2|TIM_SMCR_SMS_1; // SMS=110: Trigger Mode - The counter starts at a rising edge of the trigger TRGI

Start the pulse at the first cycle after the trigger.

TIM3->CCR3 = 1;

Channel 3 in PWM mode 2

TIM3->CCMR2 |=
 TIM_CCMR2_OC3M_2|TIM_CCMR2_OC3M_1|TIM_CCMR2_OC3M_0; // 111: PWM mode 2

Enable PWM output on channel 3

TIM3->CCER |= TIM_CCER_CC3E;

Enable one-pulse mode

TIM3->CR1 |= TIM_CR1_OPM;

Now the timer would start each time a rising edge is detected on the ETR pin, outputting a single pulse on channel 3. Set the TIM_SMR_ETP (external trigger polarity) bit if you want it to start on the falling edge instead.

waclawek.jan
Super User
March 6, 2020

I don't quite understand, please draw a timing diagram.

JW

parth kothiya
Associate III
March 9, 2020

here i want to do it.0693W0000000KEkQAM.jpg

berendi
berendiBest answer
Principal
March 9, 2020

It is an external signal, isn't it?

EXTI interrupts are not really useful for synchronization, because interrupt latency is variable, maybe between 10-40 cycles, depending on the timing w.r.t. other interrupts in the system.

Exact synchronization down to a system clock cycle can be achieved by using a timer trigger input, which can be the timer CH1, CH2, or ETR pin.

I've changed the above code a bit, using the timer in downcounting mode, so that the compare register can be set to a fixed value, which is the number of cycles before the downcounter reaches 0, to start the pulse. The reload (ARR) value should be the sum of Toff and Ton, minus the adjustment required because of the 2 cycles trigger latency. It can be changed anytime, when the new Toff value becomes available.

TIM3->ARR = 0xFFFF; // set it to Toff + Ton - 3, as the trigger takes 2 cycles to have an effect
TIM3->SMCR =
 TIM_SMCR_TS_2|TIM_SMCR_TS_1|TIM_SMCR_TS_0| // TS=111: External Trigger input (ETRF)
 TIM_SMCR_SMS_2|TIM_SMCR_SMS_1; // SMS=110: Trigger Mode - The counter starts at a rising edge of the trigger TRGI
TIM3->CCR3 = 360 - 1; // start the pulse 360 cycles ( = 10 μs ) before the counter reaches 0
TIM3->CCMR2 |=
 TIM_CCMR2_OC3M_2|TIM_CCMR2_OC3M_1; // 110: PWM mode 1
TIM3->CCER |= TIM_CCER_CC3E; // Enable PWM output on channel 3
TIM3->CR1 |= TIM_CR1_OPM | TIM_CR1_DIR; // enable one pulse mode, downcounting