# producing sine waves using pic

Status
Not open for further replies.

#### jerryvdk

##### Member level 1 Can any one help me to generate three sine waves using pic16f877a.If it is not possible in software how can i generate this??

#### horace1 what frequency do you require ?
I have used a MCP41010 digital potentiometer to generate a 3KHz sine wave
MCP41010

if you need a higher frequency a DAC (Digital to Analogue converter) could be used

#### Jack// ani Less compute intensive lookup table method is the best known way for software implementation.

#### betwixt

##### Super Moderator
Staff member It certainly is possible, I have a 16F877A here producing 13 simultaneous sine waves beside me right now.

The trick is to use software PWM and periodically load values from a look-up table of sine points into the PWM duty cycle control. If you need different sine frequencies, use different tables or read the tables at a different speed. If you need different phases at one frequency, use one table and several pointers to it with their offsets adjusted to set the phase angle.

Brian.

• Jack// ani

### Jack// ani

Points: 2

#### jerryvdk

##### Member level 1 Will u please explain how to implement it. Actually i want to generate three sine waves of 120 deg phase shift with each other.

#### betwixt

##### Super Moderator
Staff member I can't show you the exact code so I will describe the principle:

First generate a table of sine look up points. These are values ranging from 0 to 255 which represent sine points from -1 to +1, you can do this easily with a spreadsheet. If all is well, the sine value 0 will be either 127 or 128, in other words half way between 0 and 255. You need to sample the sine values at fixed intervals, the easiest to use is to use 256 samples so use angles of 360/256 = 1.4 degrees, you should get a table of 256 values. If you want to be clever, you can see that the values in each quadrant are identical but mirrored so you can increase the resolution x4 if you really have to.

Next, set up a timer at 256 times the frequency you want to produce. This will be used to set the rate at which the table values are read. At each tick of the timer you move to the next value in the table, at the end you wrap around to the start again.

Then set up a faster timer if necessary to generate the PWM pulse periods, at each of the 256 steps mention before, you will load the value from the table into a counter which increments at this rate. When the value is zero, make the PIC pin high, make it low again when the counter value equals the value from the table. Keep repeating this until the next value is read from the table and then use that instead.

To make three phase signals, do all timing stages above, you only need one sine value table though. For one output pin just do as above, for the second phase and third phase signals, do as above but start one third and two thirds along the table so the values for +120 and +240 degrees are picked up at the same time as the 0 degree value.

It is actually fairly easy in software, it's visualizing it in your head that gets confusing!

Brian.

• Marcoscr, jerryvdk and Jack// ani

Points: 2

### Marcoscr

Points: 2
V
Points: 2

#### jerryvdk

##### Member level 1 Thanks for ur explanation.My doubt is that how i can assign values to sin(1.4),sin(2.8).. I assigned 128 corresponding to sin(0) since (0+256)/2=128.

---------- Post added at 13:40 ---------- Previous post was at 12:48 ----------

Next, set up a timer at 256 times the frequency you want to produce. This will be used to set the rate at which the table values are read. At each tick of the timer you move to the next value in the table, at the end you wrap around to the start again.

Then set up a faster timer if necessary to generate the PWM pulse periods, at each of the 256 steps mention before, you will load the value from the table into a counter which increments at this rate. When the value is zero, make the PIC pin high, make it low again when the counter value equals the value from the table. Keep repeating this until the next value is read from the table and then use that instead.

Brian.

The thing i understood from this is write the sine lookup table.

1)Set up a counter say 1khz(1ms), to read the data from lookup table.
2)After every 1ms read the data,make a pin high,decrement till it reaches zero,when becomes zero make the pin low and continue the cycle

Is my understanding right?

#### betwixt

##### Super Moderator
Staff member The values in the table are simply a list of sine values for each angle, scaled so the result falls between 0 and 255 so they fit best into an 8-bit number. The sine values range from -1 to +1 so the first scale them so they use all the 8 bits by multiplying by 127, this makes the range -127 to +127. As we don't really want negative numbers, add 127 to the result to make them all positive, the range is then 0 to 254.
For example:
Sin(0) = 0, 0 x 127 = 0, 0+127 = 127.
Sin(1.4) = 0.024, 0.024 x 127 = 3.10, 3.10 +127 = 130.
.
Sin(90) = 1, 1 x 127 = 127, 127 + 127 = 254.
Sin(180) = 0, 0 x 127 = 0, 0 + 127 = 127
Sin(270) = -1, -1 x 127 = -127, -127 + 127 = 0.

It's easiest to set up a small spreadsheet with the values to calculate them all quickly.

These are the PWM values at the 255 points in the sine wave which represent the voltage at that place in the sine curve. For example if you wanted a frequency of 100Hz, you would have to go through all 255 values one hundred times a second so the rate you advance through the table would be 255 x 100 = 25500 steps per second.

To actually generate the voltage, you produce the PWM waveform by running a second counter, it loops continuously and resets or sets the PIC pin according to the value read from the table. It is basically a small timing loop which is fed values from the table in a bigger loop. For example, if the table value was 0, you would simply leave the pin low all the time, if the value was 128 you would set the pin high until the small loop had counted up to 128 then set it low again. If the value was 254 the pin would be high all the time. So what you are producing is a repeated pulse on the pin that varies in width according to the table value. This is PWM ! By averaging the value with an RC filter you produce what is very close to a pure sine wave.

Brian.

• babatundeawe and Marcoscr

Points: 2

### babatundeawe

Points: 2

#### jerryvdk

##### Member level 1 I created a lookup table for sine wave and i initialised timer1 frequency as 255khz.i.e rate which advance through the table is 255 x 1000 = 255000 steps per second.

After each step i loaded lookuptable value to tmr2 and make a pin high till the counter overflows. How we can generate three simultaneous sine waves using 1 counter?

• babatundeawe

### babatundeawe

Points: 2

#### betwixt

##### Super Moderator
Staff member Easy, don't use TMR2 to hold the count, hold the count in memory and use the roll-over of TMR2 to increment it.
This way you can use TMR2 to increment more than one memory location, if you use 3 locations you get 3 simultaneous counters all incrementing at the same time.
To shift the phase between them, you load each counter from the value in a different part of the sine table. There are 256 entries in the table so if you load the first counter with the value in location X, the second from location X + 85 and the third from location X + 171 you get three sine waves almost exactly 120 degrees apart. To get exactly 120 degrees you would have to read X + 85.33 and X + 170.66 but using integers that's impossible, 85 and 171 are very close to the best values.

Brian.

• babatundeawe

### babatundeawe

Points: 2

#### jerryvdk

##### Member level 1 I wrote the program, but im not getting sine wave after integrating the pwm.im attaching my code below.Is there any mistake is there? I selected RB4,RB5,RB6 as pwm output pins.

#### Attachments

• pwm.txt
2.1 KB · Views: 78

#### betwixt

##### Super Moderator
Staff member I don't use the same compiler as you and I'm not able to run a simulation right now but the code basically looks OK.
You don't have to check the interrupt enable bits are set, they should be set once and then all you have to do is check the interrupt flags to see which caused the ISR to be called. Can you simulate it and see how often the TMR2 interrupt occurs. It should be much faster than the TMR1 interrupt. Remember that TMR2 is creating the actual PWM signals, TMR 1 is stepping through the look-up table to read the PWM start values.

Brian.

#### babatundeawe

##### Full Member level 5 pls i need to understand something about timer2. when using it in pwm mode. is the postcaler available?

thanks

#### babatundeawe

##### Full Member level 5 hi jerryvdk

i checked your code and i believe it should work but i think there are some shortcommings, and thats why you are not getting anything out.

1. i guess you are trying to load your pwm values using timer1.
if so u have to enable timer1 interrupt so that you can load the pwm values in the isr.

2. i think there is no need for ccp1 usage here as you are not comparing timer2 with the pr2 register
so instead of checking ccp1 interrupt flag check timer1 interrupt flag.

3. avoid re - entrant of interrupt.
i will suggest u diasble further interrupt so as to avoid multiple interrupt and so that you can load ur pwm as timer2 is faster than timer1 just as betwixt sugest

hope this helps
tunde

---------- Post added at 07:29 ---------- Previous post was at 07:29 ----------

hi jerryvdk

i checked your code and i believe it should work but i think there are some shortcommings, and thats why you are not getting anything out.

1. i guess you are trying to load your pwm values using timer1.
if so u have to enable timer1 interrupt so that you can load the pwm values in the isr.

2. i think there is no need for ccp1 usage here as you are not comparing timer2 with the pr2 register
so instead of checking ccp1 interrupt flag check timer1 interrupt flag.

3. avoid re - entrant of interrupt.
i will suggest u diasble further interrupt so as to avoid multiple interrupt and so that you can load ur pwm as timer2 is faster than timer1 just as betwixt sugest

hope this helps
tunde

#### nitishshaw27

##### Newbie level 2 i am given a project just to produce three pwm signals, in accordance with sinosoidal signals which are 120 degrees phase difference among them, i just need pwm signals and not sinosoidal signals.......plzz help me

m vry new to PIC, and i hav tried only PWM simple code to generate PWM signals of given PWM freq and duty cycle.

- - - Updated - - -

Brian,

can u please make me undrstnd with the code, i got you....bt cnt initiate without the codes.
and also tell me, the output which we are getting is a sine wave or pwm wave????

Last edited:

Status
Not open for further replies.