Timer Interrupts

Does the Mega board support Timer Interrupts ?
If so, how to.......

Check the processor data sheet, and study this tutorial

1 Like

I had a look at that. Thanks.
I was referring to the ATmega 2560 Arduino. I imagine it is similar to the UNO.
In your sample code you have many variables such as TCCR0A, which I'm assuming are the internal registers in the MCU chip.
There must be a header file to cover these definitions, but I don't see that in your code ?

All ATmega chips have the same core. Memory and features vary by chip. Some lines are pin compatible and only memory varies.

The details, I get from the datasheet. The 328P full datasheet is around 350 pages on PDF at Microchip.com. Those are the last word, why look for less? There are loads of docs on the company site and the Arduino.cc Main Site has enough to make a manual out of starting with the reference and Library pages.
The is also, search words AVR LibC with complete reference to the C Standard Libraries for AVR chips. Bookmark folder time?

I see those register names compile so they must be built into the IDE

1 Like

Yes, there's a file for each board covered.
And board files can be added.

Is it possible to examine the board files ?
So I can a better handle on some of the definitions. Nick Gammon has been very good with his comments but I would like a bit more detail.

These definitions related to the avr registers are not in the board files. The location depends on how you installed the IDE. Under Windows you can find them e.g.

"C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\avr"

There are different files for the different AVR controllers. But you will not really find interesting information there. In the end it only maps the register names to its HW adresses. The main source of information to scope with timer registers directly is the datasheet.

1 Like

Then get the ATmega2560 full datasheet, free download at Microchip.

Why get less if that's what you want?

Maybe you need to learn how to net-search, doing it for you robs you of a necessary skill.

1 Like

Thanks for all the helpful replies guys. I have downloaded the ATmega2560 data manual. Of lot of useful stuff there. I see timers 0 & 1 are only 8 bit.
I wasn't aware, that in the Arduino environment, that you can access the chip's registers. Something I am very familiar with from the bad ol' days when we made
our own microprocessor boards ourselves and wrote everything in Assembler. I used a lot of Motorola chips.
Back when PC's were slow, and the early days of DOS, you were able to access
the 808x registers. I wrote entire programs for DOS (and early Windows) in assembler. It was the only way to get the best performance (and to possibly cause absolute mayhem). Later versions of Windows blocked this maverick method.

I do search the links where it says 'Read the Documentation'. However, annoyingly, this never takes you directly to the subject on hand.

Ahhh! I was less sure of where you're at but now... less less sure!

When I started looking at ASM for more than critical sections the increasing diversity of chips convinced me stay in high level languages.

Do you remember Main Loop programming in the 80's? On AVR's it's possible to keep the main loop running over 50KHz with several inputs and outputs as long as none of those is too high frequency.
And that brings me to, do you really need interrupt fast timing?

If you do get into AVR ASM.... the core has 32 general use registers that are pretty orthagonal and flexible.

Also if Rugged Circuits is still in business, they made the Quadram cards that extend Mega2560 RAM. Want 8 56K banks of heap and an 8K dedicated stack space? That one ran about $30 pre-COVID.

The way it works is:

  • The Arduino automatically adds a #include <Arduino.h> to your .ino file.
  • Arduino.h does #include <avr/io.h>
  • avr/io.h is provided by avr-libc and the compiler, rather than Arduino. Based on the compiler switch that specifies the chip type, io.h will do something like #include <avr/iom2560.h>
  • The various iomXXXX.h files are generated by Microchip (nee Atmel), supposedly automatically from the chip design specs. They should contain definitions for every register/feature of the chip, plus assorted constants for bitnumber and bitfield values, all in some vaguely regular naming convention that closely matches the chip datasheet.

Alas, for a typical modern Arduino install, the path is more like:

"C:\Users\YourUserName\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\avr\include\avr\iom2560.h"

It might be easier to look at the avr-libc sources online: avr-libc/include/avr/iom2560.h at main · avrdudes/avr-libc · GitHub
(github even implements some nice source-browsing features.)

3 Likes

I'm quite happy to stay with C and the Arduino environment. I've done enough assembler to last me a life time. The ATmega2560 data sheet/manual has all the info I need. 400+ pages without an index it seems. Ah, I see the index is at the end.
It has extensive samples, as you probably know, in both assembler and C.

All I want to do is plonk a value in a timer register, and when it counts down to zero, or counts up to my value, I then get an interrupt. I guess millis() would do this.
delay() is a pain as it holds up the process.

I like using interrupts.
With my current project I have a rotary encoder on one pin, another 2 phase encoder on two more pins and a push button switch on another pin. All on interrupt pins. D18/19/20/21 on the Mega board.

Some sections in my code require time delays from 0.1 sec up to 10 seconds max.
Ideal situation for Timer Interrupts.

What is AVR ?

Usually the "Table of Contents" set up in the PDF is pretty good.
Nice hierarchy, and a more-or-less standard structure.

Try the trick in this article:

Manage your counter inside the ISR, and then call your own function when it times out.

Well I've made a bit of progress. I have a blink LED program running using Timer1 interrupts (on a UNO - I mislaid my Mega USB cable).
I can alter the value in OCR1A to alter the frequency. I can also play around with the prescaler registers to further adjust the frequency.
I am using CTC mode (TCCR1B bits WGM12, CS12, CS10 all set).

Now instead of a continuous frequency, I just want a one-shot. So I thought I could disable further interrupts by clearing OCIE1A bit in TIMSK1 register at the end of my ISR. When I do this I get no interrupts at all.

I don't see why this is so, because I am clearing the Interrupt enable bit at the end of the ISR ??

You would think it would do at least one interrupt before encountering the instruction that cancels that particular interrupt ?

Arduino millis() low 8 bits are +/- 1 for reasons beyond this topic.

If timing matters enough to justify the overhead or for any reason needs to be closer than 1 ms, use micros() not millis(). Even micros has a grain of 4, it ticks every 4 usecs. And for short intervals, unsigned int micros is good for over 65 ms. AVR's are 8-bit after all.

1 Like

ISR that begins by turning interrupts off and ends by turning them back on? They have 85 cycles of save and restore compiled in.

Some clarification is needed here: your code doesn’t need to switch interrupts of or on.

When an interrupt occurs the Interrupt Controller will reset the I-bit and the processor jumps to the address from the vector concerned.

That address is placed there by the Arduino compiler when you program an ISR in your sketch.

At the end of your ISR the compiler will place a RETI instruction, that will enable interrupts by setting the I-bit.

Also, the compiler will check what registers are used in your ISR and save-and-restore only these.

Don’t do in your ISR what the compiler already does, it will restrain the optimalization, unless your application needs it.

The reason I did this is because I only want a one-shot.
I don't want continuous interrupts from the timer.
It's a bit crude I know. That is why I was asking, am I using the most suitable mode ? I'm current programming the Timer to CTC mode.

This is what I want.

  1. Initiate timer interrupts
  2. After suitable delay, interrupt occurs (polling not necessary - other processing continues - Timer counting in the background).
  3. Count reached. ISR signals end of timing period
  4. Switch off timer (don't want any more interrupts until such time as I want another delay period.)

Correct me if I'm wrong but both millis() and micros() need to be polled to determine when the delay is over?