For a project which requires precise timings, I'm trying to align three PWM signals from three different timers; one 12 MHz, one 1.5 MHz and one 0.75 MHz signal.
As far as I understand this would require all three timers to start counting at the same time from 0.
The only problem is that I can't seem to find a way to start the timers simultaneously; when I run FTM2_SC = FTM1_SC = FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); every register is set after each other, which already creates a time offset between the timers.
What I tried in the code below is to give the timers an specific offset before they start, which would make them align when they get started sequentially.
For Teensy 3.6:
This seems to work ok, but it produces a small error at the beginning; when starting the timers the output of the channel will always go to HIGH; the following two screenshots explain more than a thousand words:
0.75 MHz & 12 MHz: View attachment SDS00002.BMP
0.75 MHz & 1.5 MHz: View attachment SDS00003.BMP
I assume there is a better way of doing this, one that also doesn't depend on the delay between the execution of timer start commands.
I would love to hear any suggestions!
Thanks!
As far as I understand this would require all three timers to start counting at the same time from 0.
The only problem is that I can't seem to find a way to start the timers simultaneously; when I run FTM2_SC = FTM1_SC = FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); every register is set after each other, which already creates a time offset between the timers.
What I tried in the code below is to give the timers an specific offset before they start, which would make them align when they get started sequentially.
For Teensy 3.6:
Code:
// For Teensy 3.6
// 12 MHz on pin 3
// 0.75 MHz on pin 29
// 1.5 MHz on pin 35
void setup() {
FTM1_SC = 0;
FTM1_CNT = 0;
FTM1_MOD = 4;
FTM1_C0SC = 0x28;
FTM1_C0V = 2;
CORE_PIN3_CONFIG = PORT_PCR_IRQC(1) | PORT_PCR_MUX(3);
FTM2_SC = 0;
FTM2_CNT = 0;
FTM2_MOD = 79;
FTM2_C0SC = 0x28;
FTM2_C0V = 40;
CORE_PIN29_CONFIG = PORT_PCR_IRQC(1) | PORT_PCR_MUX(3);
FTM3_SC = 0;
FTM3_CNT = 0;
FTM3_MOD = 39;
FTM3_C4SC = 0x28;
FTM3_C4V = 5;
CORE_PIN35_CONFIG = PORT_PCR_IRQC(1) | PORT_PCR_MUX(3);
}
void loop() {
syncStart();
delayMicroseconds(100);
stop();
delay(10);
}
void stop() {
FTM1_SC = 0;
FTM2_SC = 0;
FTM3_SC = 0;
}
void syncStart() {
noInterrupts();
FTM2_SC = 0;
FTM2_CNT = 0;
FTM1_SC = 0;
FTM3_SC = 0;
FTM1_CNTIN = 3;
FTM1_CNT = 0;
FTM1_CNTIN = 0;
FTM3_CNTIN = 36;
FTM3_CNT = 0;
FTM3_CNTIN = 0;
FTM2_SC = FTM1_SC = FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start the timers
interrupts();
}
This seems to work ok, but it produces a small error at the beginning; when starting the timers the output of the channel will always go to HIGH; the following two screenshots explain more than a thousand words:
0.75 MHz & 12 MHz: View attachment SDS00002.BMP
0.75 MHz & 1.5 MHz: View attachment SDS00003.BMP
I assume there is a better way of doing this, one that also doesn't depend on the delay between the execution of timer start commands.
I would love to hear any suggestions!
Thanks!
Last edited: