tech-support

*/ ?>

Introduction

In third part of low-level programing AVR microcontrollers we'll be introduced with some new registries. We will use timer interrupts to create our own delay function in order to blink the LED on pin13. C programing will be reused and in the next tutorial we'll switch to Assembler. So far we've done these: Lesson 1. Blinking LED diodes Lesson 2. Bitwise operators

What is a timer?

Timer (more precisely Timer/Counter) is a piece of hardware implemented in to a microcontroller (other controles and processors also have it).Timer is programed over special registries. For example, we configure a prescaler, his mode, waveform generator which will be explained more thoroughly soon. While we work with Croduino/Arduino (Atmel AVR ATmega328 microcontroller) we will concentrate on that part again. ATmega328 has three timers: timer0, timer1 i timer2. Timer0 and timer2 are 8bit timers, timer1 is 16bit. Main difference is the resolution, 8bit has 256 values and 16bit have 65536 for bigger a 16bitno 65536 for bigger resolutions. All timers rely on system clocks, on Croduino/Arduino it is 16Mhz. All timers on Arduino firmware (bootloader) are configured on 1kHz frequency and all interrupts are enabled. In case you are here for Arduino Timer registry, skip to this section how to use it. Imagine that you have a counter which on a press of a button increases by one. Timer/counter works on the same principle: counts beats of a clock. We've mentioned that the speed of counting is 16 million beats per second, aproximately  63ns per beat or operation. 8bit timer will count from 0-255 and 16bit from 0-65535. Time needed for a counter to reset is 256/16.000.000= 16us, and 65536/16.000.000 = 4ms for a 16bit registry. it's not a really practical way to blinka a LED every 1 second. Instead of controling the speed of timer/counter we will use something called prescaler. In the next section we will focus on registries in charge of timers, and in one of them we will define  the prescaler. Prescaler Prescaler defines the speed of a certain timer (timer0, timer1 or timer2) according to this formula: (timer speed [Hz]) = (Arduino clock speed (16MHz) [Hz]) / prescaler According to  datasheet prescaler has defined values of 1, 8, 64, 256 i 1024. It can be seen that prescaler 1 will increment the clock of 16MHz, prescaler 8 2Mhz, prescaler 64 250kHz etc. Simply said, prescalerset to 1024 will after every 1024 beats of 16Mhz timer/counter add 1 on his counter (timer0, timer1, timer2). To make it simple, In the time while John eats 1024 hamburgers, Bob will eat 1. Let's get back to timers. First new registry we will mention in this tutorial is OCR - output compare register in which we will save compare match value. Does it seem to be too much at once? It is not, we've already mentioned all of the above, and now they've been given the official names. Insert it in the formula so we can visualise it better: formula Explanation: 16Mhz - speed of Arduinos clock timer/counter, we insert it as 16.000.000 Hz brzina.timera - considering that we want to blink the LED every second, we insert the frequency 1Hz -1 - counter number 0 so we insert -1 in the formula compare match registar From the table we can see that the smallest prescalar we can use is 256 for 16bit timer 1. Reason? Value 62499 Can be saved in 16bit registry of timer1. To measure counters in frequency of 1Hz(1 second) we can use prescaler 1024, but it is much more accurate to use a smaller prescaler. In none of this cases we can't use 8bit timers timer0 and timer2. Now when we've chose the timer and prescaler it's time to meet the registries that we need to set up. Registries For more check datasheet TCCR1A Timer count control register - 0b00000000 (normal)(normal) TCCR1B Timer count control register - 0b00000100 (no icr)(256-prescaler) TCCR1C Timer count control register - 0b00000000 (no force) OCR1AH output compare register - high byte 0xF4 OCR1AL output compare register - low byte 0x23 On this registries we set up calculated compare match value, 62499. Since we set up highi and low byte  separately we change 62499 from decimal to hexadecimal and that is 0xF423. So high byte is  0xF4, and low byte 0x23. TIMSK1 timer interrupt mask 0b00000010 (output compare u enable - OCIE1A) DDRB PORTB DDRB i PORTB registries we've already mention in the first lesson.

C code

 
void setup() {
  DDRB = B00100000; // portB5 (pin13) is set as output

  cli();   //we are disabling all interrupts, so the timer interrupt won't be distrupted by another interrupt with higher priority
  TCCR1A = 0b00000000;
  TCCR1B = 0b00000100;
  TCCR1C = 0b00000000;
  OCR1AH = 0xF4;
  OCR1AL = 0x23;
  TIMSK1 = 0b00000010;
  sei();   // we re-enable interrupts including timer interrupts
}

ISR(TIMER1_COMPA_vect) { // timer compare interrupt service routine
  PORTB ^= 0b00100000;   // XOR operator, if the LED is on we turn it off and vice versa
}

void loop() {
}

Timer library

There are a couple of timer libraries that use different functions. We will get busy only with those that we'd use in the example of blinking LED, find more on Arduino references. Timer0 For functions it represents itself as delay(), millis() and micros(). delay() - stops the microcontroller for a given time in miliseconds, there is also this function delayMicroseconds()  etc. millis() - function that has saved time from the start of microcontroller  or its restart in miliseconds. Untill  overflow it can count for 15-ish days. micros() - function that has saved time from the start of microcontroller or its restart in microseconds. Untill overflow it can count for 70-ish minutes. Example of blinking LED without delay() function:
unsigned long proslo_vrijeme = 0;        // we generaly use unsigned long for variables that save time

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {

  unsigned long trenutno_vrijeme = millis();  // saves current time from the start of the microcontroller

  if (trenutno_vrijeme - proslo_vrijeme >= 1000) {
    proslo_vrijeme = trenutno_vrijeme; // saves when did the LED blink last time

    digitalWrite(13, digitalRead(13) ^ 1); // change the state of LED
  }
}

Conclusion

Besides the fact that the functions we've just worked with allow us to multitask, they give us a much better insight in the duration time of the process itself. If we compare blinking of an LED on this way and the one on Arduino digitalWrite() and delay() functions, we can see that after some time we have deviations in moments when the LED blinks. For much accurate work monitoring of microcontrollers and interrupts it is necessary to go down a bit on program language scale. After short introduction lessons we will start with Assembly programming.

How to solder our LED dice solder kit.

Cool tutorial which will show you how to write your own Arduino library: what is consists of and how to make it work.