Atmel AVR064 STK502 BOARD.

Sto curiosando nel sito di atmel ed ho visto questo: http://www.efo.ru/ftp/pub/atmel/_AVR_MCUs_8bit/_Technical_Library/tools/stk/stk502/index.html

Dove dice :On-board 32 kHz Clock Oscillator for Easy RTC Implemetations Quindi anche con il 328 facendo oscillare un quarzo a 32KHZ si possono implementare le funzionalità di un RTC che di solito ho visto che si preferisce comprare.

Quali vantaggi ci sono ad avere un RTC esterno anzichè interno?

No perchè c'è anche il codice sorgente dell'RTC.

Però non ho idea di come collegare il quarzo, forse bisogna fare un osclillatore esterno ed il segnale iniettarlo in qualche pin.

Chi ne sa qualcosa?

Ciao.

Io l'ho visto fare su di un pic... si usano due piedini collegati direttamente al quarzo se non sbaglio...

l'rtc intrno ha una risoluzione bassissima e si mangia vari secondi al giorno, un vero rtc è molto più preciso di solito ed in più ha anche un sistema di compensazione dell'errore introdotto dalla variazione di temperatura.

No, aspetta Brain. Secondo me non è come dici. Riporto dal datasheet dell'Atmega328. pag. 156:

The clock source for Timer/Counter2 is named clkT2S. clkT2S is by default connected to the main system I/O clock clk IO. By setting the AS2 bit in ASSR, Timer/Counter2 is asynchronously clocked from the TOSC1 pin. This enables use of Timer/Counter2 as a Real Time Counter (RTC). When AS2 is set, pins TOSC1 and TOSC2 are disconnected from Port C. A crystal can then be connected between the TOSC1 and TOSC2 pins to serve as an independent clock source for Timer/Counter2. The Oscillator is optimized for use with a 32.768 kHz crystal.

Quindi essendo la sorgente un quarzo esterno, non usi il clock di sistema per cui tutto dipende dalla qualità del quarzo e dall'ottimizzazione del circuito. Puoi così farti effettivamente un RTC, però devi gestirti tu tutta la parte di conteggio ora/data, perché il datasheet non mi pare che specifichi che lo fa il chip. Ti dice solo che ti mette a disposizione il timer2.

Puoi così farti effettivamente un RTC, però devi gestirti tu tutta la parte di conteggio ora/data, perché il datasheet non mi pare che specifichi che lo fa il chip. Ti dice solo che ti mette a disposizione il timer2.

Si il codice sarebbe questo preso da Atmel, ma perchè un RTC esterno oltre all’orologio fornisce informazioni sul calendario?

//  Include files

#include "Main.h"

#include "RTC.h"

// Lookup table used to determine the highest date in a specific month

unsigned char MaxDate[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

/*! \brief  Start Timer/Counter2 in asynchronous operation using a

 *          32.768kHz crystal.

 */

void RTC_init(void)

{

    Delay(1000);            // wait for 1 sec to let the Xtal stabilize after a power-on,

    __disable_interrupt();  // disabel global interrupt

    TIMSK2 = 0;             // disable OCIE2A and TOIE2

    ASSR = (1<<AS2);        // select asynchronous operation of Timer2

    TCNT2 = 0;              // clear TCNT2A

    TCCR2A = (1<<CS22) | (1<<CS20);             // select precaler: 32.768 kHz / 128 = 1 sec between each overflow

    while(ASSR & (0x01 | 0x04));       // wait for TCN2UB and TCR2UB to be cleared

    TIFR2 = 0xFF;           // clear interrupt-flags

    TIMSK2 = (1<<TOIE2);    // enable Timer2 overflow interrupt

    __enable_interrupt();                 // enable global interrupt

    // initial time and date setting

    HOUR = 8;

    MINUTE = 0;

    SECOND = 0;

    DAY = 4;

    MONTH = 11;

    YEAR_LO = 2;

    YEAR_HI = 20;

}

/*! \brief  Updates the time and date variables

 */

void Time_update(void)
{
   unsigned char LeapYear = FALSE;

    //the variable SECOND gets updated in the Timer0 Overflow Interrupt Routine every second

    if(SECOND > 59)                         // if one minute

    {

        SECOND = 0;                         // clear SECOND

        MINUTE++;                           // increment MINUTE

        if(MINUTE > 59)                     // if one hour

        {

            MINUTE = 0;                     // clear MINUTE

            HOUR++;                         // increment HOUR

            if(HOUR > 23)                   // if one hour

            {

                HOUR = 0;                   // clear HOUR

                DAY++;                      // increment DAY

                if(MONTH == 2)              // if it's February

                {

                    // check for leap year

                    if(!YEAR_LO)                        // if YEAR_LO = 0, (a century has passed)

                    {

                        if(!(YEAR_HI%4))                // check if YEAR_HI is divisible by 4

                            LeapYear = TRUE;                // then it is a leap year

                    }

                    else if(!(YEAR_LO%4) & (YEAR_LO != 0))  // else if YEAR_LO is divisible by 4 and not zero

                        LeapYear = TRUE;                    // then it's a leap year

                }

                if(DAY > (MaxDate[MONTH] + LeapYear))   // if a whole month has passed

                {

                    DAY = 1;                // clear DAY

                    MONTH++;                // increment MONTH

                    if(MONTH > 12)          // if one year

                    {

                        MONTH = 1;          // clear MONTH

                        YEAR_LO++;          // increment YEAR_LO

                        if(YEAR_LO > 99)    // if one century

                        {

                            YEAR_LO = 0;    // clear YEAR_LO

                            YEAR_HI++;      // increment YEAR_HI

                            if(YEAR_HI > 99)    // if 100 centuries

                                YEAR_HI = 0;    // the AVR is still going strong :)

                        }

                    }

                }

            }

        }

    }

}

/*! \brief  Increment the varible SECOND by one - interrupt function.

 */

#pragma vector = TIMER2_OVF_vect

__interrupt void TIMER2_OVF_interrupt(void)

{
    SECOND++;               // increment second
}

Ma sai che un quarzo da un vecchio orologio guasto lo smonto volentieri, se ha questa frequenza 32.768kHz
provo ad impementare delle funzioni di alto livello più digeribili.

Grazie Brain, Leo.
Ciao.

Un RTC ha dei registri interni che vengono aggiornati man mano che scorre il tempo e che contengono i secondi, minuti, ore, giorno della settimana, giorno del mese, mese ed anno nonché effettuano anche la compensazione per l'anno bisestile e come passare da un mese all'altro. Tutte queste funzioni non credo che il timer dell'Atmega te le faccia, dovresti farlo tu a livello di codice.

In genere i quarzi per orologio lavorano a 32768 Hz, è quasi uno standard.

Facevo caso ad una cosa. Rileggendo quell'estratto sono andato a ricercare quei pin, TOSC1 e TOSC2.... Ebbene, sono i pin normalmente deputati all'utilizzo del quarzo esterno, non sono altri 2 pin (come pensavo). Quindi l'uso di un quarzo da 32768 Hz per usare l'Atmega328 ti obbliga ad usare l'oscillatore interno come fonte di clock per il sistema, perciò ottieni sì un RTC ma anche un micro che va minimo a metà velocità (l'oscillatore va a 8 MHz).

Me ne sono accorto pure io, però leggi questo http://www.atmel.com/dyn/resources/prod_documents/doc1259.pdf

Dove la descrizione dice: Real-Time Clock using the Asynchronous Timer on tinyAVR and megaAVR devices.

Nel doc fà riferimento al ATmega103 che ha TOSC separato dall'Xtal, ora non so se hai qualche attiny che ha i pin separati.

Peccato di avere scoperto che con l'arduino non si pùo fare, specie dopo esseremi procurato un quarzo preso da un vecchio CASIO ormai non funzionante.

Ciao.

Ho letto velocemente quel documento. Esso dice che quanto descritto si applica a tutti gli Atmega con modulo RTC integrato, come l'Atmega103 a cui quel documento fa riferimento. Difatti nella descrizione del micro si legge:

Real-time Counter (RTC) with Separate Oscillator

Ho aperto poi per scrupolo il datasheet dell'Atmega328 ed ho letto tra le sue caratteristiche:

Real-time Counter with Separate Oscillator

Quindi in teoria anche questo micro ha un modulo RTC integrato. Ciò significa che esso opera in modo asincrono dal clock di sistema. Anche il datasheet lo specifica: anche in condizioni di grossi carichi di lavoro sulla CPU, il modulo RTC, operando con il suo clock separato, mantiene la sua precisione. Interessante.

PS: l'Attiny non dovrebbe avere questo modulo.

Tratto dal d.s. ristretto del 328: Unstable 32kHz Oscillator The 32kHz oscillator does not work as system clock. The 32kHz oscillator used as asynchronous timer is inaccurate. Problem Fix/ Workaround None. Penso che si capisca anche se è in inglese :P

Si quello è scritto anche nella sezione Errata del datasheet esteso, ci sarebbe da provare cosa comporta, perchè se l'errore introdotto e quello spiegato qui http://www.atmel.com/dyn/resources/prod_documents/doc1259.pdf

Con un clock di 8MHZ e calibrando l'oscillatore rc grazie al quarzo da 32KHZ l'errore dovrebbe essere ancora minore e sopratutto non è cumulativo.

Dico questo perchè non è detto che ci serve un orologio di precisione in tutti i progetti, se perde un secondo all'anno mi sta pure bene, ma evito di acquistare un RTC esterno interfacciarlo ecc.

Ciao.

:slight_smile: un secondo all’anno sarebbe oro
mediamente un rtc come il ds1307 ha un errore di +o- mezzo secondo al giorno e non credo che l’atmega riesca a fare di meglio.

mediamente un rtc come il ds1307 ha un errore di +o- mezzo secondo al giorno e non credo che l'atmega riesca a fare di meglio.

ahaha, si allora sogna, niente da fare, io credevo fossero più precisi cio circa 3 minuti all'anno. Comunque anche se un atmega sballasse di 10 all'anno per certi progetti potrebbe essere tollerato.

Comunque sarebbe da provare e verificare, quel The 32kHz oscillator used as asynchronous timer is inaccurate, non dice quanto non è accurato ed in riferimento a cosa, se si riferisce a quello che dice il doc1259 allora è da provare, solo che con il 328 non si può usare un quarzo di sistema separato ma bisogna usare l'oscillatore rc interno, mentre con ATmega103 si possono usare entrambe i quarzi perchè i pin sono separati.

Ciao.

L'oscillatore interno rc è mooolto inpreciso e nella migliore delle ipotesi l'errore sarebbe di vari secondi al giorno. Anche i quarzi non sono di per sè garanzia di precisione, nei datasheet questo parametro è specificato come errore in PPM (parti per milione). quindi anche usando un buon rtc con un quarzo scarso si otterrebbero risultati pessimi, poi c'è anche l'effetto della temperatura... provate a calcolarvi la deviazione da qui: http://www.maxim-ic.com/tools/calculators/rtc.cfm Per il momento la soluzione migliore per gli rtc è quella di inglobare in quarzo interno e autocalibrarsi in base alla temperatura del die, questa è la tecnologia tcxo, compensated crystal oscillator (TCXO) che incorporano rtc moderni come il ds3231.

MauroTec: allora è da provare, solo che con il 328 non si può usare un quarzo di sistema separato ma bisogna usare l'oscillatore rc interno, mentre con ATmega103 si possono usare entrambe i quarzi perchè i pin sono separati.

Sul 328 è possibile usare il Timer2 come rtc prendendo come sorgente il clock principale tramite il prescaler del timer2. Attenzione che il Timer2 serve per il PWM, se viene utilizzato come RTC si perdono alcuni pin PWM di Arduino, da verificare quali.

A me sembra carissimo http://it.rs-online.com/web/search/searchBrowseAction.html?method=getProduct&R=0419429

Vero fà tutto lui, ma sempre caro è.

Ciao.

:stuck_out_tongue_closed_eyes: e mica avevo detto che era lowcost.. guarda questa miniguida (molto parziale) http://www.maxim-ic.com/design_guides/en/REAL_TIME_CLOCKS_2.pdf che mi sembra abbastanza riassuntiva :)

Non avete pensato che per realizzare un RTC basta prendere una qualunque mcu 8 pin low cost, collegargli un quarzo preciso, scrivere un programmino che conta i cicli del timer e li converte in data ora, interfaccia I2C/SPI e con meno di 3 Euro avete risolto.

è vero astrobeed, si può fare anche così, tutto però dipende dalla precisione richiesta. usando un mcu per migliorare la resa e compensare la risposta in temperatura dovresti misurare anche quella e ricalibrare al volo l'oscillatore in base a quella, e poi si introdurrebbe anche l'errore del sensore di temperatura usato ecc... un sistema come quello che dici non è paragonabile ad un buon rtc come precisione alla lunga , ma se non è richiesta tutta questa precisione và più che bene :)

è vero astrobeed, si può fare anche così, tutto però dipende dalla precisione richiesta.

Appunto era quello che dicevo, però ci sarebbe da vedere qual'è l'errore in un'anno o giorno, considerando le variazioni di temperature da 7 a 32 gradi del nostro clima.

Se dopo un'anno anzichè segnare 00:00 segna 00:10 e non oltre io penso che può andare, e se il micro non fà grandi lavori si potrebbe anche pensare di usare un solo micro, tanto il timer funziona in backgroung.

Rimane da stabilire se usare il Timer2 e il prescaler e ricavare il clock dal quarzo da 16MHZ esterno, oppure montare come quarzo esterno uno da 32768 HZ ed usare l'oscillatore rc interno.

Per questa ultima soluzione sembra che si possa calibrare l'oscillatore rc interno grazie al quarzo da 32768HZ.

Cosa consigliate?

Ciao.