Configurazione Timer PWM

Salve a tutti!

Voglio usare un arduino per pilotare a half bridge ad alta frequenza. Per questo ho bisogno di configurare due pin in modo che diano due segnali alla stessa frequenza ma in opposizione di fase con un tempo morto tra una transizione e l'altra. Impostando i registri in questo modo (Phase-Correct PWM):

void setup()
{
  pinMode(3, OUTPUT);
  pinMode(11, OUTPUT);
  TCNT2  = 60;//initialize counter value to 0
  TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);
  TCCR2B = _BV(CS22); // _BV(CS10); //_BV(CS22);
  OCR2A = 175;
  OCR2B = 80;
}

void loop()
{
  // This code will loops consecutively
  
}

riesco a farlo. Tuttavia vorrei aver modo di regolare la frequenza in modo preciso (adesso posso solo saltare in blocchi cambiando il prescaler). Qualcuno saprebbe suggerirmi come fare?

Molte grazie!

Potresti usare il timer 1 che è a 16 bit ed ha quindi una maggior risoluzione rispetto al timer 2 che è a 8 bit.
La frequenza dei 2 pin la vari agendo sul registro OCRxA e OCRxB che regolano il compare match per il timer.

Devi ricalcolare poi tutti i valori e la modalità per il timer a 16 bit, e cambiare i pin perché il timer 1 esce sui pin 9 e 10.

Ciao,
grazie del suggerimento. Solo che il mio problema è vorrei cambiare la frequenza dei due IO in un range continuo da 100 a 300Khz. Con i due registri posso solo cambiare il duty. Cambiando il prescaler posso cambiare la frequenza a multipli di due. Io vorrei poter alterare sia i duty che la frequenza in modo continuo. Mi stavo chiedendo se era possibile usare un timer per triggerare un altro in modo da poter gestire i due PWM in modo indipendente

Putroppo la cosa si fa complessa: ad ogni cambio di prescaler ti dovresti ricalcolare il valore di OCRxA/B per adeguarlo al range di frequenza che vuoi usare.
Per attivare il secondo segnale sfalsato rispetto al primo con un altro timer la risposta è sì: dovresti semplicemente, all'interno della ISR di gestione dell'interrupt del primo timer, attivare il secondo timer impostato per triggherare il pin dopo un certo periodo e poi, all'interno della ISR di questo timer, disattivare l'interrupt.

Ciao,
risolto.
Anche se l'argomento non sembra aver interessato molto, posto la soluzione (nel caso qualcun altro dovesse fare qualcosa di simile!)

void setup()
{
  // imposta gli IO come output
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  
  // Configura timer 1 PWM phase/frequency correct con top contatore ICR!
  // Pin A non invertito, pin B invertito
  TCCR1A = _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1);
  
  // no prescaling (CS10)
  TCCR1B = _BV(WGM13) | _BV(CS10);  
  
  // imposta il conteggio totale (da 0 a ICR1, da ICR1 a 0)
  ICR1 = 20;   // frequenza 400Khz (16Mhz / (ICR1x2))
    
  OCR1A = 5; // imposta il conteggio per primo PWM (durata duty 1)
  OCR1B = 15; // imposta il conteggio per secondo PWM (durata duty 2)

  
}

void loop()
{
  // This code will loops consecutively
}

Ok, ma il codice mettilo fra gli appositi tag, la prox volta :wink:

Con questo post ho scoperto un mondo nuovo sul PWM.

Sto tendando di realizzare il classico regolatore di tensione per i 220Vca a parzializzazione d'onda.

Ora chiedo, è possibile utilizzare questi timer per generare gli impulsi di accensione del triac con ritardi variabili?

Potreste darmi un aiuto o qualche link di riferimento dove poter approfondire l'argomento.

Grazie

Questo link per apprendere la tecnica è buon inizio, ma fai attenzione poiché lo schema e lo sketch sono stati progettati per il funzionamento a 125AC 60Hz:

http://playground.arduino.cc/Main/ACPhaseControl

Leggi anche:

http://playground.arduino.cc/Code/ACPWM

http://www.pamvotis.org/e-solutions/index.php/en/2013-01-05-14-08-40/arduino-acpwm-library#library

Davvero interessanti i link che mi hai indicato!

Avevo anch'io individuato l'interrupt per gestire il zero-crossing, solo non volevo inchiodare la CPU per gestire il ritardo dell'impulso di accensione.

Oltre al classico "copia/incolla" spero di capirci qualcosa con questo nuove librerie.

Grazie mille!