Ciao a tutti,
grazie in anticipo per l'aiuto, vi espongo il mio problema:
vorrei creare un pwm modificabile in frequenza e in periodo, ma andando a poter utilizzare delle frequenze diverse da quelle dei prescale, es: 2,7kHz 1,5kHz e via dicendo, al momento non sono riuscito a trovare una libreria che riesca a fare questo, non voglio usare dei delayMicroseconds() perchè mi bloccherebbe il programma.
Ciao, ti posto un codice sul fast pwm, non prenderlo come oro colato perchè l'ho trovato in giro e non mi ricordo neanche se l'ho modificato in qualche modo.
Provato al volo genera 45kHz sul pin 4 e 90kHz sul pin 3, ArduinoUNO.
Magari prendi spunto
int variabile_timer2 = 0;
int duty = 25; //duty cycle 25%
void setup() {
DDRD |= (1 << DDD3); // pin 3 come output
DDRD |= (1 << DDD4); // pin 4 come output
TCCR2A = 0x23; // 00100011
TCCR2B = 0x09; // 00001001
OCR2A = 176; // inizializzo il top level match a 176 ->f_PWM=90kHz
variabile_timer2 = (OCR2A * duty) / 100; //calcolo il duty cycle voluto in base al top level match inserito
OCR2B = variabile_timer2;
TIMSK2 = 0b00000010; // abilito tinterrupt sul compare matchA
}
void loop() {
}
ISR(TIMER2_COMPA_vect)
{
bitSet(PIND, 4); // toggla il pin
}
Posso solo consigliarti una vecchia applicazione (multipiattaforma) che scrivemmo Leo ed io parecchi anni fa, ma che, per il calcolo del PWM, è ancora valida ... se ne parlava, a suo tempo, QUI ... vedi se può esserti utile ...
Mi sono riguardato un po' il codice e l'ho sistemato , ora dovrebbe essere un po più chiaro:
ad esempio questo genera una frequenza di 10kHz, duty cycle 25% con prescaler 8
int variabile_timer2 = 0;
int duty = 25; //duty cycle 25%
void setup() {
pinMode(9,OUTPUT);
// VEDI DATASHEET PER CONFIGURAZIONE REGISTRI TIMER 2
/*
CS22 CS21 CS20 Description
0 0 0 No clock source (Timer/Counter stopped)
0 0 1 clk T2S /(No prescaling)
0 1 0 clk T2S /8 (From prescaler)
0 1 1 clk T2S /32 (From prescaler)
1 0 0 clk T2S /64 (From prescaler)
1 0 1 clk T2S /128 (From prescaler)
1 1 0 clk T 2 S /256 (From prescaler)
1 1 1 clk T 2 S /1024 (From prescaler)
OCR2A = (256/f_finale)*(f_clk/(N*510)) con N valore prescaler -- !! OCR2A max val 255 !!
*/
TCCR2A = 0b00100001; // COM2A1 COM2A0 COM2B1 COM2B0 – – WGM21 WGM20
TCCR2B = 0b00001010; // FOC2A FOC2B – – WGM22 CS22 CS21 CS20
OCR2A = 100; // inizializzo il top level match --> DETERMINO FREQUENZA
variabile_timer2 = (OCR2A * duty) / 100; //calcolo il duty cycle voluto in base al top level match inserito
OCR2B = variabile_timer2;
}
void loop() {
}
per rispondere alla domanda iniziale: dai prescaler non scappi, però modificando il valore di OCR2A puoi giocare lo stesso sulla frequenza e con OCR2B cambi il duty cycle