Pages: [1] 2   Go Down
Author Topic: PWM push pull....help! [RISOLTO]  (Read 1336 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 0
Posts: 259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
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
« Last Edit: December 29, 2012, 01:09:19 pm by ekjk » Logged

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

Non c'è nessuno che mi possa aiutare?
Logged

Offline Offline
Sr. Member
****
Karma: 7
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
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 smiley-grin
... 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...
Logged

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

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).
Logged


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

Grazie delle risposte,

Leo, potresti per favore scrivermi le due righe che servono per attivare l'interrupt su 0cr2b?
« Last Edit: December 26, 2012, 05:53:47 am by ekjk » Logged

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

Leo, potresti per favore scrivermi le due righe che servono per attivare l'interrupt su 0cr2b?
Scusa, tu usi il canale A del timer, quindi devi agganciarlo al OCR2A.

TIMSK2 |= (1<<OCIE2A);

Poi scrivi la tua ISR:
Code:
ISR(TIMER2_COMPA_vect) {
 ..
 ..
}

Prova
Logged


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

Ho provato con questo codice

Code:

ISR(TIMER2_COMPA_vect)
{
  if(flag)  {PORTD = B00100000; flag=false;}
  if(!flag) {PORTD = B00000000; flag=true;}
}

Ma così ottengo un segnale sovrapposto al mio e più stretto di duty cycle....why?
Logged

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

Ho provato con questo codice

Code:

ISR(TIMER2_COMPA_vect)
{
  if(flag)  {PORTD = B00100000; flag=false;}
  if(!flag) {PORTD = B00000000; flag=true;}
}

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.
Logged


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

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.
Logged

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

Ma che modalità usi per il timer 2? Non è che forse il contatore incrocia 2 volte OCR2A e quindi generi 2 interrupt?
Logged


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

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
Logged

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

Dovrebbe essere la CTC.
La CTC non interagisce con i pin esterni. Si sfrutta per gestire il timer come semplice contatore. Sei sicuro?

Quote
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  smiley-wink

Quote

 // 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...

Quote
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.
Logged


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

Intanto grazie per la pazienza  smiley

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.
Logged

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

Ho controllato, effettivamente il timer viene impostato in Fast PWM con OCRA come top.

Ti consiglio la lettura di questa pagina:
http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html
spiega come manipolare i timer in generale, il 2 nello specifico.
Ti sarà d'aiuto.
Logged


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

Grazie mille, ci riprovo.
Logged

Pages: [1] 2   Go Up
Jump to: