6 years, 11 months ago.

controling the duty cylce using timer

Hi,

I am using the MBED to switch two MOSFETs for my final year project. The MOSFETs are connected in push pull configurations and used to convert DC to AC to be supplied to the input of the primary of the transformer. I am using the timer function of the Mbed to control the switching frequency (25 KHz)... the problem am having is that I cannot get the duty cycle to be 50% for both signals and one of my MOSFETS gest really hot due to the on and off timing not being equal.

I have posted my code below and would really appreciate if you could help me

  1. include "mbed.h" DigitalOut MOSFET1(p5); Gate of MOSFET_1 DigitalOut MOSFET2(p7); Gate of MOSFET_2 DigitalOut MOSFET3(p8); DigitalOut MOSFET4(p9); Timer t;

int main() { t.start(); while(1) {

if (t.read() >=0.0000000000 && t.read() <= 0.00001666667) { MOSFET1 = 1; MOSFET_1 ON MOSFET2 = 0; MOSFET_2 OFF MOSFET3 = 0; MOSFET4 = 0; }

if (t.read() > 0.00001666667 && t.read() <= 0.00003333334) { MOSFET1 = 0; MOSFET_1 ON MOSFET2 = 1; MOSFET_2 OFF MOSFET3 = 0; MOSFET4 = 0; }

if (t.read()> 0.00003333334) { t.reset(); }

} }

Question relating to:

-

posted by Wim Huiskamp 19 Dec 2012
Comment on this question

3 Answers

6 years, 11 months ago.

Thanks Wim,

" I recommend that you use a gap between the two phases during which you make sure that all FETs are off first before you switch one of them on again."

can I use 'wait' and if statement to check that all are off before i switch the other one on.

I tried PWM outputs but i could not get two inverted square waves :(

The regular mbed pwm lib wont help for this problem. Check the usermanual for the lpc1768 and look into the timer compare registers: use 2 different compare values to start and stop each mosfet driver outputpin.

Easiest solution in your case would be to insert a new 'if test' for the deadzone intervals:

deadzone (t>0)-(t<1): both fets off

phase1 (t>1)-(t<2): fet1 on, fet2 off

deadzone (t>2)-(t<3): both fets off

phase2 (t>3)-(t<4): fet1 off, fet2 on

reset

You could also use a ticker that triggers a statemachine.

posted by Wim Huiskamp 19 Dec 2012

I tried that, the MOSFETs now do not get heated up as before but still I cannot get 50% duty cycle :(

#include "mbed.h"
DigitalOut MOSFET1(p5);
DigitalOut MOSFET2(p7);
DigitalOut MOSFET3(p8);
DigitalOut MOSFET4(p9);
Timer t;


int main()
{
    t.start();
    while(1) {

        if (t.read() >=0.00 && t.read() <= 0.00001) {
            MOSFET1 = 0; // MOSFET_1 OFF
            MOSFET2 = 0; // MOSFET_2 OFF
            MOSFET3 = 0;
            MOSFET4 = 0;
        }
         if (t.read() >=0.00001 && t.read() <= 0.00002) {
            MOSFET1 = 1; // MOSFET_1 ON
            MOSFET2 = 0; // MOSFET_2 OFF
            MOSFET3 = 0;
            MOSFET4 = 0;
        }
         if (t.read() >=0.00002 && t.read() <= 0.00003) {
            MOSFET1 = 0; // MOSFET_1 OFF
            MOSFET2 = 1; // MOSFET_2 ON
            MOSFET3 = 0;
            MOSFET4 = 0;
        }

        if (t.read() > 0.00003 && t.read() <= 0.00004) {
            MOSFET1 = 0; // MOSFET_1 OFF
            MOSFET2 = 0; // MOSFET_2 OFF
            MOSFET3 = 0;
            MOSFET4 = 0;
        }

        
        
        if (t.read()> 0.00004) {
            t.reset();
        }
       
    }
}

posted by Salma Alarefi 21 Dec 2012

hey,

I have used ‘ticker’ instead of ‘timer’ I think there is a problem with the code… am not sure if I should set all MOSFET s to low for the whole time of the program

#include "mbed.h"
DigitalOut MOSFET1(p5); // Gate of MOSFET_1
DigitalOut MOSFET2(p7); // Gate of MOSFET_2
DigitalOut MOSFET3(p8);
DigitalOut MOSFET4(p9);
Ticker ticker;

void MOSFETS(int lednr) {
    switch(lednr) 
    {
    
        case 1: MOSFET1 = 1; // MOSFET_1 ON
                MOSFET2 = 0; // MOSFET_2 OFF
                MOSFET3 = 0;
                MOSFET4 = 0;
                
        case 2: MOSFET1 = 0; // MOSFET_1 OFF
                MOSFET2 = 1; // MOSFET_2 ON
                MOSFET3 = 0;
                MOSFET4 = 0;       
    }
}

template<void (*fptr)(int), int value>
void caller() { 
    fptr(value);
}

  
int main()
{
    ticker.attach(caller<&MOSFETS,1>, 0.00004);
    wait(0.005);
    ticker.attach(caller<&MOSFETS,2>, 0.00004);
    wait(0.005);

    while(1) 
    {
            MOSFET1 = 0; // MOSFET_1 OFF
            MOSFET2 = 0; // MOSFET_2 OFF
            MOSFET3 = 0;
            MOSFET4 = 0;
       
    }
}
posted by Salma Alarefi 21 Dec 2012

In your Timer example the order of the two active phases and the two deadzones is still not as it should be: both off, one on, both off, other on. You also have deadzones that are the same length as the active zones. This means that duty cycle is 25% for each FET. Use short deadzones (eg 2 us) and longer active phases (eg 18 us).

#include "mbed.h"
DigitalOut MOSFET1(p5);
DigitalOut MOSFET2(p7);
DigitalOut MOSFET3(p8);
DigitalOut MOSFET4(p9);
Timer t;
 
 
int main()
{
    t.start();
    while(1) {
 
        if (t.read_us() >=0 && t.read_us() <= 2) {
            MOSFET1 = 0; // MOSFET_1 OFF
            MOSFET2 = 0; // MOSFET_2 OFF
            MOSFET3 = 0;
            MOSFET4 = 0;
        }
         if (t.read_us() > 2 && t.read_us() <= 20) {
            MOSFET1 = 1; // MOSFET_1 ON
            MOSFET2 = 0; // MOSFET_2 OFF
            MOSFET3 = 0;
            MOSFET4 = 0;
        }

        if (t.read_us() > 20 && t.read_us() <= 22) {
            MOSFET1 = 0; // MOSFET_1 OFF
            MOSFET2 = 0; // MOSFET_2 OFF
            MOSFET3 = 0;
            MOSFET4 = 0;
        }
         if (t.read_us() > 22 && t.read() <= 40) {
            MOSFET1 = 0; // MOSFET_1 OFF
            MOSFET2 = 1; // MOSFET_2 ON
            MOSFET3 = 0;
            MOSFET4 = 0;
        }
             
        if (t.read_us() > 40) {
            t.reset();
        }
       
    }
}

posted by Wim Huiskamp 22 Dec 2012

I have tried that but it seems like something is being short circuited.. However, I have now managed to get the 50% duty cycle using 'ticker'. It is more exact and the code is much simpler. your help is very much appreciated :)

posted by Salma Alarefi 02 Jan 2013
6 years, 10 months ago.

You could also use the hardware timers. In this example works, and you can confirm using oscope or
set to a lower frequency to confirm via LEDs. This code only works with LPC1768:

#include "mbed.h"

PwmOut MOSFET1(p23);
PwmOut MOSFET2(p25);

int main() {
myled.period(1);           // This tells the processor to do it's thing, next we program it with correct output variables.

// 24 pr. uS in MR0
LPC_PWM1->MR0 = 24*40;     // 40 usek routine
LPC_PWM1->MR1 = 1;         // Set the PWM2 output HIGH at this count
LPC_PWM1->MR2 = 24*19;     // Set the PWM2 output LOW at this count
LPC_PWM1->MR3 = 24*21;     // Set the PWM4 output HIGH at this count
LPC_PWM1->MR4 = 24*39;     // Set the PWM4 output LOW at this count
LPC_PWM1->PCR |= 0x14;
LPC_PWM1->LER |= 0x1E;

    while(1) {
        wait_ms(20);
    }
}

6 years, 11 months ago.

Please use <<code>>....<</code>> around your code to make it more readable

include "mbed.h"
DigitalOut MOSFET1(p5); //Gate of MOSFET_1
DigitalOut MOSFET2(p7); //Gate of MOSFET_2
DigitalOut MOSFET3(p8); 
DigitalOut MOSFET4(p9);

Timer t;

int main() {
 t.start();
 while(1) {
  if (t.read() >=0.0000000000 && t.read() <= 0.00001666667) {
    MOSFET1 = 1; // MOSFET_1 ON 
    MOSFET2 = 0; // MOSFET_2 OFF
    MOSFET3 = 0;
    MOSFET4 = 0;
  }

  if (t.read() > 0.00001666667 && t.read() <= 0.00003333334) {
    MOSFET1 = 0; // MOSFET_1 OFF
    MOSFET2 = 1; // MOSFET_2 ON
    MOSFET3 = 0;
    MOSFET4 = 0;
  }

  if (t.read()> 0.00003333334) {
    t.reset();
  }
 } //while

}

There may be a short period when both mosfets are on at same time. Note that MOSTFET2 is still on when (t.read() > 0.00003333334) and you reset the timer. The next time around the while loop you switch on MOSFET1 BEFORE you switch off MOSFET2. This could cause a short. It depends on the switch characteristic how long it takes for the FET to switch off completely. I recommend that you use a gap between the two phases during which you make sure that all FETs are off first before you switch one of them on again.

Note that the PWM hardware may do just that for you: use two pwm outputs and select different on/off compare values. This has the added advantage that your mbed can do some usefull things rather than just wait for its timer :).

Hello, I am now using the ticker function to control the MOSFETs and am now getting square-wave with 50 KHz. However, am also using another two MOSFTEs as synchronous rectifiers. Each of these two has to be switched ON with the corresponding MOSFET that I have already switched using the ticker… I have tried the code below but the four MOSFETs got heated up very quickly and am not quite sure how should I control the rectifiers without affecting the other MOSFTES….. BTW even my MBED is heated up very badly

#include "mbed.h"
DigitalOut MOSFET1(p5); // Gate of MOSFET_1
DigitalOut MOSFET2(p7); // Gate of MOSFET_2
DigitalOut MOSFET3(p8);
DigitalOut MOSFET4(p9);

Ticker flipper;

 
void flip() {
    MOSFET1 = MOSFET3= !MOSFET1;
    MOSFET2 = MOSFET4= !MOSFET2;
   
}
 
int main() {
    MOSFET1 = 1; 
    MOSFET2 = 0;
   
    flipper.attach(&flip, 0.00001); //
 
        while(1) {
        
    }
} 

posted by Salma Alarefi 22 Jan 2013

There are still no precautions in your code to make sure that MOSFET1 and MOSFET2 are not both conducting at the same time. You can not get 50% dutycycle without a brief moment where both FETs conduct. The mbed simply needs some time between

   MOSFET1 = MOSFET3= !MOSFET1;

and

   MOSFET2 = MOSFET4= !MOSFET2;

So FET1 and FET2 are on for a brief moment until you switch off FET2

Even when mbed were infinitely fast then the FETs will not switch off immediately. Depending on FET type and driver circuit there will be a short delay that may cause both FETs to conduct. There needs to be a safe deadzone to make sure both are fully off before you switch one of them on again.

The mbed may heat up because the outputs are overloaded or because your supply voltage is too high. Are you using external supply on Vin?

posted by Wim Huiskamp 22 Jan 2013