Pure sine wave generation using PIC16F73/PIC16F76

Published by MKDas on

In this tutorial, we are going to learn how to generate a pure sine waves with PIC16F73 or PIC16F76 micro-controller. We will learn how SPWM is generated and how we can get a pure sine wave from SPWM. After learning the basic concept you can implement this into your project. So be with me and read to the end of this article.

Disclaimer: Electricity is always dangerous. Skill required to work with electricity. Do work with your own risk. Author will not be responsible for any misuse or harmful act. This website contents is also copyright protected. Anything copied and directly posted in your website and claiming it as yours is prohibited and nonsensical. Author published all the articles as opensource to help you making your project and learning purpose only. Learn and make one for yourself. If need any help feel free to ask the author. Author will be helpful to you. Thanks.

Pure sine wave generation techniques:

Generating pure sine wave is one of the most interesting work in power electronics study. Pure sine wave can be generated in different ways. You can use either

  • Analog Circuits designed with Op-Amp
  • Using ICL8038 function generating IC
  • SPWM generation with Op-Amp circuits.
  • Using SPWM generated with a micro-controller.

You may find other ways to generate a sine wave. Whatever the way you select it depends on your choice. In this article, we will discuss the last technique from the list mentioned above.

What is SPWM:

SPWM means Sinusoidal Pulse Width Modulation. A PWM signal with variable duty cycle according to a sinusoidal wave. It is something like this:

SPWM signal

Here there is a triangular wave and a sine wave of low frequency than the triangular one. If we compare these two signals with the help of an Op-Amp, we will get a PWM signal. This PWM signal has a variable duty cycle, which is increasing slowly in the midpoint of our reference sine wave and decreasing in corners.

SPWM feature of micro-controller:

No, the PIC16F73/76 micro-controller does not have any special feature to generate SPWM. But it can generate PWM which is known as the CCP module of micro-controller.

Using this CCP module we can generate a PWM signal. Now, all we need to do is changing the duty cycle of this PWM signal in a sinusoidal way so that we can get a pure sine wave after filtering this signal. Now we will do coding for SPWM. But to make sine wave, here we are using a lookup table. This table can be self-written or you can use software to generate your sine table. I’ll use Smart Sine to generate my sine table here.

Sine table generation using Smart Sine:

This tool is very easy to use. Just put your No. of table entries, peak point and angle. You’ll get a sine table clicking the calculate button.

Sine table generation using Smart Sine

So here

sin_table[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};
is our sine table of 32 entries.

MicroC Code:

/*******************************************************************************
* Pure sine wave generation technique using PIC microcontroller                *
* Program Written by_ Engr. Mithun K. Das                                      *
* MCU:PIC16F73; X-Tal: 20MHz; mikroC pro for PIC v7.6.0                        *
* Date: 13-04-2020                                                             *
*******************************************************************************/

unsigned char sin_table[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};

int duty=0;

void Interrupt() iv 0x0004 ics ICS_AUTO
{
   if (TMR2IF_bit == 1)
   {
      duty++;
      if(duty>=32)
      {
        duty=0;
        CCPR1L=0;
        asm nop;// no operation for one cycle
      }
      
      CCPR1L = sin_table[duty];
      TMR2IF_bit = 0;
   }
}

void main()
{
   TRISC = 0x00;//all output
   PR2 = 249;
   CCP1CON = 0x4C;
   TMR2IF_bit = 0;
   T2CON = 0x2C;
   TMR2IF_bit = 0;
   TRISC = 0;
   TMR2IE_bit = 1;
   GIE_bit = 1;
   PEIE_bit = 1;
   while(1)
   {
       //infinity loop
   }
}//end 

Code Explanation:

You already know that we are using a sine table here named,

sin_table[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};

Now, there is no limit of the number of entry for you sine table. More the entry, more the pure sine wave you’ll get. Only one thing to know that more entry will consume more memory. Anyway, here we will use 32 entries.

That means, if we want to get a sine of 50Hz, we have 10ms in each half-cycle. So we have to use a timer interrupt which is called 32 times within this 10ms.

void Interrupt() iv 0x0004 ics ICS_AUTO
{
   if (TMR2IF_bit == 1)
   {
      duty++;
      if(duty>=32)
      {
        duty=0;
        CCPR1L=0;
        asm nop;// no operation for one cycle
      }
      
      CCPR1L = sin_table[duty];
      TMR2IF_bit = 0;
   }
}

Here is that interrupt where we are using Timer2. Timer2 is configured by this code here to generate interrupt 32 times within 10ms.

   PR2 = 249; //Prescaler
   CCP1CON = 0x4C; //PWM control
   TMR2IF_bit = 0;
   T2CON = 0x2C;//Timer2 control bit settings
   TMR2IF_bit = 0;
   TRISC = 0;
   TMR2IE_bit = 1;
   GIE_bit = 1;
   PEIE_bit = 1;

PR2 is Prescaler and CCP1CON is the PWM control bit. And T2CON is a timer2 control bit. You can read the datasheet to know more about this.

Test Result:

We can test the simulated result using proteus. Note that you’ll find a small spike in the sine wave because of our sine table value. If you can edit the value if required to get 100% pure result.

Sine wave generation simulation result
SPWM

Now you can try your own to generate pure sine wave using PIC16F73. To get the result with PIC16F76, just use the same hex. It will work fine.


MKDas

Mithun K. Das; B.Sc. in EEE from KUET. Blog: https://labprojectsbd.com

9 Comments

enrique · September 12, 2020 at 3:57 pm

Hello, thank you very much for sharing your knowledge, I admire your work, I want to tell you that I am starting in this wonderful field of micro controllers, I would like to know, if someone helps me, what part of the code should I change to work at 60 Hz and 120 volts, in my country this is the standard.
Thank you very much

    Mithun K. Das · September 13, 2020 at 4:37 am

    Still have no design for 60Hz. But I’ll try to edit the code for 60Hz in future.

Hariharan K · January 17, 2021 at 2:12 am

Sir is this code is available in using Mplab XC8 Compiler?

    Mithun K. Das · January 19, 2021 at 3:43 am

    No, but maybe a little modification will fit in MPLAB

Georg · February 22, 2021 at 4:18 pm

Dear Mithun K. Das!

I got very important knowledge from the pulicized article, thank you very much! I just started learning with microcontrollers and the C programming language – I’m a beginner. I sought help for my first project. The task would be to produce a sine signal without overtones ( without distortion ). It is 50 Hz by default, but can also be switched to 67.5 Hz. This analog signal should be in a very good quality analog amplifier stage. This unit is already working perfectly. I have a PIC16F887 type microcontroller in MikroElektronika MikroC PRO and EasyPIC v7 development environment. I would like to ask if I need to change anything in the program when using the PIC16F887? How can I attach the signal directly from the microcontroller, or would it be better with a DAC device? I can’t use PROTEUS completely well yet. I design with MULTISIM software. Does step 32 generate a sufficiently “smooth” sine signal, or can the number of steps be increased?

Thanks for helping!

    Mithun K. Das · February 23, 2021 at 5:04 am

    It is not clear to me about the use of your sine wave signal. If you want to generate a pure signal, I’ll suggest using dsPIC. But it completely depends on your requirement and use of the signal. If you still want to use PIC MCUs then you must consider a little distortion will be in your signal. Although it is negligible % you must keep it in mind. If you need any help let me know.

Georg · February 25, 2021 at 7:27 am

Thanks for the reply! I am designing a custom built turntable. It is powered by 2 synchronous motor motors running simultaneously with a belt drive. I want to control these motors. Two frequency values ​​are required – for speeds 33.3 and 45 (and 78 possibly). I conduct the sine wave to an amplifier stage, which produces 220 v AC at 50 Hz and 65.5 Hz. I need to pay attention to the right torque and fine frequency tuning is also required. That’s why I want to solve it using PIC. I would like to start from the example given. Fine-tuning is absolutely necessary. I can’t do that with a Quartz oscillator. I have already built a quartz oscillator control.

    Mithun K. Das · February 25, 2021 at 8:34 am

    In this case, I strongly recommend you use a VFD. Making an inverter using PIC MCUs will not serve your purpose. Use dsPIC or PIC24 series with Motor Controller module built-in. Also, pay attention to the IGBT driver section.

    If you need professional’s help you can contact with our admin: mithun060@gmail.com

      Georg · February 25, 2021 at 5:50 pm

      Thank you very much for the advice and thank you for the email contact as well. I need to be further informed on the subject.

Leave a Reply

Your email address will not be published. Required fields are marked *