I have this code that produces a pulse on the adafruit feather m4 express and i can already use the serial monitor to change the frequency. I'd like to know how to change the duty cycle.
const uint8_t outputPin = 5;
volatile bool flag = false;
float currentFreq = 50.0; // default frequency (Hz)
void TC3_Handler(void) {
if (TC3->COUNT16.INTFLAG.bit.MC0) {
TC3->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0;
flag = true;
}
}
void setTimerFrequency(float freq) {
if (freq < 0.1 || freq > 200000) return;
currentFreq = freq;
uint32_t compareValue = (120000000.0 / 1024.0) / freq;
TC3->COUNT16.CC[0].reg = compareValue;
while (TC3->COUNT16.SYNCBUSY.bit.CC0)
;
Serial.print("Frequency updated to: ");
Serial.print(freq);
Serial.println(" Hz");
Serial.print("CC0 = ");
Serial.println(compareValue);
}
void setup() {
Serial.begin(115200);
delay(1500);
Serial.println("Booted");
Serial.println("Enter frequency in Hz:");
pinMode(outputPin, OUTPUT);
// ---- Enable clock for TC3 ----
MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC3;
GCLK->PCHCTRL[TC3_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0;
TC3->COUNT16.CTRLA.bit.SWRST = 1;
while (TC3->COUNT16.SYNCBUSY.bit.SWRST)
;
TC3->COUNT16.CTRLA.reg =
TC_CTRLA_MODE_COUNT16 | TC_CTRLA_PRESCALER_DIV1024;
TC3->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ;
setTimerFrequency(currentFreq);
TC3->COUNT16.INTENSET.reg = TC_INTENSET_MC0;
NVIC_EnableIRQ(TC3_IRQn);
TC3->COUNT16.CTRLA.bit.ENABLE = 1;
while (TC3->COUNT16.SYNCBUSY.bit.ENABLE)
;
Serial.println("Timer enabled");
}
void loop() {
// Toggle pin from ISR flag
if (flag) {
flag = false;
digitalWrite(outputPin, !digitalRead(outputPin));
}
// Serial frequency update
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
float newFreq = input.toFloat();
if (newFreq > 0) {
setTimerFrequency(newFreq);
}
}
}