Variable phase shifting pwm

Status
Not open for further replies.

jpv

New member
Hi everyone,
This is my first post here. I will try to be as clear as possible.

My objective :

Generate two pwm signals, 40 khz each one, pwm duty cycle is 50%, fixed in time, with variable phase shifting. Working on T3.6

My problem :


I m looking for a solution and found some threads about generating phase shift pwm.
I first found this post : https://forum.pjrc.com/threads/42158-PWM-phase-shift-help, and adapted it to my need, by trying to update CnV values on the while.
I just tried to update the c2V and c3v on FTM3. To do that, i realised that i needed each time to halt the timer, and restart it. Here is the used code : each 100ms, the 2 + 3 ch (on pin 7) is 90° phase shift, and then in phase, and so on :
Code:
void setup()
{
  FTM3_SC = 0;    // halt timer
  FTM3_COMBINE = FTM_COMBINE_COMBINE1; // ch 2+3 = adjustable high/low points
  FTM3_C0V = 749;  // high at 50% of period
  FTM3_C2V = 375;  // high at 25% of period
  FTM3_C3V = 1125;  // low at 75% of period
  FTM3_CNT = 0;   // reset timer
  FTM3_MOD = 1499; // timer period (MOD+1 clocks of F_BUS)
  FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start timer
  // configure the pins to be controlled by FTM3 channels
  CORE_PIN2_CONFIG =  PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // ch0
  CORE_PIN7_CONFIG =  PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // ch2+3
  Serial.begin(115200);
  //analogWriteRes(12);//Résolution du pwm
  //analogWriteFrequency(pinpwm, 40000);
  //analogWrite(pinpwm, 2048);
}


void loop()
{
  
  FTM3_SC = 0;    // halt timer 
  FTM3_C2V = 375;  // high at 25% of period
  FTM3_C3V = 1125;  // low at 75% of period

  FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start timer 

  delay(100);

  FTM3_SC = 0;    // halt timer
  FTM3_C2V = 1;  // in phase
  FTM3_C3V = 750;  // in phase
  FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start timer 
  delay(100);

}
This code do phase shifting, but here is problem : Because (i think), FTM3 is halt and restart, i can see on scope, a decay in time of the fixed pwm (channel 0). For exemple, if i set a 40khz pwm on pin 6, and probe channel 0 (pin 2) and pin 6, a slow continuous phase is observed on a scope (assuming pin 6 shows no decay in time). Here is the code for the test:

Code:
const byte pinpwm = 6; //Added compared to previous code for test
void setup()
{
  FTM3_SC = 0;    // halt timer
  FTM3_COMBINE = FTM_COMBINE_COMBINE1; // ch 2+3 = adjustable high/low points
  FTM3_C0V = 749;  // high at 50% of period
  FTM3_C2V = 375;  // high at 25% of period
  FTM3_C3V = 1125;  // low at 75% of period
  FTM3_CNT = 0;   // reset timer
  FTM3_MOD = 1499; // timer period (MOD+1 clocks of F_BUS)
  FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start timer
  // configure the pins to be controlled by FTM3 channels
  CORE_PIN2_CONFIG =  PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // ch0
  CORE_PIN7_CONFIG =  PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE; // ch2+3
  Serial.begin(115200);
  analogWriteRes(12);////Added compared to previous code for test
  analogWriteFrequency(pinpwm, 40000); //Added compared to previous code for test
  analogWrite(pinpwm, 2048);////Added compared to previous code for test
}


void loop()
{
  
  FTM3_SC = 0;    // halt timer 
  FTM3_C2V = 375;  // high at 25% of period
  FTM3_C3V = 1125;  // low at 75% of period

  FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start timer 

  delay(100);

  FTM3_SC = 0;    // halt timer
  FTM3_C2V = 1;  // in phase
  FTM3_C3V = 750;  // in phase
  FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); // start timer 
  delay(100);

}

I m not really pro with low level coding (not at all to be honnest), but i tried to find a solution.
In the documentation, i found at 45.5.10Registers updated from write buffers and at 45.5.10.3CnV register update the first raw of Table 45-8. CnV register update : i thought i was in this case, that is to say : CLKS[1:0] = 0:0 then When CnV register is written, independent of FTMEN , but it does seems. I found another information:
In Input Capture, Capture Test, and Dual Edge Capture modes, any write to a CnV register is ignored.
In output modes, writing to a CnV register latches the value into a buffer.
A CnV register is updated with the value of its write buffer according to Registers updated from write buffers.
The same problem was encountered here : https://forum.pjrc.com/threads/33084-Teensy-3-1-PWM-register-update.
I tried to find a solution and i m on this problem for hours. My bad english is mainly blocking me, and be adding my noobyness in the low level programming, i must admit i'm blocked.

My question :
Is there a way, to update quickly, on the fly, the cnv values, without halting, reseting, restarting the ftm?

Sorry for the size of the message, and thank you to read until here!
Sincerly
jpv
 
Last edited:
Hi everyone,
My objective :

Generate two pwm signals, 40 khz each one, pwm duty cycle is 50%, fixed in time, with variable phase shifting. Working on T3.6
If the duty cycle is fixed at 50%, how is it PWM (Pulse Width Modulation)?
 
If the duty cycle is fixed at 50%, how is it PWM (Pulse Width Modulation)?

Maybe it's not the good term in english, square waveform must be more appropriated? Let me know if my original message is not clear.
Thank you.
 
Status
Not open for further replies.
Back
Top