Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Easy Sine Wave Generation with PIC micro-controller

Generating Sine wave is very demanded job in power electronics field. So do to me too. I read some topics over the internet and found many ways to generate a sine wave. As most of you are really interested in generating sine wave so I’m writing today about it here.

There is some different ways out there to make a sine wave. Here I’m presenting one of my easiest one. To get this one all you need a micro-controller which have at-least 2 PWM/CCP module. But if you get the concept I’ll describe here then you can make it with your own code. So let’s see the concept generating a sine wave with two PWM/CCP module.

First of all, to get a sine wave we will need two SPWM signal. These two signals will generate sine wave after filtered with inductors and capacitors. But in between this signal and filters we need some kind of Transformer and to switch the transformer need some MOSFETs. Usually a H-Bridge will do the work for us. It will transform the DC power source being switched as per the SPWM signal that will flow through the Transformer. And from the output of the transformer we will get AC signal. And after filtering, we’ll get a pure sine wave signal.

Here is a basic H-Bridge circuit. And the image is describing itself what will happen and how we can get the AC signal from a DC signal.

h-bridge_fig1.png



asdf.png



OK, fine. Now lets see what is in a sine wave, asdf.png a sine wave there is tow half signals. Each of these half signals consumes 10mS of time for 50Hz system. So if we wish to generate a sine wave of 50Hz, we need to do a full SPWM cycle in between this 10mS. My plan is simple. In this 10mS of time, all I need to do is taking a PWM signal and the duty cycle will be around zero at the starting point, almost full at the middle of this 10mS and then zero again at the end of the 10mS. This is simple. And if this can be done, after a filter with LC, we’ll get the result.

In the mean time, we need to generate a square wave of 10mS duration. This is only for a half cycle. So to complete another half cycle, we need to do the same as we did for the first half but just reversed of the 10mS duration and same as PWM.

This will overload the MCU. So we have to make a table for PWM duty cycle. Here I’ll present a simplest one. Keep in mind that, “The more the number in the table, more the accuracy”.

sign_table[18] = {50,75,100,125,150,175,200,225,250,250,225,200,175 ,150,125,100,75,50};

We will use just 18 samples here as we are just doing the basic. And what the micro-controller have to do is, MCU will generate an interrupt of 555.55uS to execute this 18 samples twitch within that 10mS. So that the PWM duty cycle starts from low in the start of the half cycle, then maximum at the middle of the half cycle and then again low at the end of the half cycle. Thus a complete SPWM can be found. You can use Timer0 or Timer1 for this purpose. Then 18 sample will take around 10mS and twitch this sampling will make a complete cycle. Meanwhile, we will use a variable to count, when the count will be equal to 18, we’ll just reverse the clock order. Thus we will get two SPWM and two 50Hz push-pull signal. If you don’t understand why this 18 samples are taken then just look at the table. And you’ll find that, the duty cycle is maximum at the middle and lowest by the start and end. Then imagine what will happen if this digital signal is converter into analog signal, a sine wave….. Yes! It will be a sine wave.

So lets see the code here,

Code:
/*******************************************************************************
*         Project For "Sine Wave generation using two PWM with PIC"            *
*                Program Written By_ Engr. Mithun K. Das                       *
*                     MCU: PIC16F73, X-Tal: 20MHz                              *
*                           16, January, 2015                                  *
*******************************************************************************/

// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections




unsigned int duty1=50,duty2=50;
unsigned int i=0;
unsigned char sign_table[18] = {50,75,100,125,150,175,200,225,250,250,225,200,175,150,125,100,75,50};
short toggle=0;

void InitTimer1()
{
    T1CON         = 0x01;
    TMR1IF_bit         = 0;
    TMR1H         = 0xF5;
    TMR1L         = 0x28;
    TMR1IE_bit         = 1;
    INTCON         = 0xC0;
}

void Interrupt()
{
    if (TMR1IF_bit)
    {
        TMR1IF_bit = 0;
        TMR1H         = 0xF5;
        TMR1L         = 0x28;
        //Enter your code here
        i++;
        if(i==18)
        {
           toggle = ~ toggle;
           i = 0;
           if(toggle)RC2_bit = 0;
           else RC1_bit = 0;
        }

        if(toggle)
        {
            RC0_bit = 0;
            RC3_bit = 1;
            PWM1_Set_Duty(0);
            PWM2_Set_Duty(sign_table[i]);
        }
        else
        {
            RC0_bit = 1;
            RC3_bit = 0;
            PWM2_Set_Duty(0);
            PWM1_Set_Duty(sign_table[i]);
        }
    }
}


void main()
{
  TRISC = 0x00;//all output
  PORTC = 0x00;//all clear
 



  PWM1_Init(20000);//initialize at 20KHz
  PWM1_Start();
 
  PWM2_Init(20000);// initialize at 20Khz
  PWM2_Start();
 
  Lcd_Init();//initialize LCD
  Lcd_Cmd(_LCD_CLEAR);//clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);//Cursor off
  Delay_ms(100);
  Lcd_Out(1,4," SINE WAVE ");
  Lcd_Out(2,1,"Generation  Test");
  Delay_ms(2000);
  InitTimer1();//initialize Timer1 for 555us interrupt
  while(1)
  {
        Lcd_Out(1,1,"   SINE WAVE    ");
        Lcd_Out(2,1,"GENERATION  TEST");
        Delay_ms(1000);
       
        Lcd_Out(1,1," USING TWO PWM  ");
        Lcd_Out(2,1," WITH INTERRUPT ");
        Delay_ms(1000);
       
        Lcd_Out(1,1," LCD TEST WITH  ");
        Lcd_Out(2,1," TIMERS ARE ON  ");
        Delay_ms(1000);
  }
}

This code will generate the required signal. Also a LCD will be used to show some messages. After simulating the code with the circuit in proteus, we’ll get a result like this:
sine-wave-one.jpg



Now Our required signal is ready. All we need to do is to use these signals to drive the H-Bridge. Then the H-Bridge will switch a transformer and we will get an AC signal over the output of the Transformer. Then after filtering the signal, we will get the pure sine wave. Here is the rest of the circuit…

capture.jpg



s1.jpg



Bingo!!! We got the sine wave…!!!

This is the very basic way to generate sine wave. Now its your duty to use the concept. You can use it to design a pure sine wave inverter for yourself or as your wish. Its all yours.

Thank you all. If you need any further help, please contact with me. For more please visit my blog:https://labprojectsbd.com/
  • Like
Reactions: thannara123

Comments

Thanks Mr. Mithun. Very nice work. for understanding please provide the pin connection accordin to the mosfet no.
 

Part and Inventory Search

Blog entry information

Author
Mithun_K_Das
Read time
5 min read
Views
9,164
Comments
1
Last update

More entries in Uncategorized

More entries from Mithun_K_Das

Share this entry

Back
Top