Embedded Systems and Power Electronics

Total Pageviews

About Me

My photo
I am currently a PhD student at UC Berkeley, following a 6-year journey working at Apple after my undergrad years at Cornell University. I grew up in Dhaka, Bangladesh where my interest in electronics was cultivated, resulting in the creation of this blog.

BTemplates.com

Powered by Blogger.

Feb 16, 2013

Sine Wave Generation without ECCP - Using single CCP Module of PIC16F877A




I had previously shown how to generate sinusoidal pulse width modulation (SPWM) signals using the ECCP module in a PIC for generating a sine wave output for use in DC-AC inverter. I have had requests from people asking how to generate the same SPWM signals with other microcontrollers that don't have the ECCP module, such as the super popular PIC16F877A.

So, here I talk about how to generate the same SPWM signals using just one CCP module as can be commonly found on so many microcontrollers. This allows much greater flexibility in microcontroller selection.

You should go through the other articles related to generating SPWM with the ECCP module (if you haven't already gone through them, that is) to get an idea of what I'm talking about regarding sine wave generation with the ECCP module and about sine wave generation in general, really:


The code I had previously used (utilizing the ECCP module) is:


//----------------------------------------------------------------------------------------
//Programmer: Syed Tahmid Mahbub
//Target Microcontroller: PIC16F684
//Compiler: mikroC PRO for PIC (Can easily port to any other compiler)
//-----------------------------------------------------------------------------------------


unsigned char sin_table[32]={0,25,49,73,96,118,137,
159,177,193,208,220,231,239,245,249,250,249,245,
239,231,220,208,193,177,159,137,118,96,73,49,25};


unsigned int TBL_POINTER_NEW, TBL_POINTER_OLD, TBL_POINTER_SHIFT, SET_FREQ;
unsigned int TBL_temp;
unsigned char DUTY_CYCLE;

void interrupt(){
     if (TMR2IF_bit == 1){
        TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
        if (TBL_POINTER_NEW < TBL_POINTER_OLD){
           CCP1CON.P1M1 = ~CCP1CON.P1M1; //Reverse direction of full-bridge
        }
        TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 11;
        DUTY_CYCLE = TBL_POINTER_SHIFT;
        CCPR1L = sin_table[DUTY_CYCLE];
        TBL_POINTER_OLD = TBL_POINTER_NEW;
        TMR2IF_bit = 0;
     }
}

void main() {
     SET_FREQ = 410;
     TBL_POINTER_SHIFT = 0;
     TBL_POINTER_NEW = 0;
     TBL_POINTER_OLD = 0;
     DUTY_CYCLE = 0;
     ANSEL = 0; //Disable ADC
     CMCON0 = 7; //Disable Comparator
     PR2 = 249;
     TRISC = 0x3F;
     CCP1CON = 0x4C;
     TMR2IF_bit = 0;
     T2CON = 4; //TMR2 on, prescaler and postscaler 1:1
     while (TMR2IF_bit == 0);
     TMR2IF_bit = 0;
     TRISC = 0;
     TMR2IE_bit = 1;
     GIE_bit = 1;
     PEIE_bit = 1;
    
     while(1);
}
//-------------------------------------------------------------------------------------




That's the previous code. Now let's look at the code based on a single CCP module and not the ECCP module. For this, I chose the super popular PIC16F877A microcontroller. The chosen frequency, like before, is 16kHz. The code is:
 

//----------------------------------------------------------------------------------------
//Programmer: Syed Tahmid Mahbub
//Target Microcontroller: PIC16F877A
//Compiler: mikroC PRO for PIC (Can easily port to any other compiler)
//-----------------------------------------------------------------------------------------



unsigned char sin_table[32]={0, 25, 50, 75, 99, 121, 143, 163, 181,
198, 212, 224, 234, 242, 247, 250, 250, 247, 242, 234, 224, 212, 198,
181, 163, 143, 121, 99, 75, 50, 25,0};


unsigned int TBL_POINTER_NEW, TBL_POINTER_OLD, TBL_POINTER_SHIFT, SET_FREQ;
unsigned int TBL_temp;
unsigned char DUTY_CYCLE;

sbit MOSA at RD0_bit;
sbit MOSB at RD1_bit;
sbit MOSC at RD2_bit;
sbit MOSD at RD3_bit;

unsigned char FlagReg;
sbit Direction at FlagReg.B0;
//0 -> MOS A + D
//1 -> MOS B + C

void interrupt(){
     if (TMR2IF_bit == 1){
        TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
        if (TBL_POINTER_NEW < TBL_POINTER_OLD){
           //CCP1CON.P1M1 = ~CCP1CON.P1M1; //Reverse direction of full-bridge
           if (Direction == 0){
              MOSA = 0;
              MOSD = 0;
              MOSB = 1;
              MOSC = 1;
              Direction = 1;
           }
           else{
                MOSB = 0;
                MOSC = 0;
                MOSA = 1;
                MOSD = 1;
                Direction = 0;
           }
        }
        TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 11;
        DUTY_CYCLE = TBL_POINTER_SHIFT;
        CCPR1L = sin_table[DUTY_CYCLE];
        TBL_POINTER_OLD = TBL_POINTER_NEW;
        TMR2IF_bit = 0;
     }
}

void main() {
     SET_FREQ = 410;
     PORTD = 0;
     TRISD = 0;
     PR2 = 249; // 16kHz
     CCPR1L = 0;
     CCP1CON = 12; //PWM mode
     TRISC = 0xFF;
     TMR2IF_bit = 0;
     T2CON = 0x04; //TMR2 on
     while (TMR2IF_bit == 0);
     TMR2IF_bit = 0; //Clear TMR2IF
     PORTC = 0;
     TRISC = 0;
     TMR2IE_bit = 1;
     GIE_bit = 1;
     PEIE_bit = 1;
    
     while (1);
    
}


Now let's talk about the changes I've made in order to be able to use a single CCP module instead of the ECCP module.

When the ECCP module is used, it generates the SPWM signals and sends the modulation signals to the required "MOSFETs" (of course there's a drive circuit in between) depending on the "direction" as dictated by CCP1CON.P1M1 (bit 7 of CCP1CON register). Since this bit does not exist in the CCP module (obviously, since it's "uni-directional"), this functionality must be achieved in software. Since we don't have the ECCP module and have chosen to use a single CCP module only, the 4 drive signals come from other pins not associated to the PWM module. I've chosen PORTD bits 0 to 3. Of course, you can select any other 4 pins.

This is the circuit diagram of the SPWM signal generation portion:


Fig. 1 - Circuit diagram of SPWM generation section - microcontroller + AND gates (Click image to enlarge)

Below (Fig. 2) is the circuit diagram for the configuration of the MOSFETs and the drivers - and the synchronization with the signals generated from Fig. 1 above.


Fig. 2 - MOSFET Configuration Section (Click image to enlarge)

The SPWM generation is done by the single CCP module and which MOSFETs to send the signals to is set by the "Direction" bit and the hardware trick employing the AND gate. When "Direction" is equal to 0, the high side MOSFET A is kept on for 10ms during which time the SPWM signals on CCP1 output (RC2) are sent to low side MOSFET D by sending a "1" to RD3, which, with the help of the AND gate "diverts" the CCP1 signal to the low side MOSFET D (see Fig. 1 above). The same thing is achieved when "Direction" is equal to 1, just with high side MOSFET C and low side MOSFET B. When MOSFETs A and D are operated, MOSFETs B and C are kept off and vice versa. The MOSFETs are first turned off before the other two are turned on, as can be seen in the code block:

           if (Direction == 0){
              MOSA = 0;
              MOSD = 0;
              MOSB = 1;
              MOSC = 1;
              Direction = 1;
           }
           else{
                MOSB = 0;
                MOSC = 0;
                MOSA = 1;
                MOSD = 1;
                Direction = 0;
           }


To understand how the timing and the table pointer operation work, go through this:

Demystifying The Use of Table Pointer in SPWM - Application in Sine Wave Inverter

I've modified the sine table to increase the deadtime. Notice how there's a 0 at both the start and the end. This achieves the additional deadtime. See Fig. 4 below. I did this by using my software "Smart Sine" to generate a sine table with 31 values and then adding a 0 at the end.
 
Besides that, the other functionality are the same - the PWM initialization and setting, the table and table pointer are used the same way as before. So make sure you go through this tutorial if you aren't completely clear regarding it:

Demystifying The Use of Table Pointer in SPWM - Application in Sine Wave Inverter

For the MOSFET drivers, you require high/low side MOSFET drivers. One of the most popular such driver is the IR2110. For a thorough tutorial on using the IR2110, go through this tutorial:
http://tahmidmc.blogspot.com/2013/01/using-high-low-side-driver-ir2110-with.html

Here are the simulation results:


 Fig. 3 - Generated SPWM  Drive Signals (Click image to enlarge)



Fig. 4 - Clear demonstration of the "deadtime" (Click image to enlarge)


Fig. 5 - Simulation results showing signal frequencies (Click image to enlarge)


Fig. 6 - Generated Sine Wave Signal (Click image to enlarge)


The operation is quite simple to understand. The trick lies in a simple software modification and the use of the external AND gates. It's quite simple really! All we've needed are 5 IO pins from the PIC16F877A leaving all the other IO pins unused - for use for so many other tasks you can carry out. Observe how the main function in the code is not doing anything and all is done in the interrupt. Notice the empty endless while(1) loop where you can carry out any other required task.

I hope you've understood how to generate SPWM signals using just the single CCP module of a microcontroller and can now use it for all your applications! Keep in mind that this isn't restricted to only PICs but can be used for any microcontroller containing one PWM module. Let me know your feedback and comments.

181 comments:

  1. can you share a hex file because when i compile this code on mikroC
    appear many errors

    ReplyDelete
    Replies
    1. Sharing the hex file will defeat the purpose of this tutorial as many people will choose to just download and use the hex file.

      If you are facing problems, elaborate on the problems you are facing and then, I can help you solve those problems. However, there is no error in the code posted since I have successfully compiled and simulated it. So, elaborate on the issues you are facing and I can try and help fix them.

      Regards,
      Tahmid.

      Delete
    2. Hello Tahmid,
      may i know how to change this program to 3 phase.. what i need to do..

      Delete
    3. Nice job Tahmid, but I saw some errors here, if you turn on the high side MOSFET A for 10 ms and at the same time turn on the low side MOSFET D with SPWM signal, you will get a shoot through-condition.

      Shoot-through is defined as the condition when both MOSFETs are either fully or partially turned on, providing a path for current to “shoot through” from +V to GND. this condition will destroy the MOSFETs.

      So I think, this circuit maybe works on PROTEUS simulation, but not on real work.

      To correct the error, when "direction" bit is equal "0", the high side MOSFET A is kept on for 10ms during which time the SPWM signals on CCP1 output (RC2) are sent to low side MOSFET B (not D) by sending a "1" to RD1 (not RD3), both MOSFETs D and C are kept on inactive state (OFF) and when "direction" bit is equal "1", the high side MOSFET C is kept on for 10ms during which time the SPWM signals on CCP1 output (RC2) are sent to low side MOSFET D (not B) by sending a "1" to RD3 (not RD1), both MOSFETs A and B are kept on inactive state (OFF)

      Juan Miguel Perez
      Microtronic Technology

      Delete
    4. Good catch! There was a typing mistake in Fig. 2. Thanks for pointing it out! I'll make the correction. It should be ABCD instead of how it's shown now.

      Delete
    5. hello tahmid in your code never you use sbit Direction at FlagReg.B0; Nowhere do I see that this is being used Then the change of direction appears by magic

      Delete
  2. it is ok , the code run Successfully
    thank you

    ReplyDelete
    Replies
    1. That's great! I wish you success on your project!

      Regards,
      Tahmid.

      Delete
  3. i want to use IGBT , can you help me to find the driver Circuit? ?

    ReplyDelete
    Replies
    1. You can use IR2110. The drive circuit for IGBT is similar to that for a MOSFET.

      Go through this for a tutorial on IR2110:

      http://tahmidmc.blogspot.com/2013/01/using-high-low-side-driver-ir2110-with.html

      Regards,
      Tahmid.

      Delete
  4. hi tahmid, thanks for the info, been great understanding the concept of making the pure sine wave. I've simulated this over proteus, pin RD0-RD3 would show the clock showing signal frequency at '50'. But when I place the counter terminal tool on the CCP1 it does not show '16000', it shows '0'. can you share if you have come across this problem before? thanks!

    ReplyDelete
    Replies
    1. As you can see in Fig. 5, the frequency counter clearly shows a frequency approximately 16kHz. If it shows zero, you're doing something wrong. Ensure that the program compiled properly and you set up the simulation "hardware" properly.

      One thing to remember: the frequency counter in Proteus works by checking the clock over one second intervals. So, until one second (in Proteus simulation, shown at the bottom of the screen) occurs, the frequency counter will show zero. So, after simulation starts, wait for at least a minute, perhaps more than that and then check to see if it still shows zero or not.

      Delete
    2. i have the same problem ccp1/RC2 pin shows nothing it stops :( it doesn't have 16khz freq.

      Delete
    3. its still zero...i have comiled the code successfully but freq counter shows 3 on 50Hz..and 0 on 16kHz..i have waited for atleast 6 min but shows nothing..the ccp1/RC2 pin not running...plz help

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Yeah! i got the code working?

    here it is

    '****************************************************************
    '* Name : UNTITLED.BAS *
    '* Author : *
    '* Notice : Copyright (c) 2013 *
    '* : All Rights Reserved *
    '* Date : 2/22/2013 *
    '* Version : 1.0 *
    '* Notes : *
    '* : *
    '****************************************************************
    DEVICE 16F877A

    XTAL 16

    ON_HARDWARE_INTERRUPT GOTO isr

    DIM tblpointernew AS WORD
    DIM tblpointerold AS WORD
    DIM tblpointershift AS WORD
    DIM setfreq AS WORD
    DIM tbltemp AS WORD
    DIM dutycycle AS BYTE
    DIM flag AS WORD
    DIM SINVAL AS BYTE
    DIM direction AS BIT

    SYMBOL mosa = PORTD.0
    SYMBOL mosb = PORTD.1
    SYMBOL mosc = PORTD.2
    SYMBOL mosd = PORTD.3
    'SYMBOL direction = flag.0 '0 = mosa + mosd and 1 = mosb+mosc

    SYMBOL PEIE = INTCON.6 ' Peripheral Interrupt Enable
    SYMBOL GIE = INTCON.7 ' Global Interrupt Enable

    'SYMBOL TMR1IF = PIR1.0 ' TMR1 Overflow Interrupt Flag
    SYMBOL TMR2IF = PIR1.1 ' TMR2 to PR2 Match Interrupt Flag
    SYMBOL TMR2IE = PIE1.1 ' TMR2 to PR2 Match Interrupt Enable

    GOTO main

    DISABLE
    isr:

    CONTEXT SAVE

    IF TMR2IF == 1 THEN

    update:
    tblpointernew = tblpointerold + setfreq
    IF tblpointernew < tblpointerold THEN
    IF direction == 0 THEN
    mosa = 0
    mosd = 0
    mosb = 1
    mosc = 1
    direction = 1

    ELSE
    mosb = 0
    mosc = 0
    mosa = 1
    mosd = 1
    direction = 0
    ENDIF
    ENDIF

    tblpointershift = tblpointernew >> 11
    dutycycle = tblpointershift
    SINVAL = LOOKUPL dutycycle, [0, 25, 50, 75, 99, 121, 143, 163, 181,198, 212, 224, 234, 242, 247, 250, 250, 247, 242, 234, 224, 212, 198,181, 163, 143, 121, 99, 75, 50, 25, 0]
    CCPR1L = SINVAL
    tblpointerold = tblpointernew

    TMR2IF = 0
    ENDIF

    CONTEXT RESTORE

    main:
    setfreq = 410
    tblpointernew = 0
    tblpointerold = 0
    tblpointershift = 0
    dutycycle = 0
    TRISD = 0
    PORTD = 0
    TRISC = 0
    PORTC = 0
    PR2 = 249
    CCPR1L = 0
    CCP1CON = 12

    TMR2IF = 0
    T2CON = $04

    TMR2IF = 0
    TMR2IE = 1
    GIE = 1
    PEIE = 1
    direction = 0

    WHILE 1 = 1

    WEND

    ReplyDelete
    Replies
    1. Plz add Feedback code on this code......

      Delete
  7. hi tahmd,,,

    i was simulated your circuits ,,but at h bridge i get shape like thick sine wave,,not smooth like yours whats should i do please help me for this;;;
    regards
    abdul

    ReplyDelete
    Replies
    1. That's an indication of a problem with filtering. Adjust the values of the filter components you are using.

      Regards,
      Tahmid.

      Delete
  8. Thank you so much Tahmid , Is there anyway to get the sine signal at the output of the h bridge without using filtering ? Or do we have to use it certainly ? also do you have any other communication way , like skype , facebook etc..
    Best ,
    Abdul

    ReplyDelete
    Replies
    1. Filtering is a MUST. That's the basis on which sine wave generation with SPWM works - you approximate the sine wave with square wave digital signals, that upon filtering give a nice sine wave output.

      Regards,
      Tahmid.

      Delete
    2. thanks again for your replay
      ,but why did you add and then invert in the output h bridge signals through oscilloscope

      Delete
    3. The oscilloscope in Proteus is ground referenced. I inverted one channel and added the two channels because I needed to show the signal "with reference to each other".

      Regards,
      Tahmid.

      Delete
  9. hi tahmid ,,
    thanks so much for sharing your knowledge,, i just want to us you about your filter using to get that pure sine wave i have tried many types but i couldn't get result like yours,,if possible can you specify components of your filter
    hope you will help me in this,,
    regards
    abdul

    ReplyDelete
    Replies
    1. My one shown here is a simulation result.

      In practice, it is very time-consuming to pick the correct components for proper filtration. You must continuously tweak the value of the components if you are using trial and error method.

      Regards,
      Tahmid.

      Delete
  10. thanks again tahmid for your replay ,,
    some time when i changes the value of the filter components i got an error during simulation in a Proteus its display like this `,,, program or EEPROM data has invalid address[2000] for this device ,,,
    i wonder what is a reasons for that,,,,,,

    ReplyDelete
    Replies
    1. That is indicative of an error in the program and not the hardware. Ensure that you have compiled the program properly and are using the correct device in the simulation.

      Regarding the LC filter, you should adjust them in practice - actual hardware - instead of in Proteus simulation.

      Reagards,
      Tahmid.

      Delete
  11. hi tahmid,,
    i finally got pure sine wave like yours after add transformer(1 to 1 ratio) working as load and then 10uF capacitor at the output of h bridge but problem is i got too small voltage in terms of mV and desired output volts is 12V,,,

    also i used ir2101 driver and i connected exactly as in your tutorial ,,

    ReplyDelete
    Replies
    1. I'll say what I've said before:

      Regarding the LC filter, you should adjust them in practice - actual hardware - instead of in Proteus simulation.

      Regards,
      Tahmid.

      Delete
    2. sir can you send me ur proteous simulation.it would be helpful fr me to detect my problem....

      Delete
  12. Hi Tamid,
    Nice tutorial.
    Would you please explain the PWM generation and feedback correction for Battery charging also. I mean with the same transformer and Mosfets working in reverse to charge the battery with mains.
    Thank you
    J.T.Rao

    ReplyDelete
    Replies
    1. I'll try to write one tutorial regarding that topic soon.

      Thanks for the suggestion!

      Regards,
      Tahmid.

      Delete
  13. hi Tahmid,
    thanks you very much for sharing your knowledge to us,,,am new in this kind of inverter circuit ,,,can you help me by sending to my email you completely design so as i can learn after seen a working simulation circuit,,, so that letter i can modify or making my own after learning from yours
    i real appreciate if you can help me.........
    my email gandolf_12@yahoo.com;
    regards,
    ahmad

    ReplyDelete
    Replies
    1. Unfortunately, I don't have a complete design with working simulation. You can learn by yourself by searching for information online. There's also quite a lot of material on this blog itself.

      Regards,
      Tahmid.

      Delete
  14. hi
    great job. pls can you post the code in .ASM ..and can i do without h bridge drivers using the pic..thanks.

    ReplyDelete
    Replies
    1. Hi,
      The code is only in C. You can download mikroC for free from their website.

      You can't drive a H-bridge without some sort of H-bridge driver. I prefer to use dedicated driver chips such as IR2110, L6385E, etc. You can do it using discrete components as well.

      Regards,
      Tahmid.

      Delete
  15. void interrupt(){
    if (TMR2IF_bit == 1){
    TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
    if (TBL_POINTER_NEW < TBL_POINTER_OLD){
    //CCP1CON.P1M1 = ~CCP1CON.P1M1; //Reverse direction of full-bridge
    if (Direction == 0){
    MOSA = 0;
    MOSD = 0;
    MOSB = 1;
    MOSC = 1;
    Direction = 1;
    }
    else{
    MOSB = 0;
    MOSC = 0;
    MOSA = 1;
    MOSD = 1;
    Direction = 0;
    }
    }
    TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 11;
    DUTY_CYCLE = TBL_POINTER_SHIFT;
    CCPR1L = sin_table[DUTY_CYCLE];
    TBL_POINTER_OLD = TBL_POINTER_NEW;
    TMR2IF_bit = 0;
    }

    icould not understand the above (interrupt)
    can you explain it in a simple way

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. thanks tahmid for demystifying the technique of the SPWM. I already understand it perfectly well. Concerning Generating SPWM without ECCP such as in this case. There is just a simple question i want to ask u.
      unsigned char FlagReg;
      sbit Direction at FlagReg.B0; These lines in ur code is actually making me not understanding this stuff.

      The FlagReg which is a register was created. The FlagReg.B0 is what? I dont understand the second line?
      Because FlagReg was not set as an array how is then that FlagReg.B0 came about..... Why cant i use "unsigned char Direction;" in place of the two lines... Thats my question. I am using mikroC version 6.2 and i Gueess u are using mikroC pro version 5.6 so the code written above is not compatible with mine and hence cannot run on version 6.2 mikroC compiler. I Tweaked your code a little... bur i got stuck at the point of............unsigned char FlagReg;........ i see dis line as a created register;
      sbit Direction at FlagReg.B0;....... i see dis line as a SFR (special function register). whats the difference between FlagReg and FlagReg.B0? why cant i use Direction just like that instead of making FlagReg and then direction?......
      Dats why i wanted to confirm these two statements. These Questions would make me understand this code fully.
      Here is the one I tweaked.

      #define MOSA PORTD.F0
      #define MOSB PORTD.F1
      #define MOSC PORTD.F2
      #define MOSD PORTD.F3

      unsigned char FlagReg;
      #define Direction FlagReg

      unsigned char sin_table[32]={0, 25, 50, 75, 99, 121, 143, 163, 181,
      198, 212, 224, 234, 242, 247, 250, 250, 247, 242, 234, 224, 212, 198,
      181, 163, 143, 121, 99, 75, 50, 25,0};


      unsigned int TBL_POINTER_NEW, TBL_POINTER_OLD, TBL_POINTER_SHIFT, SET_FREQ;
      unsigned int TBL_temp;
      unsigned char DUTY_CYCLE;

      //sbit MOSA at RD0_bit;
      //sbit MOSB at RD1_bit;
      //sbit MOSC at RD2_bit;
      //sbit MOSD at RD3_bit;

      //0 -> MOS A + D
      //1 -> MOS B + C

      void interrupt(){
      if (PIR1.F1 == 1){
      TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
      if (TBL_POINTER_NEW < TBL_POINTER_OLD){
      //CCP1CON.P1M1 = ~CCP1CON.P1M1; //Reverse direction of full-bridge
      if (Direction == 0){
      MOSA = 0;
      MOSD = 0;
      MOSB = 1;
      MOSC = 1;
      Direction = 1;
      }
      else{
      MOSB = 0;
      MOSC = 0;
      MOSA = 1;
      MOSD = 1;
      Direction = 0;
      }
      }
      TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 11;
      DUTY_CYCLE = TBL_POINTER_SHIFT;
      CCPR1L = sin_table[DUTY_CYCLE];
      TBL_POINTER_OLD = TBL_POINTER_NEW;
      PIR1.F1 = 0;
      }
      }

      void main() {
      SET_FREQ = 410;
      PORTD = 0;
      TRISD = 0;
      PR2 = 249; // 16kHz
      CCPR1L = 0;
      CCP1CON = 12; //PWM mode
      TRISC = 0xFF;
      PIR1.F1 = 0;
      T2CON = 0x04; //TMR2 on
      while (PIR1.F1 == 0);
      PIR1.F1 = 0; //Clear TMR2IF
      PORTC = 0;
      TRISC = 0;
      PIE1.F1 = 1;
      INTCON.F7 = 1;
      INTCON.F6 = 1;

      while (1);

      }

      yeah thanks tahmid for your anticipated support.......

      Delete
    3. Hello Tahmid. I use Hitech C Compiler. I have "translated" the whole program. But I am not able to understand "the same two" lines. Can you plz explain what those lines mean so that we can try to "translate" them.
      The lines:

      unsigned char FlagReg;
      sbit Direction at FlagReg.B0;

      Delete
  16. My Dear Tamid Mahabub (A great popular figure of Power electronics)

    I am extremely happy to learn that you got inspired to enter into the fascinating world of power electronics through my very elementary book POWER ELECTRONICS DEMYSTEFIED. Thank you for pointing out some inadvertent printing mistakes found in this book I consider your statement about my book in your blog as one of the greatest rewards received by me in my professional life as a design engineer, a man of science and an author of technical books.
    I am amazed by the huge popularity of your blog and your keen interest in sharing the knowledge among the thousands interested in power electronics.
    I am also highly impressed by your uncanny ablity to master the following two seemingly opposing topics;
    1. Microcontrollers and the software
    2. Hardcore Power electronics hardware domain
    Apart from this, what pleased me most was nothing other than the photo you posted on all the circuit boards with dead MOSFETS, IGBTs etc and candid declaration of many of your failures before your remarkable success you have achieved today.
    I have some humble request to you
     Please contribute some good articles to our website www.microkut.com on power electronics & microcontroller technology.
     Be an active part of this website microkut.com. In this connection please visit Calcutta and hold an official meeting with our team.
    Waiting for your reply
    Chandra Sekhar Roy
    Director
    Digital Power Corporation
    +91 9830053365
    ronixin@gmail.com
    www.microkut.com

    ReplyDelete
    Replies
    1. Dear Sir,

      Sorry for the late reply. Due to my school examinations, I could not manage time to reply.

      Your book is a great book has been a stepping stone to my future endeavors and efforts in power electronics. In fact, when someone asks me for book recommendations for power electronics, this is one of the books I recommend.

      Thank you for the compliments. I am always trying to make my blog better. I try to share as much as I can so that I can reach out to help as many people as possible.

      I am always looking to use microcontroller in power electronics for most, if not all, control in the designs. I believe that a strong ability and grasp of microcontrollers gives one complete control of the design/circuit, while at the same time resulting in the simplification of the design, improved efficiency of the design and, in most cases, a reduction in cost as well.

      I will certainly contribute to www.microkut.com . I will contact you through email regarding this.

      Visiting Calcutta may be difficult on my part now, since I have my GCE A Level examinations in May-June and will be leaving for the USA for university towards the beginning of August. If I do get time in between, I will certainly try to visit Calcutta and shall contact you then.

      I am truly honoured that a man such as yourself has visited my blog, commented on my post and has become a member. Any further comments or suggestions for improvement you may have regarding the blog will be highly appreciated.

      With thanks and regards,
      Tahmid.

      Delete
  17. TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;

    what does this means?

    SET_FREQ=410 (How?please explain.)

    what is the frequency of clock?
    why TMR (prescaler) not used?



    ReplyDelete
    Replies
    1. Go through this:

      http://tahmidmc.blogspot.com/2013/02/demystifying-use-of-table-pointer-in.html

      Regards,
      Tahmid.

      Delete
  18. how can i made a dead time between the square wave ( Rd0 , 1 , 2 , 3 ) ????

    ReplyDelete
    Replies
    1. Use a sine table with a maximum value that is quite a bit lower than (PR2 + 1). That can act as deadtime.

      Regards,
      Tahmid.

      Delete
  19. Long life to you sir Tahmid

    ReplyDelete
  20. HI TAHMID
    This is Ganesan from tamilnadu(india).I am the new one for power electronics field.I visited your blog . that was very helpful for me. i am trying to make single phase sine wave inverter. i designed your circuit "Sine Wave Generation without ECCP - Using single CCP Module of PIC16F877A" it is running successfully. but i am facing a problem in the full bridge inverter side in proteus simulation. i have attached the file with this. and also in which side i have to connect the CRO probe in the proteus. please give me a suggestion.

    ReplyDelete
  21. HI TAHMID
    This is Ganesan from tamilnadu(india).I am the new one for power electronics field.I visited your blog . that was very helpful for me. i am trying to make single phase sine wave inverter. i designed your circuit "Sine Wave Generation without ECCP - Using single CCP Module of PIC16F877A" it is running successfully. but i am facing a problem in the full bridge inverter side in proteus simulation. i have attached the file with this. and also in which side i have to connect the CRO probe in the proteus. please give me a suggestion.

    ReplyDelete
  22. hi
    i have attached the two files. first one is working . second one is not working.
    http://search.4shared.com/postDownload/e5jv9qVz/sine_wave_inverter.html

    ReplyDelete
  23. Hi Tahmid!
    visiting your blog is always helpful. you guy is doing a great job. God bless you.
    I copy your code in Mikro C compiler and build the hex file. Simulate the circuit in Proteus as shown in tutorial. PORTD is working correctly. but no signal at CCP1 pin. What can be wrong. please guide me.
    thanks!

    ReplyDelete
    Replies
    1. Check to make sure that the code is exactly as shown. It should be working fine, as I've shown in the simulation images.

      Regards,
      Tahmid.

      Delete
    2. Thanks Tahmid for your concern.
      I have checked the code three times word by word. its exactly same as shown by you. I am also amazed. code should be worked correctly.
      I am designing a single phase inverter as a part of my Final Project. I am stuck with it. Try again and again to edit the code but no way.Could you please send me your Hex file?
      I shall be very thankful to you for this regard.

      Delete
    3. There could be a problem with the simulation. You should try it on hardware. Just check that the output signals are coming from the PIC. If you get the outputs, then you can conclude that the error is in simulation.

      Regards,
      Tahmid.

      Delete
  24. Hello Tahmid, should this code work with any pic with a CCP module? I tried the code on a 18f2525 and the CCP1 pin only stays HI, I think the rest of the pins worked as they should, any advice?

    ReplyDelete
    Replies
    1. It should work with any PIC with a CCP module, provided you initialize the CCP module and use it properly. You should attach the code and DSN file. I could take a look if I get time. Upload to an online storage site such as rapidshare.

      Regards,
      Tahmid.

      Delete
  25. hello tahmid. i worked your code. it is working fine.i got sine wave output from your code.but i have faced one problem. when i run the 1/2 hp motor using this inverter IGBT IS heating.motor is not rotating.but drilling machine(500w) is working using this inverter. and here i have used igbt for H bridge driver.what will be the mistake? please guide me?

    ReplyDelete
    Replies
    1. Do the IGBTs get too hot? Have you used sufficient heatsinking? Have you used a fan? Did you measure the output voltage? What's the output voltage with the 0.5HP motor?

      Delete
    2. i have used h25r1202 as IGBT. IGBT IS very hot in the running condition of the 0.5 hp motor. i gave dc supply to the IGBT s collector terminal from the mains (Ac supply).i.e i converted ac to dc via bridge (10A).from this i got 350 v dc. will it be problem for running the motor?i have not used fan.

      Delete
  26. Hello Tahmid i was the one that asked you about the pic 18f2525.
    The links below have the DSN file and code i used.
    I really hope you get the time. Thanks in advance.
    http://www.mediafire.com/?anq4kjbo4204ara
    http://www.mediafire.com/?n30rz14ra83c0sz

    ReplyDelete
  27. hai,tahmid....i used pic 16f877a to get pulses to switch buckboost circuit.inorder to avoid the source and ground problem i used IR2111 driver ic.Mosfet i using is IRF540.But IR2111 will not be directly fed from pic since its logic high is 5V.IR2111 needs a logic high about its Vcc=12V.For resolving this problem i used an optocoupler between pic and IR2111.So i got optocoupler output with a logic high as 12 V with optocoupler Vcc as 12V.
    Anyway i got the pulses having a voltage level sufficient to turn on IRF540 (Vgs=12V).But now the problem is that,at 0.1 V input to buck boost is working.But when the input voltage is increased,it is not working.But,i noticed that the problem is that when voltage is increased pulses from pic is not there.
    Can you help.....it is urgent......

    Thank u
    shafeeq

    ReplyDelete
  28. hi tahmid,,,in your fig 2, A and D are high and low side of one bridge respectively and in figure 3, A and D are simultaneously high,,, so i have a doubt, if if A and D are both HIGH at a same time then it will be short circuit ,, please clear my confusion,,

    ReplyDelete
    Replies
    1. hai,,i think its just a mistake in naming B and D.think interchanging the connection B and D.

      Delete
  29. Hello Hahmid,
    I construct circuit as you do using Sine Wave Generation without ECCP - Using single CCP Module of PIC16F877A.And I have some problems.
    In Proteus simulation, the output of pic are ok,as you showed and they have 5V in each output(5 pins).But in real construction, 17 pin has over 3V(may be 3.2V) and the remaining pins(19,20,21,22) have over 2V(may be 2.3V).
    Why don't they have 5V each? VDD is nearly 5V.I gave the pic double supply and ground(31,32,11,12).How to set the configuration bits when i burn the hex file to pic.The power supply to MOSFETs is 12V.The two outputs have around 3V each(may be 3.4V).
    It is very less.I don't know exactly what type of transformer to be used.(When i create a mikroC pro project,how much frequencies for pic16f877a is used?)The two output and ground is connected to the transformer, there is no output from the transformer.
    What should i do? Please help me! urgent!!!!!!!!!!!!
    My mail is myinthtun08@gmail.com.

    ReplyDelete
  30. Hi Tahmid,

    As with the PIC16F684 sine wave generation i´m working with this one to.
    And here i´m getting the same saw tooth wave at the rc filter aswell?
    I've tried many many rc configuration and even use a program to calculate the best rc combo for 50 and 60hz but i'm still getting the saw tooth wave.
    Hope you gotten my email with all the info about this one to.
    Waiting patiently for your reply.

    Cheers
    Grandi

    ReplyDelete
  31. hi Tahmid , i construct your circuit the i used hef4081 and gate ic ... when i used and gate ic no output form and gate

    ReplyDelete
    Replies
    1. Do you get the proper outputs from the microcontroller?

      Delete
  32. Hello Tahmid,me I used the PIC16F877A but the signals I am getting are not the same at all there is a difference on their on and off time ;
    mainly those signals which pass through the AND gate are not good and their on and offtime are different to the other two signals A and B
    which I think should cause a short circuit.

    Please help on this,firstly I used PIC16F876A and I had the same erro even on the board and simulation but I changed and took PIC16F877A
    and paste your codes as they are but I considered a difference on the on/off time meanwhile the signals are not the same as the one of yourFig. 3 - Generated SPWM Drive Signals (Click image to enlarge).

    Tell mehow may I proceed.

    Thans.

    ReplyDelete
  33. I Tahmid,I want to generate a spwm signal of 28Khz which must be used for controlling H-Bridge ,what can I do?

    I generated one referring to your tutorials but the frequency I get is 50Hz so with that the MOSFET became very hot so I want to change the controlling signal.

    Noe:This DC-AC Converter I am repairing before in its normal operation it used 28Khz for controlling the MOSFET (in H_Bridge).

    Thanks and waiting for your Good reply.

    ReplyDelete
  34. Hi Tahmid

    I ported your code to another controller from Freescale and it seems to be working fine for now.
    Can you suggest a method to change the base frequency (up to 100Hz) based on an ADC input?

    I want to congratulate you on your wonderful blog and useful libraries...cheers!!!!!!

    ReplyDelete
    Replies
    1. Please refer to this:

      Demystifying The Use of Table Pointer in SPWM - Application in Sine Wave Inverter
      http://tahmidmc.blogspot.com/2013/02/demystifying-use-of-table-pointer-in.html

      I think you'll get your answer from here.

      If you still don't, feel free to ask specific questions.

      Hope this helps!

      Regards,
      Tahmid.

      Delete
  35. Hi Tahamid, I am trying to run the code in MPLAB using Hi-Tech C. I however get so many errors and the code doesnot compile well. Could it be that the code cannot be run using MPLAB's Hi-Tech C?
    Thanks in Advance

    ReplyDelete
    Replies
    1. Of course it can. But it will take quite a lot of changes due to syntax and library differences between mikroC and Hi-Tech C.

      Regards,
      Tahmid.

      Delete
  36. hi tahmid thanks for shairing your knowladge,,
    am desigining inverter by using arduino uno ;i create 32 array by using sinetable to control pwm i saw in your blog,,,
    but the problem is my output frequency is not stable(i mean not costant ) and my pwm change all time not stablized ;
    this is my code;


    // avr-libc library includes
    #include
    #include
    int pwm1= 3;int pwm2= 11;
    byte flicker[32] = { 0, 25, 49, 73, 96, 118, 139, 159, 177, 193, 208, 220, 231, 239, 245, 249, 250, 249, 245, 239, 231, 220, 208, 193, 177, 159, 139, 118, 96, 73, 49, 25};
    void setup() {
    pinMode(pwm1, OUTPUT);
    pinMode(pwm2, OUTPUT);
    // initialize Timer1
    OCR2A=0;
    OCR2B=0;
    TCCR2A = 0;
    TCCR2B =0; // put your setup code here, to run once:
    TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
    TCCR2B = _BV(CS22);


    }

    void loop() {
    for(int i=0; i<31; i++) // loop equals number
    { // of values in array
    analogWrite(pwm1,OCR2A= flicker[i]);
    analogWrite(pwm2,0);

    }

    for(int i=31; i>=0; i--) // loop equals number
    { // of values in array
    analogWrite(pwm1,OCR2A= 0);
    analogWrite(pwm2,OCR2B= flicker[i]);

    }

    }

    regards abdul

    ReplyDelete
  37. Hi Tahmid, thanks for the great work
    I have failed to find IR2110 in Proteus ISIS professional but instead found IR2101. How can I connect it?
    Also, pin 17 of the PIC is always at 0 voltage, during the simulation. What could be the problem?
    Regards Henry Kato

    ReplyDelete
    Replies
    1. Pin 17 is not supposed to be always at zero. Use the oscilloscope to check the signal at pin 17.

      You can use IR2101 in place of IR2110. I think all you need to do is to account for the pin-out differences.

      You might find it helpful to refer to this:

      http://tahmidmc.blogspot.com/2013/01/using-high-low-side-driver-ir2110-with.html

      If you still can't do it, then feel free to ask and I'll try to help you further.

      Regards,
      Tahmid.

      Delete
    2. i have the same issue plz help...

      Delete
  38. How to make H-Bridge Sine wave Inverter with Pic16f72 with feedback at 50hz fixed frequency? Plz Help.......

    ReplyDelete
  39. HI TAHMID , I used your mikroC code without ECCP module. when I combile this code with MikroC PRO version 5.01, i got hex file. But i see ccp1 pin is not working when i do simulation ISIS proteus. So i can't see sine wave in ISIS. That is my problem. I want to know MikroC PRO version you combile. Depand on MikroC PRO version? PLS help me , i have MikroC PRO version 5.01 only,.. so pls share code mikroC PRO version 5.01. Thank You. Mr. Soe

    ReplyDelete
    Replies
    1. PLS suggestion to me, Can i use which mikroC version for 16F877A without ECCP module?

      Delete
    2. The mikroC version shouldn't matter. Double check everything you did.

      Delete
  40. Hi Tahmid, i compiled the code and get hex file, the program is running fine when i simulate in proteus, but the SPWM has some sort of distortion, is not as clean as yours, and when i connect the COUNTER TIMER in proteus, instaed of displaying the frequency it counts upward continuously. Pls. Tahmid help, what am i doing wrong

    ReplyDelete
    Replies
    1. I recommend trying the circuit in actual hardware.

      You need to change the mode of the timer/counter to frequency measurement. Double click the timer/counter and you can see the setting to change to frequency measurement.

      Regards,
      Tahmid.

      Delete
  41. Hi Tahmid, how to calculate dead time. Plz Help

    ReplyDelete
    Replies
    1. You need to select something that you think won't cause a short circuit. If you use a good drive circuit, this won't be too long.

      You also need to consider the MOSFET you're using and how long it takes for it to turn off completely.

      Regards,
      Tahmid.

      Delete
  42. This comment has been removed by the author.

    ReplyDelete
  43. Hi Tahmid, i am really surprise to see your knowledge about power electronic specially microcontroller. This is amazing for me from BD. I need information about inverter, which u explain here but is it pure sinewave inverter in practically ? i use TC4420 mosfet driver but i can't get sin wave ,it has some distance to show half cycle and then other. what can i do pls tell me? i am waiting for ur reply.

    ReplyDelete
    Replies
    1. The output should be a sine wave when passed through a low pass LC filter. You should be able to observe the waveform using an RC filter. But for practical use, you need to use an LC filter.

      You can't use a TC4420 MOSFET driver to drive a MOSFET H-bridge. The two upper MOSFETs require high-side drive. TC4420 is just a low-side driver.

      Regards,
      Tahmid.

      Delete
  44. Dear tahmid
    how low pass filter is designed.
    must reply

    ReplyDelete
    Replies
    1. Search on Google for "LC low pass filter".

      Regards,
      Tahmid.

      Delete
  45. Dear Tahmid
    Firstly I would like to wish you a Blessed New Year for 2014, I have read through your blog and have attempted to design a pure sine wave inverter. I am using a H bridge topology with its high side mosfets driven by the mosfet driver IR2110. The mosfets are driven by a mcrocontroller, PIC16F877, which is programmed to drive the mosfets using SPWM. I have used your SPWM code and changed its base frequency to 60Hz using the same switching 16kHz switching frequency and 32 elemnets in the sine wave array. I am using Proteus 8 Professional and have upload the simulations that I have done so far.

    http://www.4shared.com/rar/xT5DGSgice/Files.html?

    Problems:

    1. I have read your comments where you included a 0 at the end of the array to increase deadtime as well as when using the smart sine have the peak value lower than (PR2 + 1). I have done this and have realised that the dead time is not evenly spaced during certain intervals. Can you help me on this??

    2. I interfaced the PIC with the H Bridge and I am getting an error stating:
    {Spice} TRAN: Timestep too small; timestep = 1.25e-019: trouble with node #00052.
    This node joins resistor 4, R4, and the right low side mosfet, Q4, together. I do not know how to remedy this problem. From your blog I have seen you posted your resultant sine wave after using a low pass filter on your H bridge which means you have gotten your circuit to work. I hope you can help me in getting me through this problem so I can get mine to work.

    ReplyDelete
    Replies
    1. Hello my friend!!! i'1ve downloaded your schematic!!!! See the diagram for IR2110!!! http://www.avislab.com/blog/ir2101/ and see datasheet: http://www.irf.com/product-info/datasheets/data/ir2101.pdf!!! See the diagram!!!

      Delete
  46. Sir,
    I want arduino uno code for 3 phase "Sinusoidal pwm"
    It must be such that we must get totally 6 outputs- from pins 11,10,9 and 3,5,6 of arduino.
    Please help me , it is an urgent....
    My mail id is rhlk92@gmail.com

    ReplyDelete
    Replies
    1. for arduino uno you can generate output in square and convert to sine wave using filters then the output transformer!!!!

      Delete
  47. Hi Tahmid, On ur pic16f72 sinewave, pls how can u help me out, 1, to change the push reset switch to normal off / on switch. 2, to increase the 3.2khz to 5khz thanks. fmtech83@yahoo.com

    ReplyDelete
  48. pls can i use this pic16f72 circuit to drive 180volt inverter with IGBT?

    ReplyDelete
    Replies
    1. Yes you can. The PIC 16F72 has a CCP module that you can use for pulse width modulation for whatever you need. You just need a driver stage between the PIC and the IGBT.

      Regards,
      Tahmid.

      Delete
  49. HI TAHMID , i going to use the 16f877a microcontroller for producing sine wave.it have 2 ccp module.i want to produce the sine wave for 3 phase .so which pic i have to use.also tell about driver circuit.

    ReplyDelete
    Replies
    1. Take a look at the PIC16F777.

      Additionally, you can look at the motor control DSPICs. Take a look at the dsPIC33MC series of microcontrollers.

      You need to use 3 high-low side drivers for your circuit.

      Regards,
      Tahmid.

      Delete
    2. thank you for your reply.i selected the pic 16f777 for producing 3 phase sine wave.by using this i want to produce space vector modulating wave using sampled reference frame algorithm .can you send the coding for this.

      Delete
  50. hi tahmid ,can you explain the program the sine wave generation using pic 16f877a

    ReplyDelete
  51. I didnt get the deadtime in my simulated output.
    Pls give suggestion for modifying the sine table
    I'm using 512 samples in the sine table. My oscillator freq = 20Mhz and carrier freq is 20Khz

    ReplyDelete
    Replies
    1. Add zeros at the ends of the sine table to include a sort of deadtime.

      Delete
  52. hi i am using nuc 140ve3cn arm board ....may i know how to produce SPWM?

    ReplyDelete
    Replies
    1. I haven't worked with that microcontroller. However, the general idea should be the same. Go here:

      http://tahmidmc.blogspot.com/p/blog-page.html

      Look under SPWM and sine wave generation and inverter. Read through those to get a general idea of how SPWM works. Then use the onboard PWM module (I assume there's at least one) and create your own implementation of SPWM. If you get stuck, I'll be more than glad to help you try and resolve the issues - however I can only provide a high level support as I don't know the internals of that controller. Good luck!

      Regards,
      Tahmid.

      Delete
  53. hi Tahmid,
    Great tutorial. I am facing problem with output filtering circuit. Please give me idea about filtering circuit so that I will get pure sine wave.

    ReplyDelete
    Replies
    1. You will need to use a low-pass LC filter. Set the "cutoff frequency" to about 500Hz and keep on experimenting from there (trial and error method) to determine the best values of inductance and capacitance.

      Regards,
      Tahmid.

      Delete
  54. Can I use TLP250 to drive the MOSFET using this tutorial?

    ReplyDelete
    Replies
    1. You will need to either use an external power supply or a bootstrap drive method to drive the high side MOSFET.

      Regards,
      Tahmid.

      Delete
  55. can I use ccp1 and ccp2 both at a time for different pwm generation?

    ReplyDelete
    Replies
    1. Yes you can. They are independent modules. Be careful though: they have the same timebase. Keep that in mind.

      Regards,
      Tahmid.

      Delete
  56. sbit Direction at FlagReg.B0;
    i cannot get this point..what is it used for ?

    ReplyDelete
    Replies
    1. I created a variable called FlagReg. I defined the bit 0 of that variable and called it "Direction". I use this bit to understand/tell "which direction to go". When Direction = 0, current flows through the H-bridge in one direction (due to how the program is written; the program uses the Direction bit to tell which MOSFETs to drive to control direction of current through the H-bridge). When Direction = 1, current flows through the H-bridge in the other direction.

      Regards,
      Tahmid.

      Delete
  57. thanks a lot tahmid for replying and giving me solution. If due to inductive load the nature of sine wave changes so can we control pwm using closed loop to maintain the pure nature of sine wave?

    ReplyDelete
  58. Right now I am working on closed loop digital controller for dc dc converter using PV module (solar). Can you have any tutorial which related with this? Please send me link if it is available.

    ReplyDelete
  59. Right now I am working on closed loop digital controller for dc dc converter using PV module (solar). Can you have any tutorial which related with this? Please send me link if it is available.

    ReplyDelete
  60. Hi Tahmid, On ur pic16f72 sinewave, pls how can u help me out, 1, to change the micro switch to toggle off / on switch. 2, to increase the 3.2khz to 6.8khz on inverter and 20khz on charging thanks. fmtech01@yahoo.com

    ReplyDelete
    Replies
    1. Without idea of the inverter itself, I can't provide help.

      Delete
  61. Sir ,I have copied the same program and when I run the circuit in proteus, the frequency of pin ccp, D0, D2 keeps on increasing and never ends...
    why is it so? I use the same pic, and compiler is mikroc.
    please reply

    ReplyDelete
    Replies
    1. You're probably measuring time and not frequency. Double click the frequency counter and change measurement option from time to frequency.

      Delete
  62. Dear Mr.Tamid, You posted Sine wave PWM Generator 16F877 working well. I would like to control speed by fixing pot 10k or 100k ohm.
    could you help by sending Mikroc code.

    ReplyDelete
    Replies
    1. You can adapt the idea from here to vary duty cycle:

      http://tahmidmc.blogspot.com/2012/11/feedback-in-sine-wave-inverter-pic16f.html

      Delete
  63. Hi, Tahmid....
    This is the awesome tutorial on sine wave inverter. But how I add feedback option to this code (without ECCP)???

    Thanks.

    ReplyDelete
    Replies
    1. The idea is the same for feedback, with and without ECCP. So, you can adapt the idea from:

      http://tahmidmc.blogspot.com/2012/11/feedback-in-sine-wave-inverter-pic16f.html

      Delete
  64. Assalamualaikum Tahmid,

    I'm Arman from Malaysia. currently i'm doing a project on SPWM multilevel inverter where i'm using 2 set of CHB to produce stepped output voltage. do i need to use 2 set of PIC to drive the CHB since the 2nd CHB need to be shifted 120 degree? thanks

    ReplyDelete
  65. Hi Tahmid!
    visiting your blog is always helpful. you guy is doing a great job. God bless you.
    I copy your code in Mikro C compiler and build the hex file. Simulate the circuit in Proteus as shown in tutorial. PORTD is working correctly. but no signal at CCP1 pin. What can be wrong. please guide me.
    thanks!....plz help..

    ReplyDelete
    Replies
    1. Try the circuit in hardware and see if you get an output of CCP1 pin. Might be some sort of issue on simulation.

      Delete
  66. thats a great job tahmid , im just wondering if it is possible to control this sine wave frequency from PC using UART , In other words , i need to know if I can vary the frequency from this Code ??? and what is the range of frequencies that can be applied to this project??? I need help in tha ASAP please, got 3 days for my presentation and I need to find an alternative for my DDS please replay to my email : hasanabdr@gmail.com

    ReplyDelete
  67. i want to make inverter about 1200w can u give me schematic for this?





    ReplyDelete
    Replies
    1. I don't have any readymade schematics that I can give. However you may be able to find some using Google.

      Delete
    2. sir i am using same code for pic18f452.but 16khz frequency is not coming at ccp pin.and also tell me about function of flag register in this code.i am usung ir2112 driver ic in simulation but high sided mosfet is not drive by driver ic.

      Delete
  68. Kindly share the necessary code adjustments for running this code on PIC 16F877A please.

    ReplyDelete
    Replies
    1. no adjustment required for this code.........

      Delete
  69. Hi Tamhid:

    I have read carefully the explanation of the operation of the full bridge and have a question that is:

    If A transistor turned on for 10 ms and D transistor receives the PWM signal, that branch of the full bridge is making some short circuits. Also if the transistors B and C are off which receives the load voltage.

    In my view ought to function like this:
    half cycle: A on for 10ms
    D off
    B receives the PWM signal
    C receives the PWM signal complement

    another half-cycle:
    C on for 10ms
    B off
    D receives the PWM signal
    A receives the PWM signal complement

    such that two transistors of the same branch working in complement.

    Please clarify if there is any confusion in the drawing.

    greetings
    Jose

    ReplyDelete
    Replies
    1. You are correct. There was a mistake in Fig. 2. I've corrected it now.

      Delete
  70. HOW TO GET SINE WAVE LIKE FIG. 6 IN PROTEUS SIMULATION??

    ReplyDelete
  71. HI bro........I hope u r in good health and in good mood....
    I go through ur post for sine wave generation using PIC 16F877a......
    its a nice ... i am also trying to make a single phase inverter....but I am using MPLAB with XC8 compiler........
    i could not understand this portion of Code because its in MikroC....
    """""""""""""""""
    sbit MOSA at RD0_bit;
    sbit MOSB at RD1_bit;
    sbit MOSC at RD2_bit;
    sbit MOSD at RD3_bit;

    unsigned char FlagReg;
    sbit Direction at FlagReg.B0;
    //0 -> MOS A + D
    //1 -> MOS B + C
    """""""""""""""""""""""""""""""""
    please explain me for what purpose these instructions are used.....
    Thanks in advance......... :)

    ReplyDelete
  72. Hello Mr Tahmid could u help me y showing how to connect feed back transformer net work to pic for voltage regulation > thank u

    ReplyDelete
  73. Hi Tamhid:

    Can you tell me about the filter you used for producing pure AC wave from SPWM.

    ReplyDelete
  74. Hey Tahmid, the Smart Sine software links thay you gave is not available any more, if I ask you can you share it again. Thanks a lot.

    ReplyDelete
  75. how to generate 12 gating signals.

    ReplyDelete
  76. how to generate 12 gating signals

    ReplyDelete
  77. how to generate 12 gating signals

    ReplyDelete
  78. Thanks Mr Tahmid ,but the question is how does the same pure sine wave circuit using H bridge and same transformer can charge the battery knowing that the AC voltage is very small with respect to the needed for charging the battery

    ReplyDelete
    Replies
    1. You will PWM the low-side MOSFETs in the bridge to create a boost circuit along with the transformer. The upper two MOSFETs are just used for their body diodes.

      Delete
  79. hello I'm Tahmid current research on this topic. So you can give me gmail or email address so I can not learn from you. hope you can help me and nt in my Gmail address: nvtuan.dtvt.91@Gmail.com I would like to address your mail

    ReplyDelete
  80. Mr Tahmid SPWM is very usefull for me. I faced a problem with it whrn i compile your code using MPLAB IDE , HITECH C COMPILER , some times it shows too many errors nd some time it shows one error in _main. i have changes to acces single bit sbit MOSA at RD0_bit; to #define MOSA RD0; and sbit Direction at FlagReg.B0; to #define Direction FlagReg.B0; is it correct. please help me to overcome this.

    ReplyDelete
  81. Hi Tahmid thanks for your valuable blog.. I tried the code it worked well in proteus. But while writing the HEX file generated by microc in my PIC16F877A using PICkit 2 there is absolutely no output. Even an LED blinking program does not work. But all works fine if i write an HEX file generated with MPLABX and XC8. Why is this so ? Does hex file genarted by MicroC does not work on real hardware ?

    ReplyDelete
  82. hi mr tahmid i got some questions i hope (inshallah) u answer it all for me.
    1st what (tbl pointer new,old,shift,mosa and tmp)refer to?
    2nd i dont get the equation of 410 set_fre to get 50 hz frequency?
    3rd why u wrote the( if (Direction == 0){
    MOSA = 0;
    MOSD = 0;
    MOSB = 1;
    MOSC = 1;
    Direction = 1;
    }
    else{
    MOSB = 0;
    MOSC = 0;
    MOSA = 1;
    MOSD = 1;
    Direction = 0;
    }) under the interrupt void not under the main void?
    4th (TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 11;)what no.11 refer to here?
    5th (CCP1CON = 12; //PWM mode) i changed no.12 to (0x12) once and to(0b 00010010)another time and the ccp1 pin didnt work,why?
    6th (Pulse Width = (CCPR1L,DC1B1,DC1B0) * Tosc * TMR2 Prescale Value) i need to understand this equation with example if its possible?
    *i know my questions are too much but im accounting on your kindness to help me to unerstand those questions
    thanks in advance

    ReplyDelete
  83. slt comment brancher lcd 016 avec ce montage merci

    ReplyDelete
  84. mr tahmid i wonder why you are not responding to us hope you are ok (inshallah) ?

    ReplyDelete
  85. i fail DUTY_CYCLE = TBL_POINTER_SHIFT;CCPR1L = sin_table[DUTY_CYCLE]; i don't know why . Can you help me ? i use program MPLAB .And i want to use 16f887 with mosfet output to sine wave ,single phase full bridge inverter .

    ReplyDelete
  86. hi Mr Tahmid I am following your blog for powers supply it is really helpful and its really one of nice article which u explain in simple words. I am using pic16f877a with MPLAB X IDE 3.10 and xc8 compiler. I compiled your code successfully. I changed it for 60HZ ac out. Now i am getting the 60HZ sine wave but with some garbage in it also if i increase DC line voltage like i increase from 30v DC to 45v DC after 45V DC the output sine wave distorted. all component are same as u suggested in diagrams here just Mosfet are different coz later my DC line voltage will be 250V DC..
    please help me i am stuck here.

    ReplyDelete
  87. Hi Mr Tahmid I done successfully is project for 50Hz and 60 hz. I make changes up to 200HZ but i just wondering for 400 HZ AC out. I am a hobbyist trying to make a Variable frequency drive (VFD) for Ac motor control. will u help me to get it up to 400 HZ. need help please

    ReplyDelete
  88. wow its so nice to have a project like this. but is there any way not to use this IR2110 driver ? i have STP55NF06L mosfet here available. how do i use this? thanks in advance.

    ReplyDelete
  89. Hi Tahmid,I have really gone through ur article "Sine Wave Generation without ECCP - Using single CCP Module of PIC16F877A" since I lucky ran into ur live changing blog early this year(2016). And I have also tried implementing it in Mikrobasic pro for pic as the compiler am used to, but my port pins(RD0 thru RD3) is displaying 8khz instead of 50hz on the COUNTER TIMER am using for simulation on proteus while the ccp1 pin is displaying 16khz which is normal. Even when I try playing around with SET_FREQ value it still doesn't save the situation. Pls I need ur help on this earnestly. May GOD reward u mightily.

    ReplyDelete
  90. please can anyone tell me the U2 and U3 represent
    regards to everyone here

    ReplyDelete
    Replies
    1. U2 AND U3 ARE "AND GATES" (check logic circuit basics) eg. CD4081 check datasheet....Regards

      Delete
  91. hello friend'm trying to do this project his need to know if you could provide an example of code in C for ccs using pic 18f877a

    ReplyDelete
  92. HELLO CAN YOU TELLE ME WHAT IS THE WORK OF PORT AND IN THIS PROJECT

    ReplyDelete
  93. https://www.dropbox.com/s/b90n3ts1yo3pard/Untitled.png?dl=0
    please check my Proteus result if it is correct.,

    ReplyDelete
  94. Hi
    I want to build an inverter with 4 KHZ output and 24 V DC input. the power of the inverter is limited at 24 W.
    do the same algorithm and principle work with this inverter

    ReplyDelete
  95. Hi Tamid!
    I have a question,please help.
    With this project (using 16F684) Can I using 2 IR2101 to driving full bridge mosfet directly?(using 5VDD for uC and 12Vcc for IR2101 and H bridge?
    Thank you!

    ReplyDelete
  96. This comment has been removed by the author.

    ReplyDelete
  97. This comment has been removed by the author.

    ReplyDelete
  98. Hello
    Dear Sir
    Have a nice day

    Can you help me about your code in start page why not working with PIC16F877A because no signal in pin 19,20,21,22 i am compiler the code and i program with Beeprog2 Programmer and i select the 16MHZ ?

    If i would like to convert 300VDC to 220VAC what i do ?

    Thank you

    ReplyDelete
  99. How can one use this in a half bridge with center tapped transformer?

    ReplyDelete
  100. can I drive a load of 3KVA

    ReplyDelete
  101. /*
    This code was based on Baruti SPWM code with changes made to remove errors. Use this code as you would use any other baruti’s works.
    if you have advice please send a message to the baruti.themigambo@gmail.com
    6.10. 2018
    */
    const int sPWMArray[] = {500,500,750,500,1250,500,2000,500,1250,500,750,500,500}; // This is the array with the SPWM values change them at will
    const int sPWMArrayValues = 13; // You need this since C doesn’t give you the length of an Array
    // The pins
    const int sPWMpin1 = 10;
    const int sPWMpin2 = 9;
    // The pin switches
    bool sPWMpin1Status = true;
    bool sPWMpin2Status = true;

    void setup()
    {
    pinMode(sPWMpin1, OUTPUT);
    pinMode(sPWMpin2, OUTPUT);
    }

    void loop()
    {
    // Loop for pin 1
    for(int i(0); i != sPWMArrayValues; i++)
    {
    if(sPWMpin1Status)
    {
    digitalWrite(sPWMpin1, HIGH);
    delayMicroseconds(sPWMArray[i]);
    sPWMpin1Status = false;
    }
    else
    {
    digitalWrite(sPWMpin1, LOW);
    delayMicroseconds(sPWMArray[i]);
    sPWMpin1Status = true;
    }
    }

    // Loop for pin 2
    for(int i(0); i != sPWMArrayValues; i++)
    {
    if(sPWMpin2Status)
    {
    digitalWrite(sPWMpin2, HIGH);
    delayMicroseconds(sPWMArray[i]);
    sPWMpin2Status = false;
    }
    else
    {
    digitalWrite(sPWMpin2, LOW);
    delayMicroseconds(sPWMArray[i]);
    sPWMpin2Status = true;
    }
    }
    }

    ReplyDelete
  102. Hi Tahmid.
    I think at SPWM zero points one of transformers pins is floating. Am i wrong?

    ReplyDelete
  103. Hi tahmid,
    your code is very useful. in this code i can not control frequency. please add increment and decrement push button switch with this code.that means i want to control frequency with push button. please help me to modify this code and pls send it to my mail..milonctl@yahoo.com

    thanks

    ReplyDelete
  104. inverter no Feedback tested all ok tinks for yo tahmid 12v & 170v all ok 170V 32OV not fonction

    ReplyDelete
  105. Hi Tahmid, congratulations on your project,
    There's like you. alter the code routine to work at 60 Hz? here in Brazil our frequency is 60Hz

    ReplyDelete
  106. ple can u send me Hex file for pic16f877 with circuit diagram,my email is reubenmuniko727@gmail.com

    ReplyDelete