Hi..I am new to this and I wanted a little guidance for arduino zero programming
. I am trying to write a program wherein I need a fixed frequency PWM of 20KHz and I can vary its duty cycle between 0-50% ( I am able to do that) but I am not able to achieve a PWM frequency of 20 KHz and I am still getting it to be 700 Hz. Please help. Here is my code below.
int led = 9;
int button = 8;
int buttonState =0;
int brightness = 0;
int brightup = 2;
void setup()
{
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide the 48MHz clock source by divisor 1: 48MHz
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
pinMode(led, OUTPUT);
pinMode(button, INPUT);
//Enable port multiplexer
PORT->Group[g_APinDescription[9].ulPort].PINCFG[g_APinDescription[9].ulPin].bit.PMUXEN = 1; // D9(PA07)
// Connect the TCC1 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[8].ulPort].PMUX[g_APinDescription[8].ulPin>>1].reg = PORT_PMUX_PMUXO_E | PORT_PMUX_PMUXE_E; // D8
// Feed GCLK4 to TCC0 and TCC1 ??? Is there any way to feed GCLK4? only to 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
// Single slope PWM operation
REG_TCC1_WAVE |= TCC_WAVE_WAVEGEN_NPWM;
while (TCC1->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:
//
REG_TCC1_PER = 2400; // Set the frequency of the PWM on TCC1 to
while(TCC1->SYNCBUSY.bit.PER);
// The CCBx register value corresponds to the pulsewidth in microseconds (us)
REG_TCC1_CCB1 = 1200; // TCC0 CCB0 - 50% duty cycle on D2
while(TCC1->SYNCBUSY.bit.CCB1);
// Divide the 48MHz signal by 1 giving 48MHz
REG_TCC1_CTRLA |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
TCC_CTRLA_ENABLE; // Enable the TCC1 output
while(TCC1->SYNCBUSY.bit.ENABLE); // Wait for synchronization
}
void loop() {
analogWrite(led, brightness);
buttonState = digitalRead(button);
if ( buttonState == HIGH ) {
brightness = brightness + brightup;
}
if ( brightness == 128 ) {
brightness = 0;
}
delay(30);
}
void set_pwm(int i){
int y = map(i, 0, 100, 0, 2400);
REG_TCC1_CCB1 = y; // TCC0 CCB0 - 50% duty cycle on D2
while(TCC1->SYNCBUSY.bit.CCB1);
}