Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Utilizzo Timer0.

Progetti, interfacciamento, discussioni varie su questa piattaforma.

Moderatori: Foto UtenteMassimoB, Foto UtenteWALTERmwp, Foto Utentexyz

1
voti

[1] Utilizzo Timer0.

Messaggioda Foto Utentelucaking » 13 giu 2019, 16:35

Ciao a tutti, cercando di fare un poco di pratica con l' utilizzo dei microcontrollori, mi sono dedicato all' uso dei timer e degli interrupt.
L' idea iniziale era: vediamo di capire come far lampeggiare due led a diversa velocità, anzi, vediamo se riesco a generare due onde quadre con frequenze diverse (e prestabilite :D ).
Ho cominciato usando un solo timer e tutto sembrava funzionare, alchè ho scritto il codice pari pari cambiando sol il numero del timer da 0 a 2, e qui mi sono accorto che qualcosa non quadra.
Il codice che ho scritto è il seguente:
Codice: Seleziona tutto
const int led1 = 3;
const int led2 = 5;

void setup() {
        DDRD = B11111111;
        noInterrupts();           // disable all interrupts
        TCCR0A = 0;
        TCCR0B = 0;
        TCNT0  = 0;
        TIMSK0 = 0;
        TIFR0 = 0;
        OCR0A = 30;                // compare match register
//        TCCR0A |= (1 << WGM01);          // CTC mode
        TCCR0A = B00000010;
//        TCCR0B |= (1 << CS00);    // prescaler
//        TCCR0B |= (1 << CS02);    // prescaler 256
        TCCR0B = B00000100;
//        TIMSK0 |= (1 << OCIE0A);  // enable timer compare interrupt
        TIMSK0 = B00000010;
       
        TCCR2A = 0;
        TCCR2B = 0;
        TCNT2  = 0;
        TIMSK2 = 0;
        TIFR2 = 0;
        OCR2A = 30;
//        TCCR2A |= (1 << WGM21);   // CTC mode
        TCCR2A = B00000010;
//        TCCR2B |= (1 << CS20);   // prescaler
//        TCCR2B |= (1 << CS22);    // prescale 256
        TCCR2B = B00000100;
//        TIMSK2 |= (1 << OCIE2A);  // enable timer compare interrupt
        TIMSK2 = B00000010;
        interrupts();             // enable all interrupts
}

ISR(TIMER0_COMPA_vect){          // timer compare interrupt service routin
        PORTD ^= _BV(led1);        //macro _BV setta il bit relativo al valore (bit to val)
}                                  // al posto di fare (1 << val)

ISR(TIMER2_COMPA_vect){
        PORTD ^= _BV(led2);
}

void loop() {
}


Ho utilizzato i due timer a 8 bit, settando i prescaler a clock/256 ed i registri di comparazione OCRnA allo stesso valore, ma cio che viasualizzo all' oscilloscopio è questo:
SDS00003.jpg
SDS00003.jpg (53.71 KiB) Osservato 1033 volte


Mi aspettavo di avere due forme d' onda identiche, al massimo leggermente sfasate ma con identica frequenza.
Ho fatto un po di prove ma nulla.
Non capisco cosa sbaglio.
Avatar utente
Foto Utentelucaking
898 2 5 8
Expert
Expert
 
Messaggi: 828
Iscritto il: 29 mag 2015, 14:28

1
voti

[2] Re: Utilizzo Timer0.

Messaggioda Foto Utentexyz » 13 giu 2019, 17:31

Scusa ma stai mischiando API di Arduino con la programmazione diretta dei registri del microcontrollore, o una o l'altra altrimenti si interferiscono a vicenda.

Se leggi la documentazione ufficiale del API di Arduino scopri che il timer0 è usato per tutte le funzioni sul tempo:

...
Timer0 is a 8bit timer.
In the Arduino world Timer0 is been used for the timer functions, like delay(), millis() and micros(). If you change Timer0 registers, this may influence the Arduino timer function.
...

Se vuoi programmare direttamente il micorocontrollore puoi farlo, non usare nessun include di Arduino, nessuna sua funzione, nessuna sua libreria. Puoi usare il compilatore GCC per AVR e la libreria standard C per gli AVR tutte e due presenti tra i file del IDE di Arduino.

La programmazione diretta del microcontrollore in C la funzione di partenza è la classica "main" nessun "setup" e "loop".
Avatar utente
Foto Utentexyz
5.930 2 4 5
G.Master EY
G.Master EY
 
Messaggi: 1572
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[3] Re: Utilizzo Timer0.

Messaggioda Foto UtenteIlGuru » 13 giu 2019, 17:50

Vedo la programmazione di arduino tramite i registri del micro.
Sono commosso. Davvero.
Non abbandonare questa strada per favore.
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.129 1 10 13
Master
Master
 
Messaggi: 1371
Iscritto il: 31 lug 2015, 23:32

0
voti

[4] Re: Utilizzo Timer0.

Messaggioda Foto Utentespeedyant » 13 giu 2019, 18:18

Ottimo Foto Utentelucaking!

Adesso una pausa, respiro profondo e studio del datasheet del micro e delle api di arduino!

Attenzione che il Timer0, Timer1 e Timer2 hanno delle "specifiche funzioni" all'interno dell'ecosistema arduino...
Son quello delle domande strane!
Avatar utente
Foto Utentespeedyant
3.451 3 6 8
Master
Master
 
Messaggi: 2430
Iscritto il: 9 lug 2013, 18:29
Località: Torino

0
voti

[5] Re: Utilizzo Timer0.

Messaggioda Foto Utentelucaking » 13 giu 2019, 19:12

In realtà stavo solo facendo qualche prova, pensavo che "saltare qualche passaggio" non comportasse grossi problemi, invece il gioco si complica....

Sapevo che il timer0 di arduino fosse usato per quelle funzioni, ma credevo che non essendo presenti nel mio codice non dovessero influire, quindi mi confermate che il problema è questo?

xyz ha scritto:Se vuoi programmare direttamente il micorocontrollore puoi farlo.

Eh, lo so, basterebbe essere capaci.... :oops: :D

xyz ha scritto:.... non usare nessun include di Arduino, nessuna sua funzione, nessuna sua libreria. Puoi usare il compilatore GCC per AVR e la libreria standard C per gli AVR tutte e due presenti tra i file del IDE di Arduino.

La programmazione diretta del microcontrollore in C la funzione di partenza è la classica "main" nessun "setup" e "loop".

In realtà essendo abbastanza profano, sono partito proprio da li, in effetti nei file dell' ide di arduino ho trovato il main.cpp, che non fa altro che chiamare una funzione init(), controllare qualcosa sull' USB, chiamare setup() e infine loop() che ad ogni ciclo controlla se c' è qualcosa sulla seriale, il problema è che poi mi perdo e non trovo ad esempio dov'è definito cosa fa init().
Avatar utente
Foto Utentelucaking
898 2 5 8
Expert
Expert
 
Messaggi: 828
Iscritto il: 29 mag 2015, 14:28

1
voti

[6] Re: Utilizzo Timer0.

Messaggioda Foto Utentexyz » 13 giu 2019, 20:43

lucaking ha scritto:Sapevo che il timer0 di arduino fosse usato per quelle funzioni, ma credevo che non essendo presenti nel mio codice non dovessero influire..

Anche se non sono presenti nel tuo codice funzioni sul tempo, API di Arduino inizializza hardware prima di chiamare "setup" e "loop" in base alle sue esigenze.

Non devi mischiare codice concepito per mascherare la complessità della programmazione diretta del micro-controllore, come le API di Arduino o la programmazione diretta di un micro-controllore.

il problema è che poi mi perdo e non trovo ad esempio dov'è definito cosa fa init().

Arduino è open source qui trovi i sorgenti ufficiali, poi cercare cosa fanno le varie parti:

https://github.com/arduino/Arduino
Avatar utente
Foto Utentexyz
5.930 2 4 5
G.Master EY
G.Master EY
 
Messaggi: 1572
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[7] Re: Utilizzo Timer0.

Messaggioda Foto Utentelucaking » 14 giu 2019, 7:47

xyz ha scritto:Non devi mischiare codice concepito per mascherare la complessità della programmazione diretta del micro-controllore, come le API di Arduino o la programmazione diretta di un micro-controllore.


Uffa, però così mi rovini tutto il divertimento.... :D
Comunque non mi sento di promettertelo. :D

Ieri sera ho trovato la definizione della funzione init() nel file wiring.c, della suite di arduino, e non fa altro che settare i registri riguardanti i timer e gli interrupt ad essi collegati.
Quello che non capisco è perché se successivamente, con la funzione setup() io li setto a mio piacere qualcosa fallisce.

Esiste un modo per "debuggare" il codice di arduino?
Forse debug è una parola grossa, intendo eseguirlo riga a riga e se serve richiedere il valore dei vari registri del micro?
Avatar utente
Foto Utentelucaking
898 2 5 8
Expert
Expert
 
Messaggi: 828
Iscritto il: 29 mag 2015, 14:28

0
voti

[8] Re: Utilizzo Timer0.

Messaggioda Foto UtenteIlGuru » 14 giu 2019, 9:02

Quando compili uno sketch tra i vari file che vengono generati ce n'è uno che contiene l'assembly che viene prodotto dal compilatore. Meglio di quello per debuggare e capire cosa fa non c'è niente
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto UtenteIlGuru
4.129 1 10 13
Master
Master
 
Messaggi: 1371
Iscritto il: 31 lug 2015, 23:32

2
voti

[9] Re: Utilizzo Timer0.

Messaggioda Foto Utentexyz » 14 giu 2019, 13:18

lucaking ha scritto:Esiste un modo per "debuggare" il codice di arduino?

Non esiste il codice di Arduino, si programma con un subset del C/C++. Arduino è una famiglia di board, un API di programmazione e un IDE programmato in Java, nulla di più.

Se per debug intendi l'esecuzione passo passo del codice sulla board questo è possibile solo sui micro-controllori compatibili col JTAG o DebugWire (non tutti i micro-controllori Atmel hanno questa funzione), con una interfaccia hardware via JTAG o DebugWire e con un software in grado di interfacciarsi. Per un utente normale questa strada non è praticabile.

Di solito chi programma una board Arduino usa come debug la stampa via seriale, con delle "printf" di dati significativi messi nel codice (rimossi nella versione finale).

Se vuoi vedere il codice assembler del tuo codice in C/C++ con il compilatore GCC per AVR con l'opzione "-S" puoi salvare il file assembler, dalla documentazione ufficiale:

https://gcc.gnu.org/onlinedocs/gcc-9.1. ... ml#index-S
Avatar utente
Foto Utentexyz
5.930 2 4 5
G.Master EY
G.Master EY
 
Messaggi: 1572
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

1
voti

[10] Re: Utilizzo Timer0.

Messaggioda Foto Utentelucaking » 14 giu 2019, 15:07

Intanto grazie a tutti per le risposte e la pazienza.


speedyant ha scritto:Adesso una pausa, respiro profondo e studio del datasheet del micro .....

Avevi ragione Foto Utentespeedyant, la risposta ai miei insuccessi era li, e neanche tanto nascosta.
22. TC2 - 8-bit Timer/Counter2 with PWM and Asynchronous Operation

22.1. Features

• Channel Counter
• Clear Timer on Compare Match (Auto Reload)
• Glitch-free, Phase Correct Pulse Width Modulator (PWM)
• Frequency Generator
• 10-bit Clock Prescaler
• Overflow and Compare Match Interrupt Sources (TOV2, OCF2A, and OCF2B)
• Allows Clocking from External 32kHz Watch Crystal Independent of the I/O Clock

Bastava leggere in maniera un po' meno superficiale per capire che i bit per la configurazione del prescaler nel Timer2 sono diversi da quelli dello 0 e dell' 1. :oops:

Beh, alla fine funziona:
SDS00006-100+100.jpg
SDS00006-100+100.jpg (45.48 KiB) Osservato 910 volte

Codice: Seleziona tutto
const uint8_t led1 = 3;
const uint8_t led2 = 5;

void setup() {
        DDRD = B00101000;        //set pin 3 and 5 as output
        cli();                // noInterrupts();

        TCCR0A = B00000010;        //set CTC mode (clear timer on compare match)
        TCCR0B = B00000101;        //set prescaler 1024
        OCR0A = 77;                // compare match register (16Mhz/1024)/77 = 200 per-sec
        TIMSK0 = B00000010;
        TCNT0  = 0;
       
        TCCR2A = B00000010;
        TCCR2B = B00000111;        //set prescaler 1024 (different bits from Timer0)
        OCR2A = 77;
        TIMSK2 = B00000010;
        TCNT2  = 0;

        sei();                //interrupts();
}

ISR(TIMER0_COMPA_vect){          // timer compare interrupt service routin
        PORTD ^= _BV(led1);        //macro _BV setta il bit relativo al valore (bit to val)
}                                  // al posto di fare (1 << val)

ISR(TIMER2_COMPA_vect){
        PORTD ^= _BV(led2);
}

void loop() {
}

Ovviamente così facendo, in setup() ho riscritto alcuni dei registri che la funzione init() definita nel file wiring.c dell' API di arduino aveva precedentemente settato mandando a spasso tutte le funzioni che fanno uso di questi timer.

Sono consapevole del fatto che siano esperienze fine se stesse, ma sono comunque soddisfatto perché a mio modo di vedere aprono un minimo gli occhi su cio che spesso usiamo senza capirci un H.
Probabilmente partendo da un approccio piu pragmatico non avrei mai perso alcune serate a spulciare il datasheet del micro ne tantomeno i file dell' API di arduino o i vari file header dell' AVR per provare a capirci qualcosa.
Avatar utente
Foto Utentelucaking
898 2 5 8
Expert
Expert
 
Messaggi: 828
Iscritto il: 29 mag 2015, 14:28

Prossimo

Torna a Arduino

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti