Go Down

Topic: PWM 38Khz (Read 2 times) previous topic - next topic

Etan

Code: [Select]

TCCR4A = ((1<<COM4A0) | (1<<WGM40));
TCCR4B = (1<<CS40);
OCR4A = 105;


Grazie mille!
Li proverò domattina appena rimetto le mani sul sistema.

Ti andrebbe di dettagliare meglio il codice in modo da capire i valori che metti nei registri e come hai fatto i conti?

Grazie ancora

Etan


Ma che frequenza ottieni?
Se cerchi "barriera ad infrarossi" trovi un mio Topic con il suggerimento di Astro che con tre righe mi ha fatto ottenere i 38KHz (circa... precisi non li avrai mai), però mi pare si trattasse del timer 2.


Grazie Michele per il suggerimento.
Sono a corto di pin ed il 6 era perfetto.
In ogni caso mi metto a studiarmi anche il tuo post.


Michele Menniti



Ma che frequenza ottieni?
Se cerchi "barriera ad infrarossi" trovi un mio Topic con il suggerimento di Astro che con tre righe mi ha fatto ottenere i 38KHz (circa... precisi non li avrai mai), però mi pare si trattasse del timer 2.


Grazie Michele per il suggerimento.
Sono a corto di pin ed il 6 era perfetto.
In ogni caso mi metto a studiarmi anche il tuo post.

ho trovato il mio sketch di prova: (c'è anche il metodo per il calcolo, il suggerimento è di Astrobeed, non mio :))
Quote
Quote

#define TX 11
void setup()
{                
  pinMode(TX, OUTPUT);     
    
  OCR2A = 209;
  TCCR2A = 0b01000011; 
  TCCR2B = 0b00001001;
  /*
  Ad OCR2A si deve associare il risultato di
  (clock/frequenza_da_ottenere/2)-1
  Esempio (Arduino a 16MHz)
  per 38000Hz: 16000000/38000/2=210-1=209
  per 40000Hz: 199
  */
}

void loop()
{
 } 

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

leo72


Code: [Select]

TCCR4A = ((1<<COM4A0) | (1<<WGM40));
TCCR4B = (1<<CS40);
OCR4A = 105;


Grazie mille!
Li proverò domattina appena rimetto le mani sul sistema.

Ti andrebbe di dettagliare meglio il codice in modo da capire i valori che metti nei registri e come hai fatto i conti?

Grazie ancora


La prima cosa da fare è scegliere la modalità di generazione dell'onda.
In questo caso ho scelto la Phase Correct PWM ad 8 bit del timer 4, che, ricordo, è a 16 bit ma può essere configurato appunto per lavorare anche ad 8/9/10 bit in alcune modalità. La Phase Correct PWM, rispetto alla Fast PWM che viene spesso scelta, permette di avere un segnale perfettamente quadro, con le fasi High e Low perfettamente simmetriche.
Per far ciò ho settato ad 1 il bit WGM40 nel registro TCCR4A.
Scelta la modalità, ho scelto il canale ed il comportamento. Volevi agire sul pin D6, che è il pin OC4A, per cui ho scelto di cambiare lo stato del pin (da alto a basso e viceversa) ogni volta che il valore del contatore del timer raggiungesse il valore del registro OCR4A. Per fare ciò ho settato ad 1 il bit COM4A0 sempre nel registro TCCR4A.
Adesso arriviamo al valore di OCR4A.

Per la modalità Phase Correct PWM, la formula da usare per calcolare la frequenza è
Fpwm = Fsys/(2*PRESCALER*VALORE_MAX*2)

Il PRESCALER è il fattore di divisione del clock di sistema. Ho usato un fattore /1, quindi nessuna divisione del clock. Per selezionare questa voce ho settato ad 1 il bit CS40 nel registro TCCR4B.
VALORE_MAX è il valore massimo del registro o, in alternativa, il valore di OCR4A.
Avendo messo PRESCALER ad 1, con Fsys pari a 16 MHz, la formula è
Fpwm = 16.000.000/(2*OCR4A*2)
Da cui
38000 = 16.000.000/(2*OCR4*2)
Da cui
OCR4A = 16.000.000/(38000*4)

Ed ecco OCR4A a 105.

Etan

Seguendo il tuo ragionamento con il datasheet dell'ATmega2560 sono riuscito a capire un pò meglio la sequenza di istruzioni.

Domani potrò caricare il nuovo firmware e verificare con l'oscilloscopio cosa accade.

grazie ancora.

Go Up