You are on page 1of 27

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Image Sources:

Fig. 1 Fig. 2 Fig. 3 Fig. 4 Fig. 5 Fig. 6 Fig. 7 Fig. 8 Fig. 9

dsPIC33FJ12GP202 datasheet dsPIC33F Reference Manual Output Compare Module Generated using MATLAB Screenshot of my software Smart Sine Drawn by me Drawn by me Drawn by me Simulation result obtained by me Simulation result obtained by me

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Introduction

Sine wave generation is extremely important in power electronics. It finds applications in many circuits, the most common ones being sine wave DC-AC inverters and AC motor control circuits. I have previously covered sine wave generation control using SPWM based on the PIC (with or without ECCP module) and the AVR microcontrollers. Here Ill talk about the implementation of SPWM using a dsPIC33FJ series microcontroller. The specific microcontroller Ill use is the dsPIC33FJ12GP202. This microcontroller is available in a 28-pin prototype-friendly PDIP package, making it easy to prototype; the large pin count also leaves a lot of pins free for other use. That is primarily why I chose this microcontroller. The microcontroller is certainly more than powerful enough for the application.

While I have used the dsPIC33FJ12GP202 microcontroller, the same concepts can be ported to other dsPIC microcontrollers, or even any other capable microcontroller, of course with some necessary changes.

The principle of SPWM is quite simple and Ill go through the entire process of implementing SPWM to generate sine wave using the dsPIC33FJ12GP202. I have divided this tutorial into 6 parts:

1. Explanation of the use of the dsPIC33FJ12GP202 Output Compare Module in PWM mode (without fault detection, as this isnt necessary for this simple application here) 2. Generation of the Sine Table 3. The code 4. Detailed explanation of the code, especially the sine wave generation control part 5. Circuit Configuration 6. Simulation Results

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Explanation of the use of the dsPIC33FJ12GP202 Output Compare Module in PWM mode The Output Compare Module uses one of two 16-bit timers, Timer 2 and Timer 3. The Output Compare Module compares the value of the selected timer with the output compare registers OCxR and OCxRS. The Output Compare Module changes the state of the output pin when there is a match between the timer value and the output compare register value, and also at the end of the period.

The Output Compare Module has quite a lot of modes in which it can be used, but here Im using only the PWM mode (without fault protection).

The dsPIC33FJ12GP202 has 2 Output Compare Modules. It is extremely useful to have 2 compare modules as you will see in the sine wave generation implementation below.

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Heres the Output Compare X Control Register, along with the description of the bits, (where X = 1 for Output Compare Module 1 or X = 2 for Output Compare Module 2):

Fig. 1 OCxCON (Output Compare x Control Register)

The bits description above clearly explains the function of the bits of the OCxCON register. You should notice that, with fault pin disabled, PWM mode is selected when OCM<2:0> is set to 6 (110 in binary equals 6 in decimal, 0x06 in hexadecimal). 5

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Now lets go on to how the PWM mode in the Output Compare Module works.

As you know by now, the Output Compare Module can use either Timer 2 or Timer 3 as the time base. Which timer is used is configured by the OCTSEL bit (bit 3) of the OCxCON register. Setting OCTSEL to 1 uses the Timer 3, whereas clearing OCTSEL to 0 uses the Timer 2.

The timer starts from zero and increments on every clock until it reaches the value of the Period Register (PRy, where y = 2 for Timer 2 and y = 3 for Timer 3). When the period value is reached (when value of timer equals value of the Period Register), the timer is reset and starts incrementing once again. The timer can be clocked using the internal clock source (Fosc/2) or a synchronized external clock source applied at the TxCK pin. In our circuit, we need not use any external clock and we use the internal clock source. Do remember that the internal clock frequency is not fixed at Fosc/2 and can be adjusted by changing the timer prescale value.

If the timer overflow interrupt is enabled, a timer overflow interrupt will be generated when the value of the timer equals the value of the Period Register PRy. Again, this timer will be either Timer 2 or Timer 3, as selected by the configuration of the OCTSEL bit in the output compare control Register OCxCON.

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Now, lets look at the how well set the value of PRy. PRy is related to the PWM period and PWM frequency by the following equations: = + 1 1

= So, rearranging: =

( ) 1= 1 ( ) ( )

So, you can set the PWM frequency by setting PRy. Thats good. Now how do we set the duty cycle? The PWM duty cycle is set by the value of the OCxR register. However, in PWM mode, the OCxR register is read-only. It cannot be written to. So, how do we set the PWM duty cycle? By using the OCxRS register. The OCxRS register acts as a shadow register for the OCxR register. This prevents glitches in the PWM output. Whenever the timer is reset, ie the timer rolls over, the value of the OCxRS register is loaded onto the OCxR register. So, by setting the value of the OCxRS register, we are setting the value of the OCxR register and thus setting the PWM duty cycle. So, you might think that we dont need to deal with the OCxR register. Well, we do. We should set the value of the OCxR register before enabling PWM mode because this initial value of OCxR will set the initial duty cycle of the PWM the duty cycle of the first pulse. Usually, we start with zero duty cycle and so its common to have OCxR cleared to zero before the PWM mode is enabled. Thats also what Ive done in the code.

So when the PWM mode is enabled, the OCx pin is: Driven high if the value of OCxR is non-zero. Driven low if the value of OCxR is zero.

When the timer is enabled, it starts incrementing until its value equals that of its Period Register. The value of OCxR is constantly compared with the value of the timer. When a match occurs, the OCx pin is driven low. On a timer roll-over, the value of the OCxRS register is loaded into the OCxR register. The OCx pin is then: Driven high if the value of OCxR is non-zero. Driven low if the value of OCxR is zero.

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

The PWM duty cycle is specified by writing to the OCxRS register. The duty cycle value can be written at any time, but the duty cycle value is not latched onto the OCxR register until timer Reset on a period match. This provides a double buffer for the PWM duty cycle and is essential for glitch-free PWM operation.

Some important boundary parameters of the PWM duty cycle include: If the duty cycle register, OCxR, is loaded with 0000h, the OCx pin remains low (0% duty cycle) If the OCxR register is greater than PRy (Timer Period register), the pin remains high (100% duty cycle) If the OCxR register is equal to PRy, the OCx pin is low for one time base count value and high for all other count values

The PWM resolution depends on PWM frequency and the timer clock frequency. The timer clock is derived from the internal clock (FCY) divided by a programmable prescaler.

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

The mode of operation is explained clearly by this diagram:

Fig. 2 PWM Mode Operation

10

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Generation of the Sine Table

So now, lets talk about sinusoidal pulse width modulation a bit. We want to generate a sine wave digitally using square waves. When digitally producing sine wave, we do so by using a fixed number of square wave pulses. The larger the number, the cleaner the sine wave. The duty cycles of the continuous pulses vary sinusoidally. If you dont get this now, dont worry; the following explanations will clear it up for you. For examples sake, lets say that we are using 10 samples 10 square wave pulses per sine wave half-cycle. Do bear in mind that usually, for a clean output, well use more pulses per half-cycle, usually at least 32.

So we have y=sin(x); x varies between 0 to 360 or, in radians, 0 to 2. Now, lets concentrate on the positive half-cycle. The negative half-cycle will have the same pulses in the opposite direction. Since we want to use 10 pulses per half-cycle, and the half-cycle is from 0 to 180, we have an interval equal to 18. So, were using 18 steps. So the pulses will be sent at 0, 18, 36 and so on. The values we need are:

1. 2. 3. 4. 5. 6. 7. 8. 9. 10.

sin(0) = 0 sin(18) = 0.31 sin(36) = 0.59 sin(54) = 0.81 sin(72) = 0.95 sin(90) = 1 sin(108) = 0.95 sin(126) = 0.81 sin(144) = 0.59 sin(162) = 0.31

Notice that we dont take sin(180) as this value will be called in the next half-cycle, at the beginning, when sin(0) = 0.

10

11

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Now that we know how to find the values, we have to scale them to something meaningful. We know that:

1. 2. 3. 4. 5. 6. 7. 8. 9. 10.

sin(0) = 0% sin(18) = 31% sin(36) = 59% sin(54) = 81% sin(72) = 95% sin(90) = 100% sin(108) = 95% sin(126) = 81% sin(144) = 59% sin(162) = 31%

100% is at the amplitude value at 90. This will equal the Period Register (or less if you want, but this will be the maximum value). Lets say that the carrier frequency of the SPWM is 25kHz and the dsPIC33FJ12GP202 is run from a 20MHz crystal oscillator. The carrier frequency is the frequency of the square wave pulses that will be sent, that, upon filtering, will represent a sine wave. Ive explained below about why I chose 25kHz as the carrier frequency.

From the equation given: = ( ) 1= 1 ( ) ( ) = 10 106 1 = 399 25000 1

We know that when OCxRS = PRy, the duty cycle is 100%. OCxRS is related to PRy linearly. So, if OCxRS is half of PRy, the duty cycle is 50%, and so on.

11

12

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

So, considering that the table values correspond to the duty cycles, the sine table: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. sin(0) = 0 sin(18) = 0.31 sin(36) = 0.59 sin(54) = 0.81 sin(72) = 0.95 sin(90) = 1 sin(108) = 0.95 sin(126) = 0.81 sin(144) = 0.59 sin(162) = 0.31

can be written as below, where the values represent the value to be stored in OCxRS: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. sin(0) = 0 * (PRy + 1) sin(18) = 0.31 * (PRy + 1) sin(36) = 0.59 * (PRy + 1) sin(54) = 0.81 * (PRy + 1) sin(72) = 0.95 * (PRy + 1) sin(90) = 1 * (PRy + 1) sin(108) = 0.95 * (PRy + 1) sin(126) = 0.81 * (PRy + 1) sin(144) = 0.59 * (PRy + 1) sin(162) = 0.31 * (PRy + 1)

We have calculated PRy as being equal to 399. So, our table is: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. sin(0) = 0 * (PRy + 1) = 0 * 400 = 0 sin(18) = 0.31 * (PRy + 1) = 0.31 * 400 = 124 sin(36) = 0.59 * (PRy + 1) = 0.59 * 400 = 236 sin(54) = 0.81 * (PRy + 1) = 0.81 * 400 = 324 sin(72) = 0.95 * (PRy + 1) = 0.95 * 400 = 380 sin(90) = 1 * (PRy + 1) = 1 * 400 = 400 sin(108) = 0.95 * (PRy + 1) = 0.95 * 400 = 380 sin(126) = 0.81 * (PRy + 1) = 0.81 * 400 = 324 sin(144) = 0.59 * (PRy + 1) = 0.59 * 400 = 236 sin(162) = 0.31 * (PRy + 1) = 0.31 * 400 = 124

That is our sine table: [0, 124, 236, 324, 380, 400, 380, 324, 236, 124]

12

13

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

This is what I meant previously when I said that the duty cycles are changed sinusoidally. If you plot the values of the sine table and draw a graph, youll see a sine wave shape. The more points you take, the smoother the wave will be.

Ill show that here. Here is a graph of the resultant graph of the sine table points plotted.

Fig. 3 Table points forming a sine wave

How do continuous pulses with sinusoidally varying duty cycles generate a sine wave? You know that the duty cycle controls the output voltage. When the output signal is filtered, the output voltages at different points vary sinusoidally as the duty cycle values vary sinusoidally, and the output voltage is proportional to the duty cycle. So, due to this, the output voltage observed will also be sinusoidal.

Notice the sinusoidal-ish shape obtained with just 10 values! The more values youll use the smoother the wave will be.

13

14

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Lets find the sine table for our program. The carrier frequency is 25kHz. I selected 25kHz for two reasons: 1. It is above 20kHz. So, being beyond the audible range, audible noise will not be generated. 2. The switching frequency is large enough to require a reasonably small inductor and capacitor for filtering. At the same time, the switching frequency is not too large that there will be huge switching losses.

For the PWM mode, I have used Timer 2 as the time base. So the Period Register is PR2. As calculated above, PR2 equals 399. For a really smooth sine wave, I chose 256 points per half-cycle.

It would be way too much hassle trying to calculate so many values by hand. So what I did was, I made the software Smart Sine and I use that for calculating tables. I found the above sine table using the Smart Sine software. Heres a screenshot showing the generation of the sine wave table mentioned above. For more information about Smart Sine and/or to download Smart Sine visit my blog or go to this link: http://tahmidmc.blogspot.com/2012/10/smart-sine-software-to-generate-sine.html

Fig. 4 Generating sine table with Smart Sine

14

15

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

The sine table for both half-cycles is:


{ 0, 5, 10, 15, 20, 25, 29, 34, 39, 44, 49, 54, 59, 107, 111, 116, 121, 125, 130, 135, 139, 144, 149, 184, 189, 193, 197, 201, 206, 210, 214, 218, 222, 254, 258, 261, 265, 269, 272, 276, 279, 283, 286, 312, 315, 318, 321, 324, 327, 330, 333, 335, 338, 357, 359, 362, 364, 366, 368, 370, 371, 373, 375, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 400, 400, 400, 400, 400, 400, 400, 400, 400, 399, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 373, 371, 370, 368, 366, 364, 362, 359, 357, 355, 335, 333, 330, 327, 324, 321, 318, 315, 312, 309, 283, 279, 276, 272, 269, 265, 261, 258, 254, 250, 218, 214, 210, 206, 201, 197, 193, 189, 184, 180, 144, 139, 135, 130, 125, 121, 116, 111, 107, 102, 54, 49, 44, 39, 34, 29, 25, 20, 15, 10, 5, 0, 5, 10, 15, 20, 25, 29, 34, 39, 44, 49, 54, 59, 107, 111, 116, 121, 125, 130, 135, 139, 144, 149, 184, 189, 193, 197, 201, 206, 210, 214, 218, 222, 254, 258, 261, 265, 269, 272, 276, 279, 283, 286, 312, 315, 318, 321, 324, 327, 330, 333, 335, 338, 357, 359, 362, 364, 366, 368, 370, 371, 373, 375, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 400, 400, 400, 400, 400, 400, 400, 400, 400, 399, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 373, 371, 370, 368, 366, 364, 362, 359, 357, 355, 335, 333, 330, 327, 324, 321, 318, 315, 312, 309, 283, 279, 276, 272, 269, 265, 261, 258, 254, 250, 218, 214, 210, 206, 201, 197, 193, 189, 184, 180, 144, 139, 135, 130, 125, 121, 116, 111, 107, 102, 54, 49, 44, 39, 34, 29, 25, 20, 15, 10, 5 } 64, 68, 73, 78, 83, 153, 158, 162, 167, 226, 230, 234, 238, 290, 293, 296, 300, 341, 343, 346, 348, 377, 378, 380, 381, 396, 397, 398, 398, 399, 399, 398, 398, 384, 383, 381, 380, 353, 350, 348, 346, 306, 303, 300, 296, 246, 242, 238, 234, 175, 171, 167, 162, 97, 92, 88, 83, 78, 64, 68, 73, 78, 83, 153, 158, 162, 167, 226, 230, 234, 238, 290, 293, 296, 300, 341, 343, 346, 348, 377, 378, 380, 381, 396, 397, 398, 398, 399, 399, 398, 398, 384, 383, 381, 380, 353, 350, 348, 346, 306, 303, 300, 296, 246, 242, 238, 234, 175, 171, 167, 162, 97, 92, 88, 83, 78, 88, 92, 97, 102, 171, 175, 180, 242, 246, 250, 303, 306, 309, 350, 353, 355, 383, 384, 386, 399, 399, 399, 397, 396, 396, 378, 377, 375, 343, 341, 338, 293, 290, 286, 230, 226, 222, 158, 153, 149, 73, 68, 64, 59, 88, 92, 97, 102, 171, 175, 180, 242, 246, 250, 303, 306, 309, 350, 353, 355, 383, 384, 386, 399, 399, 399, 397, 396, 396, 378, 377, 375, 343, 341, 338, 293, 290, 286, 230, 226, 222, 158, 153, 149, 73, 68, 64, 59,

Why both half-cycles? Thatll be clear once we look at my code on the next page.

15

16

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

The Code
//---------------------------------------------------------------//Programmer: Syed Tahmid Mahbub //Compiler: mikroC PRO for dsPIC v5.0.1 //Target dsPIC: dsPIC33FJ12GP202 //Program for sine wave generation using SPWM //---------------------------------------------------------------const int sin_table[512] = { 0, 5, 10, 15, 20, 25, 29, 34, 39, 44, 49, 54, 59, 64, 68, 73, 78, 83, 88, 92, 97, 102, 107, 111, 116, 121, 125, 130, 135, 139, 144, 149, 153, 158, 162, 167, 171, 175, 180, 184, 189, 193, 197, 201, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 254, 258, 261, 265, 269, 272, 276, 279, 283, 286, 290, 293, 296, 300, 303, 306, 309, 312, 315, 318, 321, 324, 327, 330, 333, 335, 338, 341, 343, 346, 348, 350, 353, 355, 357, 359, 362, 364, 366, 368, 370, 371, 373, 375, 377, 378, 380, 381, 383, 384, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 396, 397, 398, 398, 399, 399, 399, 400, 400, 400, 400, 400, 400, 400, 400, 400, 399, 399, 399, 398, 398, 397, 396, 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 384, 383, 381, 380, 378, 377, 375, 373, 371, 370, 368, 366, 364, 362, 359, 357, 355, 353, 350, 348, 346, 343, 341, 338, 335, 333, 330, 327, 324, 321, 318, 315, 312, 309, 306, 303, 300, 296, 293, 290, 286, 283, 279, 276, 272, 269, 265, 261, 258, 254, 250, 246, 242, 238, 234, 230, 226, 222, 218, 214, 210, 206, 201, 197, 193, 189, 184, 180, 175, 171, 167, 162, 158, 153, 149, 144, 139, 135, 130, 125, 121, 116, 111, 107, 102, 97, 92, 88, 83, 78, 73, 68, 64, 59, 54, 49, 44, 39, 34, 29, 25, 20, 15, 10, 5, 0, 5, 10, 15, 20, 25, 29, 34, 39, 44, 49, 54, 59, 64, 68, 73, 78, 83, 88, 92, 97, 102, 107, 111, 116, 121, 125, 130, 135, 139, 144, 149, 153, 158, 162, 167, 171, 175, 180, 184, 189, 193, 197, 201, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 254, 258, 261, 265, 269, 272, 276, 279, 283, 286, 290, 293, 296, 300, 303, 306, 309, 312, 315, 318, 321, 324, 327, 330, 333, 335, 338, 341, 343, 346, 348, 350, 353, 355, 357, 359, 362, 364, 366, 368, 370, 371, 373, 375, 377, 378, 380, 381, 383, 384, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 396, 397, 398, 398, 399, 399, 399, 400, 400, 400, 400, 400, 400, 400, 400, 400, 399, 399, 399, 398, 398, 397, 396, 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 384, 383, 381, 380, 378, 377, 375, 373, 371, 370, 368, 366, 364, 362, 359, 357, 355, 353, 350, 348, 346, 343, 341, 338, 335, 333, 330, 327, 324, 321, 318, 315, 312, 309, 306, 303, 300, 296, 293, 290, 286, 283, 279, 276, 272, 269, 265, 261, 258, 254, 250, 246, 242, 238, 234, 230, 226, 222, 218, 214, 210, 206, 201, 197, 193, 189, 184, 180, 175, 171, 167, 162, 158, 153, 149, 144, 139, 135, 130, 125, 121, 116, 111, 107, 102, 97, 92, 88, 83, 78, 73, 68, 64, 59, 54, 49, 44, 39, 34, 29, 25, 20, 15, 10, 5 };

16

17

Sine Wave Generation and Implementation using dsPIC33FJ


sbit MOSA at LATB2_bit; sbit MOSC at LATB3_bit; //D at LATB0_bit; //B at LATB1_bit; unsigned int Result; int PWM_Scaling = 399; int Frequency = 131; unsigned int Phase; int TBL_ID; void T2Int() org 0x0022{ Phase = Phase + Frequency; Result = Phase >> 7;

Syed Tahmid Mahbub

//25kHz //50Hz

//Timer 2 overflow interrupt

TBL_ID = sin_table[Result]; if (Result < 256){ //A and D on OC2RS = 0; MOSC = 0; OC1RS = TBL_ID; MOSA = 1; } else{ //B and C on OC1RS = 0; MOSA = 0; OC2RS = TBL_ID; MOSC = 1; } T2IF_bit = 0; } void main() { LATB = 0; TRISB = 0; AD1PCFGL = 0x3F; PR2 = PWM_Scaling; OC1CON = 0; OC1R = 0; OC1RS = 0; OC1CON = 0x0006; OC2CON = 0; OC2R = 0; OC2RS = 0; OC2CON = 0x0006; RPOR0 = 0x1213;

//All PORTB output //All digital //Set Frequency by setting Period Register //PR2 since I'll be using Timer 2 //Disable compare module //Initial duty cycle = 0 //Keep running in idle mode, Time base is TMR2, //PWM mode with fault pin disabled //Initial duty cycle = 0

//RP0 - OC1, RP1 - OC2

17

18

Sine Wave Generation and Implementation using dsPIC33FJ


SR = 0; T2IF_bit = T2IP_2_bit T2IP_1_bit T2IP_0_bit T2IE_bit =

Syed Tahmid Mahbub

0; = 1; = 1; = 1; 1;

//CPU priority interrupt level 0 //Clear TMR2 interrupt flag

//TMR2 interrupt priority 7 //Enable TMR2 interrupt //TMR2 on, prescaler 1

T2CON = 0x8000;

while (1){ } }

//Infinite loop Nothing to do now

//End of code

18

19

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Explanation of the Code

Ive added comments to every line in the main() function to make it self-explanatory. Ill have to explain the interrupt and Ill do that here.

Heres the interrupt code:

void T2Int() org 0x0022{ Phase = Phase + Frequency; Result = Phase >> 7;

//Timer 2 overflow interrupt

TBL_ID = sin_table[Result]; if (Result < 256){ //A and D on OC2RS = 0; MOSC = 0; OC1RS = TBL_ID; MOSA = 1; } else{ //B and C on OC1RS = 0; MOSA = 0; OC2RS = TBL_ID; MOSC = 1; } T2IF_bit = 0; }

The interrupt is generated at the end of every PWM cycle. That is when the value of Timer 2 equals the value of the Period Register PR2. The PWM frequency is 25kHz. So the PWM period is equal to (1/25000)s = 40s. So, the interrupt service routine is carried out every 40s. 1 50Hz half cycle is 10ms. So in one half-cycle, the ISR is carried out (10000/40) times = 250 times. 0x0022 is the interrupt vector for the TMR2 overflow interrupt.

The value of the register Frequency sets the frequency of the output sine wave. Okay, so lets go on to explain the interrupt. Phase is a 16-bit register. Every interrupt, the value of Phase is increased by the value that equals Frequency.

Every 40s, the value of Phase is increased by 131. Initially, Phase has a value of 0 and every 40s, Phase is increased by 131. So, initially Phase equals 0; after the first interrupt Phase equals 131; 19

20

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

after the second interrupt Phase equals 262; and so on. After Phase is incremented by 131 every interrupt, it is then divided by 128 (>>7 is the same as dividing by 27). So every time Phase is increased by 131, Result is incremented by 1. Result is the table pointer. After 499 interrupts, Phase holds 65369. On the next interrupt, Phase overflows. So on the 500th interrupt Phase overflows, and Result then holds 0. So, Result takes values from 0 to 499. It acts as the table pointer to the sine table. The corresponding value is retrieved from the table and stored in TBL_ID.

This value is then assigned to the required duty cycle register. Now comes the tricky (and interesting) part. The first 256 values (when the table pointer will have a value from 0 to 255) correspond to one half-cycle. The next 256 values (when the table pointer will have a value from 256 to 511) correspond to the opposite half-cycle. Ive used both Output Compare Modules in PWM here. The two Output Compare Modules drive opposite MOSFETs, thereby reversing the direction of current through the load/transformer. Notice also that two MOSFETs are SPWM-ed at 25kHz, while the other two MOSFETs are turned on and off at 50Hz.

When the first 256 values are retrieved from the sine table, Output Compare Module 1 is used to drive the output, while the Output Compare Module 2 has a duty cycle of 0%, ie it is off. Similarly when the next 256 values are retrieved from the sine table, Output Compare Module 2 is used to drive the output, while the Output Compare Module 1 has a duty cycle of 0%, ie it is off. To understand this in the context of the circuit, refer to the Circuit Configuration section below.

Now, if you want to make changes to the code, heres how to calculate the different parameters.

Phase is a 16-bit register. When you change the number of sine table entries, you need to change the number of times Phase is right-shifted before being stored in Result. The number of times Phase is right-shifted before being stored in Result is equal to: 16 log 2 (. ) In our program, this was equal to: 16 log 2 512 = 16 9 = 7

And that is what I used. Just giving you an example.

20

21

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

If you want to change the carrier frequency, you have to adjust the Period Register (PRy). Ive already shown you how to calculate the value of the Period Register (PRy).

Now, if you want to change the frequency of the output sine wave, you need to change the value of the register Frequency. Frequency is related to the output sine wave frequency and the carrier frequency by the relationship:

"" =

216 ( ) ( )

For our program, this was: Frequency = 216 65536 50 = = 131.072 131 25000

So now that Ive explained the code, lets look at the circuit configuration.

21

22

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Circuit Configuration

Fig. 5 Circuit Configuration for the dsPIC33FJ12GP202

This is how the dsPIC33FJ12GP202 is configured. The configuration is a typical configuration for the dsPIC33FJ12GP202 and follows the guidelines mentioned in the datasheet (check RECOMMENDED MINIMUM CONNECTION in the dsPIC33FJ12GP202 datasheet).

C1 should be between 4.7F and 10F. C1 is the filter capacitor for the internal voltage regulator. 6.8F is a good value lying safely in the middle of the range. C2, C3 and C4 are decoupling capacitors and should be placed as close to the microcontroller as possible.

22

23

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Fig. 6 MOSFET Configuration section

Ill just talk about the operation of the circuit a little bit. Go back to the code and look again at the interrupt. Youll notice that when QD is SPWM-ed, QA is kept on, whereas QB and QC are kept off. Similarly when QB is SPWM-ed, QC is kept on, whereas QA and QD are kept off.

After the first 256 values from the sine table are called, the direction of the output is to be reversed (remember I said this before too?). For the first 256 sine table calls (when table pointer = 0 to 255), QD is SPWM-ed and QA is kept on while QB and QC are kept off. Then for the next 256 sine table calls (when table pointer = 256 to 511), QB is SPWM-ed and QC is kept on while QA and QD are kept off. This essentially reverses the direction of current through the OUTPUT. This is the direction reversion I was talking about. Do keep in mind that this is a full-bridge converter circuit and that the MOSFETs will require high-low side drive (QA and QC will require high-side MOSFET drive while QB and QD will require low-side MOSFET drive).

Another point to note is the OUTPUT labeled in the circuit configuration shown above. This will either be a step-up transformer or your output load. If youre using a step-up transformer, you usually dont need an inductor for filtering and the filter capacitor is usually placed at the secondary of the 23

24

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

transformer. If youre not using a transformer and are feeding the output to your load, then you must use an LC filter to smooth out the resulting SPWM-ed square wave output to a pure sine wave output. Below I show three common output (filter) stages used between the bridge output and the load.

Fig. 7 Common Output (Filtering) Stages So now lets see the simulation results on the next page.

24

25

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Simulation Results Here are the drive signals:

Drive Signals

Yellow Drive signal to QA

Green Drive signal to QD

Pink Drive signal to QC

Blue Drive signal to QB ----------------------------------------SPWM Frequency: 25kHz


Fig. 6 SPWM drive signals Here is the output sine wave:

Output Sine Wave after filtration: this same output shape should be obtained using an LC filter at the bridge output. Simulation uses an RC filter at the microcontroller switching outputs for demonstration. -----------------------------------------Fig. 7 Generated Output Sine Wave

Sine Wave Frequency: 50Hz

25

26

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Conclusion

The method of sinusoidal pulse width modulation (SPWM) and generating a sine wave output from these signals is not too difficult if you understand the concepts behind these. The extremely powerful dsPIC33FJ series of microcontrollers can be used to gain complete control over the SPWM signals generation and also further control of the overall circuit. I have tried to explain thoroughly the functioning and programming of the PWM mode of the Output Compare Module of the dsPIC33FJ12GP202. I have tried to discuss in detail the generation of the sine table to be used for SPWM and have provided a brief look at my software Smart Sine which Im sure will aid you in your sine table generation. I have provided the code/program I have used alongside detailed description of the code, as well as the circuit configuration, output (filter) stage configuration and finally, simulation results of the presented code. I hope that the tutorial/article that I have prepared and presented here will be of use to those who are interested in applying the (seemingly difficult) concept of SPWM to generate sine wave outputs in (not restricted to, but especially suitable for) power electronics applications, such as inverters.

Feel free to leave your comments and feedback and do make sure that you regularly visit my blog (www.tahmidmc.blogspot.com) as I try to frequently update it with new (and hopefully useful) information. If you have any suggestions or questions regarding Sine Wave Generation and Implementation using dsPIC33FJ or even regarding my blog, feel free to post them in the Comments section below.

___________________________________________ Syed Tahmid Mahbub

26

27

Sine Wave Generation and Implementation using dsPIC33FJ

Syed Tahmid Mahbub

Reference and Related Documents

1. dsPIC33FJ12GP202 datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/70264E.pdf 2. dsPIC33F Reference Manual Output Compare section: http://ww1.microchip.com/downloads/en/DeviceDoc/70209A.pdf 3. Generation and Implementation of Sine Wave Table: http://tahmidmc.blogspot.com/2011/01/generation-and-implementation-of-sine.html 4. Smart Sine Software to generate sine table: http://tahmidmc.blogspot.com/2012/10/smart-sine-software-to-generate-sine.html 5. 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

27

You might also like