cancel
Showing results for 
Search instead for 
Did you mean: 

Generate pulses using two timers

PontusThuvessonOIM
Associate

I want to generate a ~200us pulse on the DAC (variable output) that occurs at 20Hz.

The DAC itself is no problem, the 20Hz is done with a timer interrupt.

What is the best way to implement the 200us timing? Preferably non-blocking, Another timer that starts from the first one? Suggestions welcome.

4 REPLIES 4
TDK
Guru

One way: Set up another timer to transfer to DAC over DMA. Use a buffer size of 2, with the first sample being the voltage you want and the second one being 0, put the DMA in normal mode (as opposed to circular) and change that timer's frequency based on the length of the pulse you want. You'll need to do some minor setup for each transfer.

If you feel a post has answered your question, please click "Accept as Solution".
liaifat85
Senior III

I think you can configure two timers to perform this task.

PontusThuvessonOIM
Associate

I have the two timers up and running (in a way :-)) and the do their tasks in the assigned callbacks.

But what I havn't got the way I want it is starting the second timer (TIM16 in this case) from the callback of the first one. I guess it should be same if it was started from anywhere, I basically want to start the timer from whereever in the code and get a callback 200 us later. That time might be changed later on when the prototype is tested out.

 

> I basically want to start the timer from whereever in the code and get a callback 200 us later.

Assuming the timer's counter is stopped and its counter (TIMx_CNT) is at zero (see below), set to have a cycle of 200us, and the interrupt (thus "callback") is set to Update, all you need to do is to enable the counter by setting TIMx_CR1.CEN.

TIMx_CNT then starts to increase and when it reaches TIMx_ARR, TIMx_CNT is reset to 0, Update event is generated, and if TIMx_DIER.UIE is set (and interrupt handler is properly written and enabled in NVIC), the interrupt service routine is executed.

But if you leave it at this, TIMx_CNT keeps counting and eventually reaches TIMx_ARR again and again, i.e. repeated interrupts happen every 200us. You appear not wanting this. You may want the timer to stop after TIMx_CNT reached TIMx_ARR the first time.

The easiest way to achieve this is to set the timer to One-Pulse Mode by setting TIMx_CR1.OPM. In this case, when TIMx_CNT reaches TIMx_ARR, resets to zero, Update is generated, but the counter stops counting automatically (TIMx_CR1.CEN is cleared by hardware).

I don't use Cube/CubeMX so don't know how to click this.

JW