Ciao a tutti e Buona Natale.
Sto tentando di realizzare un controllo PWM in cui avere due uscite in push pull, ovvero una dritta e una negata con arduino uno.
utilizzo questo codice per settare il pin digitale 3 per avere una quadra a 100khz con duty variabile impostando OCR2B.
TCCR2A = 0x23; // imposto “pin high on overflow”, e “clear on compare match with OCR2B
TCCR2B = 0x09; // seleziono come sorgente di clock I 16MHz di sistema senza prescaler
OCR2A = 159; // inizializzo il top level match a 159 ->f_PWM=100kHz
Vorrei avere la stessa cosa su un altro pin digitale, che però sia invertito rispetto a questo e che quindi segua il comportamento negato di questo.
ekjk:
Ciao a tutti e Buona Natale.
Sto tentando di realizzare un controllo PWM in cui avere due uscite in push pull, ovvero una dritta e una negata con arduino uno.
utilizzo questo codice per settare il pin digitale 3 per avere una quadra a 100khz con duty variabile impostando OCR2B.
TCCR2A = 0x23; // imposto “pin high on overflow”, e “clear on compare match with OCR2B
TCCR2B = 0x09; // seleziono come sorgente di clock I 16MHz di sistema senza prescaler
OCR2A = 159; // inizializzo il top level match a 159 ->f_PWM=100kHz
Vorrei avere la stessa cosa su un altro pin digitale, che però sia invertito rispetto a questo e che quindi segua il comportamento negato di questo.
Quali registri devo impostare?
Grazie
... prima cosa: forse a Natale qualcuno va anche a parenti o è pieno di prosecco e non risponde... non avere fretta...
... per i motivi di qui sopra Leo è sicuramente molto molto molto più ferrato di me sui pwm ed i timers...
... se ti accontenti di me fai male
... mi vengono a mente tre soluzioni: la prima, forse più scontata, è di attaccare un interrupt al timer e poi dentro all'interrupt fai quello che vuoi (circa perchè devi andare veloce...) ....
la seconda è hardware: ci pianto una porta logica in uscita al pin.
la terza è di nuovo software: bit COM1A1 e COM1A2 (per timer1... per timer 2 sarà immagino uguale solo con il due) del registro TCCR1A... guarda verso il fondo di questo documento... se metti i due bit alti hai l'uscita invertita... http://www.avrbeginners.net/architecture/timers/timers.html
...e detto così sembra fatta ma invece secondo me questa ultima soluzione non ti risulterà possibile perchè ti inverte in automatico tutti e due i canali/pin del timer (almeno credo) quindi dovresti ricorrere a 2 timer alla stessa frequenza al che dubito che la sincronia sia possibile...
Una soluzione semplicissima è quella di attivare l'interrupt al raggiungimento di OCR2B e dentro la corrispondente ISR (routine di gestione dell'interrupt) metti un piccolo codice che alterna lo stato su un pin a tua scelta, con uscita invertita (basta una semplice variabile di stato di cui alterni il valore).
Ma così ottengo un segnale sovrapposto al mio e più stretto di duty cycle....why?
Allora devi invertire il segno. Sul duty cicle è normale che sia leggermente diverso, qui stai facendo un segnale PWM con la tecnica del bit-banging quindi un minimo di differenza c'è rispetto al segnale che ottieni facendo pilotare il segnale direttamente al timer.
Ho provato ad invertire lo stato del flag ma il risultato è lo stesso.
Sullo stato alto del mio segnale (Ton) ho esattamente in mezzo al Ton il segnale generato con la isr, ed ha un Ton molto breve rispetto all'altro..
Non capisco come sia possibile dato che dovrebbe andare a 1 solo al raggiungimento del valore di compare e non prima.
Dovrebbe essere la CTC.
Questo è quello che uso, preso pari pari da internet
// Configurazione del Timer2 per funzionare in modo fast PWM su OC2B (pin 3 di Arduino)
// set pin high on overflow, clear on compare match with OCR2B
TCCR2A = 0x23; // imposto “pin high on overflow”, e “clear on compare match with OCR2B
TCCR2B = 0x09; // seleziono come sorgente di clock I 16MHz di sistema senza prescaler
OCR2A = 159; // inizializzo il top level match a 159 ->f_PWM=100kHz
Se qualcuno poi mi potesse spiegare gentilmente il significato di 0x23 e 0x09 gli sarei molto grato. Non capisco che bit si vadano a settare in questo modo
La CTC non interagisce con i pin esterni. Si sfrutta per gestire il timer come semplice contatore. Sei sicuro?
Questo è quello che uso, preso pari pari da internet
Ah.. ecco...
quindi non sai com'è stato configurato il timer? Io sinceramente non mi sono messo a recuperare la modalità partendo dai registri modificati, pensavo avessi già fatto il setup tu
// Configurazione del Timer2 per funzionare in modo fast PWM su OC2B (pin 3 di Arduino)
// set pin high on overflow, clear on compare match with OCR2B
TCCR2A = 0x23; // imposto “pin high on overflow”, e “clear on compare match with OCR2B
TCCR2B = 0x09; // seleziono come sorgente di clock I 16MHz di sistema senza prescaler
OCR2A = 159; // inizializzo il top level match a 159 ->f_PWM=100kHz
Qui c'è scritto "configurazione del Timer 2 per funzionare in modo fast PWM", quindi non è la CTC...
Se qualcuno poi mi potesse spiegare gentilmente il significato di 0x23 e 0x09 gli sarei molto grato. Non capisco che bit si vadano a settare in questo modo
Beh, devi aprire il datasheet, prendere quei valori "infilati" nei registri e recuperare i bit che modificano. Solo così sai come viene impostato il timer.
Mi sono sforzato più volte di leggere il datasheet ma faccio fatica coi timer.
Ho necessità di generare due quadre complementari tutto qua. La frequenza e il duty vorrei poterli impostare.
Ovviamente se aumenta il duty di una quello dell'altra deve diminuire.
Se hai bisogno di 2 segnali simili ma invertiti, perché non li fai entrambi con la tecnica del bit-banging?
Imposti il timer 2 in modalità contatore (la CTC, appunto) e ad ogni overflow del timer scambi i livelli dei 2 pin che ti servono.
Ho passato 3 ore su questi timer ma non mi funziona nulla.
Dovrebbe essere semplice creare due uscite invertite tra loro...non vorrei usare un componente in più per forza
ekjk:
ciao, ho guardato il link ma non ci ho capito tanto di più, nel senso che non capisco tutti quei simboli usati tipo la tilde o _BV() ecc.
~ è il simbolo di inversione, quindi ~1 equivale a 0. Per cui se io faccio ~(1<<TOIE2) significa che metto ad 1 il bit TOIE2 in un byte di registro, e poi ne inverto il valore, quindi diventa tutto ad 1 ed a 0 solo il bit TOIE2. Facendo un AND logico poi spengo quel bit.
No esiste una libreria in cui ti danno metodi per impostare il pin di uscita, freq e duty?
Io ci sto sclerando con sti timer