Gestione Timer/Counter su AVR

Affinché si possa generare un RTC è necessario un elemento di sincronizzazione per il tempo. Per tale scopo, è possibile usare uno dei Timer/Counter presenti nell’AVR che, nel caso del TTiny13, è unico e identificato come Timer/Counter0. Questo contatore può essere pilotato mediante un prescaler: cambiando il valore del prescaler si possono ottenere incrementi del contatore ad ogni ciclo di clock del sistema, ogni 8 cicli, ogni 64 e così via, fino a un massimo di un incremento ogni 1024 cicli. Per ottenere l’RTC il contatore viene incrementato dal timer/counter clock che a sua volta è stato inizialmente generato dal clock di sistema. I due segnali di clock vengono divisi per opportuni fattori mediante un prescaler. In dettaglio:

dove:

SysClkFrq = System Clock Frequency

SysClkPre = System Clock Prescaler

TimClkFrq = Timer/Counter Clock Frequency

TimClkPre = Timer/Counter Clock Prescaler

Il  risultato ottenuto per il TimerClkFreq è in Hertz. Il numero  di cicli che avvengono in un tempo di T secondi è dunque (figura 1):

Figura 1: schema a blocchi

Dato che viene generato un interrupt (al seguente link una panoramica di articoli sull'interrupt) ogni 256 cicli del timer /counter, il numero di interrupt che avvengono nello stesso periodo T è dato da:

Per la realizzazione del Real-Time Clock sarà dunque sufficiente prevedere una variabile da incrementare all’occorrenza di ogni interrupt. In base al numero di interrupts conteggiati, sarà quindi possibile risalire al tempo trascorso. Come regola standard è importante ricordare che più piccolo è il valore impostato per il  prescaler, maggiore sarà il numero di interrupts con conseguente maggiore precisione del RTC. Per motivi di praticità, per intervalli di tempo molto lunghi sarà necessario aumentare  il valore di prescaler e ovviare alle imprecisioni che assumerà l’RTC avvalendosi dell’uso di variabili multiple.  Il listato riportato (listato 1) permette di risalire al numero di minuti trascorsi dall’inizio del conteggio.

/////////////////////////////////////////////////////////
// Includes
/////////////////////////////////////////////////////////
// Include avr-libc stuff
#include <avr/io.h>
#include <avr/interrupt.h>
#include “types.h”
/////////////////////////////////////////////////////////
// Defines
/////////////////////////////////////////////////////////
#define STOP_TIMER TCCR0B &= 0xF8
#define START_TIMER TCCR0B |= 0x05
/////////////////////////////////////////////////////////
// Global Varibles
/////////////////////////////////////////////////////////
BYTE minutes;
BYTE timeout;
WORD Ticks256;
/////////////////////////////////////////////////////////
// Timer 0 Overflow Interrupt handler
/////////////////////////////////////////////////////////
ISR(TIM0_OVF_vect)
{
   // 256 ticks have gone by
   Ticks256++;
   // If you do the math you’ll find that if the interrupt
goes off 275 times, a minute has passed
   if (Ticks256 == 275)
   {
      // a minute has passed
      minutes++;
      Ticks256 = 0;
   }
   // do something useful here if you wish;
   // like checking to see if minutes = 60 perhaps?
   if (minutes >= 60)
   {
       // do whatever you want.. you’ll probably want to reset
the minutes variable
       // so you can start counting all over again
   }
}
/////////////////////////////////////////////////////////
// Configure device configures the micro‘s setting per our
requirements
/////////////////////////////////////////////////////////
void ConfigureDevice(void)
{
   cli(); // disable interrupts just in case
   // configure PORTB... and other settings
   TCNT0 = 0x00; // clear Timer/Counter
   START_TIMER;
   // enable interrupts on timer 0 overflow
   TIMSK0 |= _BV(TOIE0);
   sei(); // enable interrupts
}
/////////////////////////////////////////////////////////
// Main function
/////////////////////////////////////////////////////////
void main(void)
{
   // Configure device
   ConfigureDevice();
   // clear minutes and Ticks
   minutes = 0;
   Ticks256 = 0;
   // Loop forever; the interrupts will take it from here
   while(1)
  {
  }
}
Listato 1

Iscriviti e ricevi GRATIS
Speciale Pi

Fai subito il DOWNLOAD (valore 15€) GRATIS

Una risposta

  1. Maurizio Di Paolo Emilio Maurizio Di Paolo Emilio 28 gennaio 2017

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Iscriviti e ricevi GRATIS
Speciale Pi

Fai subito il DOWNLOAD (valore 15€) GRATIS