Set timer for OrangutanX2

hi, i want to use the ADC functions of OrangutanX2 to detect a voltage output from a current sensor. If the overcurrent state is over a time, warning message will be shown.
So i want to set a timer with timer interrupt. When the current is over, timer is on and start to calculate the time. Lastly timer interrupt is on and warning message is shown.
How to set the timer and timer interrupt in OrangutanX2? i have read the datasheet of ATmega644 but it sounds so complex.
Thank you for your help.

Hello.

The datasheet can certainly seem intimidating at first, but it has a lot of good information in there. Here are a few things you will need to do:

  1. include <avr/interrupt.h>

  2. globally enable interrupts by calling sei(); You can disable all interrupts by calling cli();

  3. You can enable timer interrupts using the bits of the TIMSKx register. For example, you can enable timer1 overflow interrupts by setting:

TIMSK1 |= (1 << TOIE1);

Timer overflow interrupts are generated whenever the timer’s counter hits zero. The timer1 counter is the two-byte register TCNT1. If you use the timer in normal mode, TCNT1 will count up to 0xFFFF (65535) and then will overflow back to 0, at which point a timer1 overflow interrupt will be generated (assuming TIMSK1 has its TOIE1 bit set and the global interrupt flag is set, as happens when you call sei()).

  1. Configure your desired timer to work as needed for your application. This involves determining which mode you want it to run in and at what rate you want the timer to “tick”. In general, the timers are clocked by the system clock (which is 20 MHz on the Orangutan X2), but you can set a “prescaler” that will divide this clock down to something slower. For example, if you use a prescaler of 8, the timer will tick at a rate of 20MHz/8 = 2.5 MHz. You can use the CS12:0 bits of the TCCR1B register, for example, to specify the timer1 prescaler, for example. See the table on datasheet page 128 for more information. You should select a prescaler based on the time resolution you need and the timespan you want to be able to time.

The datasheet does a good job of explaining what the various timer modes are. You will probably want to use “normal” mode, in which the timer counts up to its maximum value, incrementing the counter once per timer tick, at which point it overflows back to zero. However, you could also consider “CTC” mode, in which the timer counts up to a value you can specify before overflowing back to zero.

  1. Write your interrupt service routine (ISR). The following code will be called when the timer1 counter overflows, assuming this interrupt has been properly enabled with TIMSK1 and sei():

ISR(TIMER1_OVF_vect)
{
// your code here
}

Putting it all together, if I want to have a timeout period of one second, I could do the following (please note that this code is untested, but hopefully it’s enough to get you started):

#include <avr/interrupt.h>

unsigned char first = 1;  // global

ISR(TIMER1_OVF_vect)
{
  // code to show warning message
  first = 1;
  TIMSK &= ~(1 << TOIE1);  // disable timer1 overflow interrupts
}

int main()
{
  sei();
  TCCR1B = 0x05;  // select prescaler of 1024, so timer1 ticks at 20MHz/1024 = 19.5kHz
  while (1)
  {
    if (overcurrent && first)
    {
      TCNT1 = 0xFFFF - 19531;  // start the counter so that it will take 1s to overflow
      TIMSK1 |= (1 << TOIE1);  // enable timer1 overflow interrupts
      first = 0;
    }
    if (!overcurrent)
    {
      TIMSK1 &= ~(1 << TOIE1);  // disable timer1 overflow interrupts
      first = 1;
    }
  }
  return 0;
}

- Ben

Thank you for your help,
when i follow your code, the build is failed with error:
…/ox2m644_test.c:176: error: ‘TIMSK’ undeclared (first use in this function)

What does it mean? Do i need to include other header files?

I told you the code was untested, so you need to be on the lookout for minor typos. You can see that everywhere in my above post I talk about TIMSK1, but I guess I made a typo in one place and forgot the 1 at the end. I urge you to understand what you’re doing when you use my code and modify it for your needs rather than just copying what I wrote. It’s meant to help you understand what you read in the datasheet, not to completely solve your problem.

- Ben