PDA

View Full Version : To Generate Sine Wave Using PCPWM of PIC18F4331 (Issue)



Cyborg
- 14th February 2010, 20:53
Hi everyone,
I am trying to generate one sine wave using PCPWM of PIC18F4331. I have set the frequency of PWM to 20KHz (PTPER 249) and I am using 20MHz crystal. I have calculated the resolution which is equal to 10 bits. Hence, a value of 0 is equal to 0% duty cycle and a value of 1023 is equal to 100%.

I generated a sine table of 19 values from 0 to 90 degrees in steps of 5 with a scaling factor of 128. I have set TMR0 to 8 bits and it always starts counting from 200 to 255 then overflows. Once it overflows, it updates the pointer to the table. I believe that to complete 1 cycle, 36 samples of the sine wave are required. The TMR0 interrupt is generated every 55*1.6 us (instruction cycle) which is equal to 88 us. Hence, one cycle is generated every 36*88 us = 3.2 ms (315 Hz).

The sine table I used is below
//0-90 sine wave 128 scaling in step of 5
const char sineTable[19]={0x80,0x8B,0x96,0xA1,0xAC,0xB6,0xC0,0xC9,0xD2,0xD B,0xE2,0xE9,0xEF,0xF4,0xF8,0xFC,0xFE,0xFF,0xFF };

One more thing, the sine value once it is selected it gets multiplied by 200 then limited and sent to PDC0H and PDC0L to increase the ON time of the signal. The way I did is the max value in sine table is 255*200 = 51000 then I shift this value to the right 6 times (10bits) then send it PDC0. I am not sure if what I did is right or wrong.

I am using ISIS to simulate my program. at the moment, My sine signal is at 20 Hz and the amplitude is 1.5V P-P. What I am doing wrong? How can I increase the amplitude of the sine wave? Also can I improve the sine wave shape?

DDDvvv
- 15th February 2010, 14:50
hi,
i've been thinking about this kind of project, and im leaning towards microchips AN655 app note. it uses a 32 step lookup table to produce a 60hz sine wave, 5 bit resolution, at 19.2 khz pwm. it also gives you some code (in assembly), and ive been trying to decode that, from the comments, and the assembly code, to pbc pro, where i can easily manipulate it.
theres a big thread about a sine wave inverter, but apparently, its "top secret" and the guys are bound by corporate laws from disclosing the designs and code. the lookup table in the code is really helpful because you dont have to calculate the lookup values. good luck on your project.

Mike, K8LH
- 15th February 2010, 19:17
Hi everyone,
I am trying to generate one sine wave using PCPWM of PIC18F4331

What is the frequency of the sine wave you're trying to generate?

Cyborg
- 15th February 2010, 19:38
There is no frequency in mind. I just want to learn more about TMR0 interrupt and the generation of sine wave using PWM technique. The only thing I didnt mention in my first post is that once TMR0 interrupt is occurred, in the interrupt function, the TMR0L value is set to 200. So it counts up to 255 and then overflows.

ScaleRobotics
- 17th July 2010, 06:50
I've been interested in this as well. Using the principles of AN655, (only using DT_INTS and HPWM, rather than software PWM), here is some code. Not sure how clean my sine wave is, but it doesn't look too bad on the scope. Might be better if I trim the leads on the breadboard filter. Hopefully someone can have some fun with it. I have a feeling it might be smoother in DT_INTS using an ASM interrupt routine, so that is where I am headed next, thanks to Darrel and Bruce. Will try to give that a shot.

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=4612&d=1279345692



; Circuit Diagram:
; PIC18F2431
; Filter Diagram
;
; 2.7k 2.7k
; RC2 ___/\ /\ /\______/\ /\ /\________ Analog Output
; \/ \/ | \/ \/ |
; | |
; ----- 0.1uF ----- 0.1uF
; ----- -----
; | |
; GND GND
;
;

define OSC 40
asm
__CONFIG _CONFIG1H, _OSC_HSPLL_1H
__CONFIG _CONFIG2H, _WDTEN_OFF_2H & _WDPS_512_2H
__CONFIG _CONFIG4L, _LVP_OFF_4L
endasm

ADCON0 = 000000
ADCON1 = 000000
trisb = 111111
trisc = 111011
trisa = 111111
TMR2 = 16
PR2 = 129 ;set for 19.2Khz HPWM
LED1 var portC.1
LED2 var portC.3
Duty var word
CCP1CON.3 = 1 ' set to pwm mode
CCP1CON.2 = 1
T2CON.2=1
T2CON.0=1
STEPCOUNT var byte
stepcount = 32
; Set sine "table" in an array
sineval var byte[33]
sineval[1] = 128
sineval[2] = 148
sineval[3] = 167
sineval[4] = 185
sineval[5] = 200
sineval[6] = 213
sineval[7] = 222
sineval[8] = 228
sineval[9] = 230
sineval[10] = 228
sineval[11] = 222
sineval[12] = 213
sineval[13] = 200
sineval[14] = 185
sineval[15] = 167
sineval[16] = 148
sineval[17] = 128
sineval[18] = 108
sineval[19] = 89
sineval[20] = 71
sineval[21] = 56
sineval[22] = 43
sineval[23] = 34
sineval[24] = 28
sineval[25] = 26
sineval[26] = 28
sineval[27] = 34
sineval[28] = 43
sineval[29] = 56
sineval[30] = 71
sineval[31] = 89
sineval[32] = 108

timerone var word

INCLUDE "DT_INTS-18.bas" ; Base Interrupt System
include "ReEnterPBP-18.bas"
;LOW LED1
;high led2
ASM

INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _sine, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

T1CON = $31 ; Prescaler = 8, TMR1ON
TMR1L = 255
TMR1H = 254
@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
timerone = $FD85 ;gives about 60 htz sine
Main:
pause 5
'timerone = timerone - 1 'uncomment to vary 60hz sine
if timerone = $F9FF then timerone = $FF00

GOTO Main

'---[TMR1_INT - interrupt handler]------------------------------------------

sine:
TMR1L = timerone.byte0
TMR1H = timerone.byte1
CCPR1L = sineval[STEPCOUNT]>>1
stepcount = stepcount -1
if stepcount = 0 then stepcount = 32

@ INT_RETURN


And changing the frequency of the sine (uncomment one line):



http://www.youtube.com/watch?v=t2vMFgSQ_Qk

ScaleRobotics
- 22nd July 2010, 19:44
And here is a wiki triple sine wave using Power Control PWM at the bottom of this page: http://www.picbasic.co.uk/forum/content.php?r=229-Sine-wave-using-DT-interrupts
My scope only does two channels :(

http://www.youtube.com/watch?v=KiOz6MIA6rs

asifiqbal
- 22nd March 2014, 13:39
sinewave:; 5 volt ac at c.6 and c.7
do
high portc.7
low portc.6
pause 20
low portc.7
high portc.6
pause 20
loop
end