come da oggetto mi servirebbe aiuto per modificare la frequenza di tutti i PWM della scheda MKR WiFi 1010. Attualmente i PWM hanno una frequenza di 732Hz, ma ho necessità di impostarli tutti a circa 400Hz.
Potreste suggerirmi le istruzioni da utilizzare o una libreria da utilizzare?
Buongiorno e benvenuto nella sezione Italiana del forum,
cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.
Grazie,
Guglielmo
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto.
Se fai una ricerca su Google per "Arduino change pwm frequency on SAM D21" trovi varie discussioni in merito ... considera che una vale l'altra, la MCU è sempre quella ...
In QUESTA, ad esempio, si fa riferimento ad Arduino Zero
Grazie Guglielmo, ...
... purtroppo se sono arrivato a scrivere in questo forum è perchè ho esaurito tutte le pagine di ricerca possibili ed immaginabili, ... e ancora non riesco a farlo funzionare.
La cosa è molto semplice: Le uscite D0, D1, D2, D3, D4, D5, D6, D7 e D8 devo settarle con una frquenza di PWM da circa 400hz (<500hz altrimenti la periferica collegata al pin non funziona).
Ho provato qualsiasi titpo di sketch da inserire nella setup, ma nulla non funziona nulla. la frequenza di PWM continua a rimanere fissa a 733hz.
L'ultimo setup per PWM che ho provato è stato questo, ... ma non sono stato in grado di modificarlo per adattarlo alle mie esigenze e per il mio hardware:
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(3) | // Divide the 48MHz clock source by divisor 3: 48MHz/3=16MHz
GCLK_GENDIV_ID(4); // Select Generic Clock (GCLK) 4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
GCLK_GENCTRL_GENEN | // Enable GCLK4
GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
GCLK_GENCTRL_ID(4); // Select GCLK4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Enable the port multiplexer for the 4 PWM channels: timer TCC0 outputs
const uint8_t CHANNELS = 8;
const uint8_t pwmPins[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
for (uint8_t i = 0; i < CHANNELS; i++)
{
PORT->Group[g_APinDescription[pwmPins[i]].ulPort].PINCFG[g_APinDescription[pwmPins[i]].ulPin].bit.PMUXEN = 1;
}
// Connect the TCC0 timer to the port outputs - port pins are paired odd PMUO and even PMUXE
// F & E specify the timers: TCC0, TCC1 and TCC2
PORT->Group[g_APinDescription[2].ulPort].PMUX[g_APinDescription[2].ulPin >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
PORT->Group[g_APinDescription[6].ulPort].PMUX[g_APinDescription[6].ulPin >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
// Feed GCLK4 to TCC0 and TCC1
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TCC0 and TCC1
GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Dual slope PWM operation: timers countinuously count up to PER register value then down 0
REG_TCC0_WAVE |= TCC_WAVE_POL(0xF) | // Reverse the output polarity on all TCC0 outputs
TCC_WAVE_WAVEGEN_DSBOTTOM; // Setup dual slope PWM on TCC0
while (TCC0->SYNCBUSY.bit.WAVE); // Wait for synchronization
// Each timer counts up to a maximum or TOP value set by the PER register,
// this determines the frequency of the PWM operation:
// 20000 = 50Hz, 10000 = 100Hz, 2500 = 400Hz
REG_TCC0_PER = 20000; // Set the frequency of the PWM on TCC0 to 50Hz
while(TCC0->SYNCBUSY.bit.PER);
// The CCBx register value corresponds to the pulsewidth in microseconds (us)
REG_TCC0_CCB0 = 1500; // TCC0 CCB0 - center the servo on D2
while(TCC0->SYNCBUSY.bit.CCB0);
REG_TCC0_CCB1 = 1500; // TCC0 CCB1 - center the servo on D5
while(TCC0->SYNCBUSY.bit.CCB1);
REG_TCC0_CCB2 = 1500; // TCC0 CCB2 - center the servo on D6
while(TCC0->SYNCBUSY.bit.CCB2);
REG_TCC0_CCB3 = 1500; // TCC0 CCB3 - center the servo on D7
while(TCC0->SYNCBUSY.bit.CCB3);
// Divide the 16MHz signal by 8 giving 2MHz (0.5us) TCC0 timer tick and enable the outputs
REG_TCC0_CTRLA |= TCC_CTRLA_PRESCALER_DIV8 | // Divide GCLK4 by 8
TCC_CTRLA_ENABLE; // Enable the TCC0 output
while (TCC0->SYNCBUSY.bit.ENABLE); // Wait for synchronization
proverò a ripartire da 0 con questo SAM D21, se e quando troverò il tempo di farlo.
Avevo dato per scontato che al massimo bisognava cambiare un registro come si faceva per le Arduino uno (TCCR0B, TCCR1B, TCCR2B) o meglio ancora utilizzare una funzione tipo setPwmFrequency(pin, divisore), ... ma purtroppo mi sono reso conto che non è più così.