How many cycles takes Timer2 OVF ISR overhead?

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all,

I am sure this Q. has already been answered but so far I could not find the answer.

How many cycles does it take to handle Timer2 interrupt in C/Arduino? Or, maybe better, where could I see the intermediate ASM code generated by GCC when compiling the C sketch?

The point is I have 16-MHz Arduino with AVR 328 (and alternatively a similar one with LGT8F328P). I want to implement a sine wave generator controlled by morse encoder and want to implement gaussian error function in the beginning and end of the tone. Timer2 frequency would be roughly 32 KHz (approx. 31.25 usec until the next interrupt).

Since there is some shifting involved (24-bit shift, 8x8 multiplication into 16-bit variable, and 8-bit shift), I am afraid I could exceed the number of cycles available in those 31 microseconds.

Is there some analysis already written? (I am quite sure it is but search engine probably does not want to show me :-) ).

Thank you,

Jindra

-- bev

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK4RM wrote:
a sine wave generator

 

Why it should be a sine wave generator, for playing morse? Nobody does like to listen morse on perfect sine, it is not natural.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's something like 20 cycles but it jitters as it depends on the interrupted opcode and how long it takes to complete. For DDS Google "avr jesper DDS" 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you! This is what I needed.

BTW, is there any rule of thumb for how many cycles takes 32-bit addition, 8x8 => 16 bit multiplication etc? I would guess 32-bit add could be approximately 4 cycles, would multiplication be something like 40-50 cycles? Plus I am not sure about bit shift by multiples of 8. I would assume the compiler would do that by reading high byte. But I cannot find a confirmation :)

73! Jindra

-- bev

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, Clawson,

I looked at the dds generator. It is a slightly different approach. Since I need frequencies only up to 800 Hz, I decided to use PWM output with a 32 KHz clock (Timer2: 16 MHz / 510).  This will save a number of components (especially, for this purpose the R-2R network is a kind of waste of material).

My point is that a plain sine wave generator works well. However, when keyed (hard on-off switch of the sine wave pattern) it creates quite strong, audible clicks. This would be unpleasant for keying slow morse (up to 10-12 wpm) but for normal training, 24 wpm and faster, it is intolerable. Therefore I want to implement a few simple operations at the beginning and the end of the tone, ie. multiplication by looked-up 8-bit value of gaussian error function (implemented as 8x8 bit multiplication and 8-bit shift right). That will require a few cycles more, I just want to make sure I will not exceed the available time of approximately 30 us. In fact, the keyer does nothing most of the time - it is just waiting in the loop and once a time it checks input from paddles, and may also read rotary encoder or serial input. Even if there are just 10-15 usec left for regular program in each tick, it is just fine.

 

Thank you,

Jindra

-- bev

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sounds like a great project.

 

If it turns out you need more processing power, then have a look at an Xmega32E5.

It runs, in spec, at 32 MHz, much faster than the 16 or 20 MHz than most of the AVRs run at.

Additionally, it has an internal DAC, which can further simplify such projects.

 

I'm not familiar with the click problem.

Is that from an old school approach of gating a sine wave signal, and hence having a variable voltage discontinuity in the signal with every on and off of the keying?

 

If so, perhaps you should give a software DDS approach a try.

One of the many nice features of a SW DDS is that it has phase continuity.

In this case you can always start the sine wave at a zero crossing point in the cycle.

With a little care, you can always end on one, also.

 

JC 

 

Edit: Typos

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:
With a little care, you can always end on one, also.
Exactly. To prevent "clicks" you just need to run the wave to its next "zero crossing" when the key is released (as it's only a fraction of one cycle and you are up in audio territory (like 440Hz or whatever) it should only be a matter of milliseconds to the next zero crossing in your wave output and the shaved ape listening to this thing will not realise the wave has run on for a few more sample points.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If we take your phase_accumulator code from https://www.avrfreaks.net/forum/can-8-bit-16-bit-24-bit-shift-c-be-replaced-directly-reading-high-byte then the use of 32-bit variables creates push & pop instructions galore. On AVR there' no way around this.

 

See here: https://godbolt.org/z/s9hqbxTWT

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, JC,

 

summary: it works like breeze, absolutely no timing problem. As a test sketch it plays QUICK BROWN FOX ... On the first run I was surprised by speed, far exceeding the programmed 22 WPM and high tone only to learn I forgot to set f_cpu parameter to 16 MHz, so PlatformIO build used 32 MHz as default. It seems 32 MHz is overkill for the purpose, the interrupt handler takes about 6 us during pause and up to ~11 us when it has to pick up sine values and multiply them by Gauss function (also from lookup table).

 

But it still audibly clicks. I did not have time yet to watch the output at oscilloscope. Hopefully it would reveal something useful.

 

As for the built-in DAC in LGT, I, too, noticed that possibility. The current script is universal - it should run equally well in both the AVR and LGT. I copied parts of code from some other AVR Arduino project, writing directly to control registers of ATMega, and it works in LGT, so it is universally compatible. I assume using DAC should generate less spurious RF radiation and provide cleaner signal, so later I will definitely try. The more so because I 'd have to change nothing in my program except the target control register(s) :)

 

Later today or during the weekend I will post it to github, hoping that someone would also find my bugs in applying the gauss function :) it is applied within like 14 or 15 ticks in the beginning and the end of the mark (tone), which should be about half millisecond. To me it seemed like long enough value, but the clicks don't approve that. During pause, there is constant output of 127, so kind of half-scale DC bias - could this be causing the clicks?

 

Jindra

 

DocJC wrote:

Sounds like a great project.

 

If it turns out you need more processing power, then have a look at an Xmega32E5.

It runs, in spec, at 32 MHz, much faster than the 16 or 20 MHz than most of the AVRs run at.

Additionally, it has an internal DAC, which can further simplify such projects.

 

I'm not familiar with the click problem.

Is that from an old school approach of gating a sine wave signal, and hence having a variable voltage discontinuity in the signal with every on and off of the keying?

 

If so, perhaps you should give a software DDS approach a try.

One of the many nice features of a SW DDS is that it has phase continuity.

In this case you can always start the sine wave at a zero crossing point in the cycle.

With a little care, you can always end on one, also.

 

JC 

 

Edit: Typos

 

-- bev

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, it IS a DDS in any case. The difference is that with a DDS + pin-wise DAC I'd have to use "many" pins and resistors ("many" is relative to only 1 pin of PWM output), while the same DDS approach used with PWM allows for a very simple circuit where you can plug in headphones without too much further signal conditioning or amplification (I use a two-stage RC lowpass to suppress PWM clock frequency and reduce output power to drive common, average headphones without hurting ears)

 

DocJC wrote:

...

 

If so, perhaps you should give a software DDS approach a try.

One of the many nice features of a SW DDS is that it has phase continuity.

...

JC 

 

Edit: Typos

 

-- bev

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK4RM wrote:
22 WPM

 

Is it fixed value, can you have less, or more of it? There is my table, for your information:

 

; 1= Speed grade
; 2= Number of 2 ms elements per dot
; 3= Dot time in ms
; 4= One minute dot number: ndot=60000 ms/dottime
; 5= Speed in words per minute: wpm = ndot / 50
; 6= Associated tone frequency in Hz
;       1             2      3      4      5      6
;                            ms     ndot   wpm    Hz
.equ    zSpeedX     = 55   ; 110    545    11     128
.equ    zSpeedD     = 40   ; 80     750    15     256
.equ    zSpeedS     = 27   ; 54     1111   22     512
.equ    zSpeedM     = 20   ; 40     1500   30     1024
.equ    zSpeedF     = 17   ; 34     1765   35     2048

 

jqmosToneAndSpeed: ; 16, 8...  values of rQMOTone
    .db 16,zSpeedX, 8,zSpeedD, 4,zSpeedS, 2,zSpeedM, 1,zSpeedF

Last Edited: Fri. Jun 24, 2022 - 11:23 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But it still audibly clicks.

Do you have other interrups running ?  

If yes it will be hard to avoid some clicks.

 

One way could be to make a loop at the start of the interrupt that wait until the timer have a known value. (but the delay has to be the length of the longest time your interrupt can be hold back)

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 Since I need frequencies only up to 800 Hz

Fine then.  When the key is pressed, start generating at zero degrees, there will be no click.  When the key is opened, stop at the next zero crossing (or even within 25%, 345degrees) & all will be well. 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!