Sine Wave Generation and Implementation using dsPIC33FJ
Syed Tahmid Mahbub
2
Sine Wave Generation and Implementation using dsPIC33FJ –
Syed Tahmid Mahbub
Image Sources:
Fig. 1
-
dsPIC33FJ12GP202 datasheet
Fig. 2
-
dsPIC33F Reference Manual – Output Compare Module
Fig. 3
-
Generated using MATLAB
Fig. 4
-
Screenshot of my software “Smart Sine”
Fig. 5
-
Drawn by me
Fig. 6
-
Drawn by me
Fig. 7
-
Drawn by me
Fig. 8
-
Simulation result obtained by me
Fig. 9
-
Simulation result obtained by me
2
3
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 co ntrol 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 I’ll talk about the implementation of SPWM using a dsPIC33FJ series microcontroller. The specific microcontroller I’ll use is the dsPIC33F J12GP202. 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 c hose 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 I’ll 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 isn’t necessary fo r 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
3
4
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 1 6-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 r egister value, and also at the end e nd of the period.
The Output Compare Module has quite a lot of modes in which it can be used, but here I’m 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 wa ve generation implementation below.
4
5
Sine Wave Generation and Implementation using dsPIC33FJ –
Syed Tahmid Mahbub
Here’s 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 o f the OCxCON register. You should notice that, with fault pin disabled, PWM mode is selecte d when OCM<2:0> is set to 6 (110 in binary equals 6 in decimal, 0x06 in hexadec imal). 5
6
Sine Wave Generation and Implementation using dsPIC33FJ –
Syed Tahmid Mahbub
Now let’s 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 t he OCTSEL bit (bit 3) of the OCxCON re gister. 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 exter nal clock source applied at the TxCK pin. In our circuit, we need not use any e xternal clock and we use the internal clock source. Do remember that the internal clock frequency is not fixed at F osc/2 and can be adjusted by changing the timer prescale value.
If the timer over flow 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 o utput compare control Register OCxCON.
6
7
Sine Wave Generation and Implementation using dsPIC33FJ –
Syed Tahmid Mahbub
Now, let’s look at the how w e’ll set the value of PRy. PRy is related to the PWM period per iod and PWM
frequency by the following equations:
= + 1 ⋅ ⋅ =
1
So, rearranging:
=
) ( ) ⋅ ( ) )
−1=
⋅ ( ) )
−1
So, you can set t he PWM frequency by setting PRy. That’s 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 don’t 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 it’s common to have OCxR cleared to zero before the PWM mode is enabled. That’s also what I’ve 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 e nabled, it starts incrementing until its value equals that of its Per iod Register. The value of OCxR is constantly compared with the value of the timer. When a match oc curs, the OCx pin is driven low. On a timer roll-over, t he 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.
7
8
Sine Wave Generation and Implementation using dsPIC33FJ –
Syed Tahmid Mahbub
The PWM duty cycle is specified by wr iting to the OCxRS register. 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 pe riod 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 re gister, 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 re gister 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 t imer clock frequency. The timer cl ock is derived from the internal clock (FCY) divided by a programmable prescaler.
8
9
Sine Wave Generation and Implementation using dsPIC33FJ –
The mode of operation is explained clearly by t his diagram:
Fig. 2 – PWM Mode Operation
9
Syed Tahmid Mahbub
10
Sine Wave Generation and Implementation using dsPIC33FJ –
Syed Tahmid Mahbub
Generation of the Sine Table
So now, let’s 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 don’t get this now, don’t worry; the following explanations will clear it up
for you. For example’s sake, let’s 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, we’ll use more pulses per half -cycle, -cycle, usually at least 32.
So we have y=sin(x); x varies between 0° to 360° or, in radians, 0 to 2π. Now, let’s 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 1 80°, we have an interval equal to 18°. So, we’re 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
be ginning, Notice that we don’t 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 t he 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). Let’s 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. I’ve explained below about why I chose 25kHz as the carrier frequency.
From the equation given:
=
) ( ) ⋅ ( ) ) =
−1=
10 ∗ 106 25000 ⋅ 1
⋅ ( ) )
−1
− 1 = 399
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 corr espond 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, you’ll see a sine wave shape. The more points you take, the
smoother the wave will be.
I’ll 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 vo ltage. 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 you’ll use the smoother the wave will be.
13
14
Sine Wave Generation and Implementation using dsPIC33FJ –
Syed Tahmid Mahbub
Let’s find the sine table for our program. The carrier frequency is 25kHz. I selected 25kHz for t wo
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 re quire a reasonably small inductor and capacitor for filtering. At the same time, the switching frequency is not too large that t here 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. Here’s 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,
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,
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,
Why both half- cycles? That’ll 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 –
Syed Tahmid Mahbub
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;
//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 =
}
0; = 1; = 1; = 1; 1;
Syed Tahmid Mahbub
//CPU priority interrupt level 0 //Clear TMR2 interrupt flag
//TMR2 interrupt priority 7 //Enable TMR2 interrupt
T2CON = 0x8000;
//TMR2 on, prescaler 1
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
-explanatory. I’ll have to explain I’ve added comments to every line in the main() function to make it self -explanatory. the interrupt and I’ll do that here.
Here’s 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. cyc le. That is when the value of Timer 2 equals the value of the Period Register PR2. P R2. The PWM frequency is 25kHz. So the PWM period is equal to (1/25000)s = 40µs. So, the interrupt service routine is carried out every 40µs. 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” “ Frequency” sets the frequency of the output sine wave. Okay, so let’s 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 40µs, the value of “Phase” is increased incr eased by 131. Initially, “Phase” has a value of 0 and eve ry 40µs, “Phase” is increased by 131. So, initially “Phase” e quals 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 7
interrupt, it is then divided by 128 (>>7 is the same as dividing by 2 ). So every time “Phase” is increased by 131, “Result” is incremented by 1. 1 . “Result” is the table pointer. After 499 interrupts, “Phase” holds th
65369. On the next interrupt, “Phase” overflows. So on the 500 interrupt “Phase” overflows, and
t o the sine “Result” then holds 0. So, “Result” takes v alues from 0 to 499. It acts as the table pointer to table. The corresponding value is retrieved from the table and stored in “TBL_ID”.
This value is then assigned to the re quired duty cycle register. Now comes t he tricky (and interesting) part. The first 256 values (when the table pointer will have a value from 0 t o 255) correspond to one half-cycle. The next 256 values (when the table pointer will have a value from 256 to 5 11) correspond to the opposite half-cycle. I’ve 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 C ompare 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, here’s how to calculate the different parameters.
“Phase” is a 16-bit register. When you change the number of sine table entries, you need to c hange 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 e qual 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 adj ust the Period Register (PRy). I’ve already
shown you how to calculate the value of t he Period Register (PRy).
Now, if you want to change t he 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:
Freque Frequency ncy =
216 ∗
=
65536 ∗ 50 25000
So now that I’ve explained the code, let’s look at the circuit configuration.
21
= 131.0 131.072 72 ≈ 131
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.7µF and 10µF. C1 is the filter capacitor for the internal voltage regulator. 6.8µF is a good value lying safely in the m iddle of the range. C2, C3 and C4 are decoupling capacitors and should be placed as close to t he microcontroller as possible.
22
23
Sine Wave Generation and Implementation using dsPIC33FJ –
Syed Tahmid Mahbub
Fig. 6 – MOSFET Configuration section
I’ll just talk about the operation of the circuit a little bit. Go back to the code and look again at the interrupt. You’ll 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 c alls (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 s ine table calls (when table pointer = 256 to 511), 51 1), QB is SPWM-ed and QC is kept on while QA and QD are kept off. This essentially reverses the direction of curre nt 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 you’re using a step -up transformer, you usually don’t 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 you’re 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 w ave 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 let’s 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: w ave:
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
25
Sine Wave Frequency: 50Hz
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 conce pts 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 trie d 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 I’m sure will aid you in your sine table generation. I have provided the code/progr am 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 e specially 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 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” : Generation
“
http://tahmidmc.blogspot.com/2011/01/generation-and-implementation-of-sine.html 4.
“
Smart 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 Demystifying Application in Sine Wave Inverter ” ”:
“
http://tahmidmc.blogspot.com/2013/02/demystifying-use-of-table-pointer-in.html
27