Pages: 1 [2] 3 4 ... 6   Go Down
Author Topic: Posticipo segnale d'ingresso al variare della frequenza dello stesso  (Read 4429 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 0
Posts: 268
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Scusate avevo fatto un errore: il programma di dalubar funziona correttamente. Nello sketch c'è scritto di impostare il valore di delay nei registri però bisogna impostare il valore di partenza in modo che quello di overflow - partenza =delay, giusto?

Logged

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

esatto, anche se non è consigliatissimo da fare, devi ricordarti di farlo ad ogni overflow. se non erro puoi invece impostare il valore di overflow: questa tecnica è più pulita. Mettiamo il caso in cui perdi un interrupt dal timer perchè facevi altro, dato che non risetti il valore di partenza, che ripartirà da 0, non solo avrai perso un interrupt ma anche il prossimo verrà generato in modo erroneo
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 328
Posts: 22733
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

L'uso di un valore iniziale del contatore si fa quando l'intervallo da misurare non può essere ottenuto usando solo il prescaler.
Logged


Offline Offline
Sr. Member
****
Karma: 0
Posts: 268
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vorrei usare il timer2 perchè mi permette di ottenere con prescaler più piccoli, valori più piccoli di ritardo. dato che non ho bisogno di generare ritardi superiori a 200us, come si imposta l'overflow per ottenere il valore di delay richiesto con il timer2?

Altra cosa: per il timer 1 faccio TCNT1H e TCNT1L per settare il valore di partenza dal quale contare...ma con il timer 2 come si fa?
Perchè il compilatore mi da errore se faccio TCNT2H
Logged

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dal sito atmel scarica il manuale (la "bibbia") dell'atmega 328, e da lì vedi i registri di un timer a quale timer corrispondono, vedi i registri dl prescaler, quali valori prescaler puoi settare, e mille altre cose. credimi, se già lavori con i registri troverai sì tante cose in arabo (es. i2c, spi), ma anche delle ottime spiegazioni su TUTTI i registri
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Catania
Offline Offline
Sr. Member
****
Karma: 0
Posts: 346
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Stai prendendo il codice nel modo giusto...cioè come "spunto" e un "punto di partenza" per un approfondimento e una tua personale personalizzazione (non voleva essere un codice pronto all'uso).
Fai bene a usare il timer2, in modalità CTC. Per il valore del contatore basta usare TCNT2, dato che è un registro a 8 bit.
Per il resto segui il consiglio di Lesto riguardante la "bibbia" dell'ATMega328.

Quote
se non erro puoi invece impostare il valore di overflow: questa tecnica è più pulita. Mettiamo il caso in cui perdi un interrupt dal timer perchè facevi altro, dato che non risetti il valore di partenza, che ripartirà da 0, non solo avrai perso un interrupt ma anche il prossimo verrà generato in modo erroneo
Si, a lui conviene usare la modalità CTC che è facilmente ottenibile cambiando leggermente i registri del timer e praticamente non cambia il principio di funzionamento del sistema. Indubbiamente rende la tecnica più pulita in quanto non si deve ripristinare il valore iniziale. Sul "perdi un interrupt", invece, avrei quache perplessità, dato che solitamente è l'interrupt che interrompe qualcosa e non viceversa, e in un tipo di sistema come quello in oggetto sarà difficile che ci siano altri interrupt concorrenti.

Quote
mamma mia, mi usate i registri per impostare l'interrupt (quando attachInterrupt anadava più che bene)...
Che ti devo dire...volendo sorvolare sui quasi 200byte che l'istruzione attachInterrupt si "mangia" allegramente, usando direttamente il port mapping per settare il timer mi sembrava quasi una "stonatura" usare un'istruzione wiring...ma queste sono fissazioni mie smiley
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 268
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si l'idea del timer2 in CTC mi sembrava migliore. Ho già la bibbia e mi sto documentando ma ad esempio provando a scrivere il codice con timer2 posso generare un pwm in uscita sul pin11 ma non riesco a far partire il timer quando voglio e a fermarlo quando voglio.
Logged

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

. Sul "perdi un interrupt", invece, avrei quache perplessità, dato che solitamente è l'interrupt che interrompe qualcosa e non viceversa, e in un tipo di sistema come quello in oggetto sarà difficile che ci siano altri interrupt concorrenti.

difficile ma non impossibile, sopratutto se fai funzioni ISR troppo lunghe, o hai interrupt con frequenze troppo alte, o parli spesso via seriale (funziona ad interrupt), o usi PWM, o il timer1 che aggiorna la micros (e quindi la millis), etc.. non è così impossibile perdere un interrupt per concorrenza
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

0
Online Online
Shannon Member
****
Karma: 131
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i pin PWM usano i timer, certi pin un timer altri un altro. vedi "la bibbia" smiley
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Sr. Member
****
Karma: 0
Posts: 268
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

il codice per il timer2 è questo

Code:

#define ledPin 11
int val=0;
void setup()
{
  pinMode(ledPin, OUTPUT);
 
  //timer2
  noInterrupts();           // disable all interrupts
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2  = 0;

  OCR2A = 100;            // compare match register
  TCCR2B |= (1 << WGM22);   // CTC mode
  TCCR2B |= (1 << CS21);    // 32 prescaler
  TCCR2B |= (1 << CS20);
  TCCR2B &= ~(1 << CS22);
  TIMSK2 |= (1 << OCIE2A);  // enable timer compare interrupt
  interrupts();             // enable all interrupts
}

ISR(TIMER2_COMPA_vect)          // timer compare interrupt service routine
{
  val=!val;
  digitalWrite(ledPin, val);   // toggle LED pin
 
}

void loop()
{

}

Il problema è che cambiando il valore di OCR2A non cambia la durata della forma d'onda. e poi comunque vorrei che una volta raggiunto il valore, dentro ISR(TIMER2_COMPA_vect) si generi il segnale di uscita e si fermi il timer per poi riprendere all'arrivo di un nuovo fronte del segnale d'ingresso con il nuovo delay settato. Ma in OCR2A il valore caricato cosa è un intero? cosa rappresenta?

Logged

Catania
Offline Offline
Sr. Member
****
Karma: 0
Posts: 346
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ora hai il libro della "conoscenza"...usalo! smiley

Quote
difficile ma non impossibile, sopratutto se fai funzioni ISR troppo lunghe...
Si, Lesto, mi trovi d'accordissimo in tutto ciò che hai detto...solo che io mi riferivo specificamente al "suo" caso, cioè non credo che la sua applicazione contempli dialoghi con la seriale. Ovvio che dovendo performare il tutto per lo scopo prefissato si prenderanno tutte le (normali) precauzioni che si hanno quando si scrivono handler interrupt: ovvero poche istruzioni, uso minimo di registri, etc.
Per il millis, in verità ero convinto che Arduino gestisse uno stack interrupt...ma forse ricordo male io. Anzi se hai qualche notizia certa in merito ti sono grato smiley
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 268
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ci sono dietro da un bel pò ma non ci capisco. E' la prima volta che mi imbatto nei timer, ho bisogno di una bella spinta  smiley-confuse
Logged

Catania
Offline Offline
Sr. Member
****
Karma: 0
Posts: 346
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 Nella modalità CTC il timer viene azzerato ogni volta che il valore del contatore TCNT2 raggiunge un particolare registro denominato, appunto,  OCR2A.
E' come se l'hw del micro eseguisse una istruzione del tipo:
 
Code:
if (TCNT2 == OCR2A) ISR(TIMER2_COMPA_vect)
OCR2A, quindi, definisce il valore TOP per il contatore (0xFF).

Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 268
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok chiaro, ma nel codice che ho postato non mi cambia il duty cycle della forma d'onda cambiando il valore di quel registro, perchè?
E comunque se volessi fare che una volta raggiunto il conteggio, nella chiamata alla ISR addetta volessi stoppare la ripartenza del conteggio?

Perchè lui poi riparte da zero, invece io voglio che riparta solamente quando glielo dico io.
Logged

Catania
Offline Offline
Sr. Member
****
Karma: 0
Posts: 346
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Ok chiaro, ma nel codice che ho postato non mi cambia il duty cycle della forma d'onda cambiando il valore di quel registro, perchè?
Non può cambiare il duty cycle per il semplice fatto che la modalità CTC NON è una modalità PWM. Quindi otterrai sempre e solo periodi al 50%.

Quote
...io voglio che riparta solamente quando glielo dico io.
Allora si ritorna al sistema precedente, ovvero CTC + INT0
Logged

Pages: 1 [2] 3 4 ... 6   Go Up
Jump to: