Hi
Using a Teensy 3.2, I need a center-alligned PWM signal @ about 100kHz.
So I am working with the FTM0 registers directly. In consulting the docs, I have managed to setup the registers to what I thought was the correct configuration.
But my speed calculations seems to be wrong. As the calculated speed is different from what appears to be the actual speed.
I measured the actual speed by polling the CNT register and counting how many times the count direction switched from counting down to up, in 100mS.
I think this is probably due to the System Clk not being the same as the CPU clk.
Why the difference between the calculated speed and the apparent speed?
Can I make the clk for FTM0 faster?
Can I run the FTM0 from the CPU clk?
Any help appreciated.
Using a Teensy 3.2, I need a center-alligned PWM signal @ about 100kHz.
So I am working with the FTM0 registers directly. In consulting the docs, I have managed to setup the registers to what I thought was the correct configuration.
But my speed calculations seems to be wrong. As the calculated speed is different from what appears to be the actual speed.
I measured the actual speed by polling the CNT register and counting how many times the count direction switched from counting down to up, in 100mS.
I think this is probably due to the System Clk not being the same as the CPU clk.
Why the difference between the calculated speed and the apparent speed?
Can I make the clk for FTM0 faster?
Can I run the FTM0 from the CPU clk?
Any help appreciated.
PHP:
#include <kinetis.h>
int led = 13;
uint32_t led_timeout;
uint32_t print_timeout;
void setup() {
pinMode(led, OUTPUT);
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial);
Serial.println("Register Tester");
print_timeout = millis() + 1000;
led_timeout = millis() + 500;
pwm_setup();
}
void pwm_setup(void)
{
/*
* The Center-Aligned mode is selected when:
* - QUADEN = 0
* - DECAPEN = 0
* - COMBINE = 0, and
* - CPWMS = 1
* The CPWM pulse width (duty cycle) is determined by 2 × (CnV − CNTIN) and the
* period is determined by 2 × (MOD − CNTIN). MOD must be kept in the range
* of 0x0001 to 0x7FFF because values outside this range can produce
* ambiguous results.
* In the CPWM mode, the FTM counter counts up until it reaches MOD and then counts
* down until it reaches CNTIN.
*/
Serial.print ("F_CPU = "); Serial.println(F_CPU);
FTM0_SC = 0;
FTM0_CNTIN = 0; // minimum count
FTM0_CNT = 0; // current count
FTM0_MOD = F_CPU / 2 / 100000; // maximum count
Serial.print ("MOD "); Serial.println(FTM0_MOD, HEX);
FTM0_SC = FTM_SC_CPWMS | FTM_SC_CLKS(1) | FTM_SC_PS(0); // set the "Center-Aligned", system clk, x1
//FTM0_SC = FTM_SC_CPWMS | FTM_SC_CLKS(1) | FTM_SC_PS(1); // set the "Center-Aligned", system clk, x2
//FTM0_SC = FTM_SC_CPWMS | FTM_SC_CLKS(1) | FTM_SC_PS(7); // set the "Center-Aligned", system clk, x64
uint32_t cycles = 2 * (FTM0_MOD - FTM0_CNTIN);
Serial.print ("Pulse width = ");
Serial.print (cycles);
Serial.print (" cycles = ");
Serial.print (F_CPU / cycles);
Serial.println (" Hz");
}
#define SAMPLE_PERIOD 100
void pwm_speed(void)
{
uint32_t start = millis();
uint32_t end = start + SAMPLE_PERIOD;
uint32_t current;
uint32_t last;
uint32_t count = 0;
uint8_t down;
last = FTM0_CNT;
down = (last > FTM0_CNT); // current count direction
while (end >= millis()) {
current = FTM0_CNT;
if ((last < current) && down) { // we are now counting up
count += 1;
}
down = (last > current);
last = current;
}
Serial.print ("count = ");
Serial.print(count);
Serial.print (" speed = ");
Serial.println(count * (1000 / SAMPLE_PERIOD));
}
void loop()
{
if (led_timeout <= millis()) {
if (digitalRead(led)) {
digitalWrite(led, LOW);
led_timeout = millis() + 900;
}
else {
digitalWrite(led, HIGH);
led_timeout = millis() + 100;
}
}
if (print_timeout <= millis()) {
print_timeout = millis() + 1000;
pwm_speed ();
}
}