PDA

View Full Version : Generating 3-phase sine wave..



sirvo
- 16th July 2008, 01:50
Heello...

I'm trying to generate a 3-phase ~60Hz sine wave and i think it would be nice using any 16f7x7 with 3 CCP modules. The problem is that it will take a month to get these here where I live.

As I've been playing with 18f2550 @ 20MHz and got USB working really fine, I was trying to figure out if it is possible to create a windows interface to control a 3-phase sine wave.. then I would create sags, swells, harmonics and so...

The ideia is to control the 3-phase amp. and also its frequencys...(never exceeding ~62Hz..)

So, any ideias of where should I start figuring this out?

Is a RC low pass filter enought to generate a sine wave from a pic's pin pwm?

Well,, thanks for the attention!

skimask
- 16th July 2008, 15:39
More information than you can shake a stick at here...doesn't delve too much into the 3 phase aspect though...
http://www.picbasic.co.uk/forum/showthread.php?t=1846&highlight=inverter

Luciano
- 17th July 2008, 07:59
Hi Sylvio,

(Somehow related).

Speed Control of 3-Phase Induction Motor Using PIC18 Microcontrollers

Microchip AN843: (PDF)
http://ww1.microchip.com/downloads/en/AppNotes/00843a.pdf

(Code and PDF).
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en012011

Example of 3-phase bridge driver chip:
http://www.irf.com/product-info/datasheets/data/ir2136.pdf

Best regards,

Luciano

sirvo
- 18th July 2008, 19:33
Well.. Thank you Skimask and Luciano. Excelent readings!

So, I've bought a 16F777 and it has 3 CCP modules. As suggest in the readings above, it becomes easier to create an analog output when using high PWM frequencys. Using @ 20Mhz and Mister_E's PicMultiCalc, it turn out that it can generate frequencys > 20Khz, what is enought to this application.

Timer2 is responsable to control the PWM frequencys (all the same).

Timer1 is responsable to create the interruption to supply the new duty cycle value.

Now, let'ss think about the sine table and the software. Just to remember, I'll create an interface to control sine frequency, amplitude and also the sine table, as it would be interesting to create harmonics, sags and swells.

The sine table could be in the pic's data memory or it could be sent throught USART everytime that the user changes the interface option, like frequency. Do you think that it would work in real time using USART?


Thanks again!

sirvo
- 25th July 2008, 20:29
Well, things have been working until now...

When Timer1 interrupts, a INDEX var is summed and another position in a sine table is selected.. then a new value is output throught HPWM.

The sine table is filled with 72 number.. So, to create a 60Hz sine wave, o must read it at approx. 4.32KHz.

So, When I set timer1 to 64386 (1:1 prescaler @ 20MHz), it should interrupt at ~4.32KHz and create de 60Hz sine wave... but, it is generating a 26Hz... if I set timer1 to 65000, it decreases the 26Hz to 20Hz ... I didnt get iT! It should read the table faster, shoul'nt it?

Well, thanks!!!

skimask
- 25th July 2008, 20:48
So, When I set timer1 to 64386 (1:1 prescaler @ 20MHz), it should interrupt at ~4.32KHz and create de 60Hz sine wave... but, it is generating a 26Hz... if I set timer1 to 65000, it decreases the 26Hz to 20Hz ... I didnt get iT! It should read the table faster, shoul'nt it?
I'm guessing here, wild stab, since I don't see any other code here...
It might be reading it faster, but it might be missing/skipping a Tmr1 interrupt due to how long it takes to accomplish your interrupt code.
Try increasing the number by small amounts, see if it actually increases up to a point, and then drops off.

sirvo
- 25th July 2008, 20:57
So, here we go..

Didnt show var byte stuffs..




define OSC 20

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 10 ' 115200 Baud @ 20MHz, -1,36%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

' Set CCPx pins to outputs
TRISC.2 = 0 ' CCP1 output
TRISC.1 = 0 ' CCP2 output (could also be assigned to RB3)
TRISB.5 = 0 ' CCP3 output

' Set CCP modules to PWM mode
CCP1CON = %00001100 ' Mode select = PWM
CCP2CON = %00001100 ' Mode select = PWM
CCP3CON = %00001100 ' Mode select = PWM

INTCON = %11000000
LOAD = 64386' 4320Hz
'LOAD = 0
TMR1H = LOAD.HIGHBYTE
TMR1L = LOAD.LOWBYTE
T1CON = %00000001
PIE1.0 = 1
PR2 = 49
PORTD.0 = 0
' Set TMR2 up for 1:1 prescale & turn it on
T2CON = %00000100 ' TMR2 ON 1:1 prescale


ASM
INT_LIST macro ;IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _Timer1, PBP, yes

endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; Habilita interrupção do TMR1



MAIN:
IF FLAG = 1 THEN
flag = 0
CONTA = CONTA + 1
CONTB = CONTB + 1
CONTC = CONTC + 1
if contA = 71 then contA = 0
if contB = 71 then contB = 0
if contC = 71 then contC = 0

index = conta
GOSUB tabela
va = v

index = contB
GOSUB tabela
vb = v

index = contC
GOSUB tabela
vc = v

GOSUB SAIDA
endif
GOTO MAIN


TABELA:
SELECT CASE DIST
CASE 1: ' Fundamental
LOOKUP INDEX, [100,109,118,126,135,143,151,158,165,171,177,183,18 7,191,195,197,199,200,200,199,198,196,193,189,185, 180,175,168,162,154,147,139,130,122,113,104,96,87, 78,70,61,53,46,38,32,25,20,15,11,7,4,2,1,0,0,1,3,5 ,9,13,17,23,29,35,42,49,57,65,74,82,91], V
CASE 2: ' 3 com 20%
LOOKUP INDEX, [100,114,127,140,152,162,170,177,182,185,187,187,18 7,185,184,182,181,180,180,180,181,182,184,185,187, 187,187,185,182,177,170,162,152,140,127,114,100,86 ,73,60,48,38,30,23,18,15,13,13,13,15,16,18,19,20,2 0,20,19,18,16,15,13,13,13,15,18,23,30,38,48,60,73, 86], v
CASE 3: ' 3 com 20% + 5 com 10%
LOOKUP INDEX, [100,118,135,150,161,170,175,178,178,178,177,177,17 8,180,182,185,188,189,190,189,188,185,182,180,178, 177,177,178,178,178,175,170,161,150,135,118,100,82 ,65,50,39,30,25,22,22,22,23,23,22,20,18,15,12,11,1 0,11,12,15,18,20,22,23,23,22,22,22,25,30,39,50,65, 82], V
CASE 4: ' 3 com 20% + 5 com 10% + 7 com 10%
LOOKUP INDEX, [100,124,144,159,168,171,170,168,168,171,175,181,18 7,190,190,188,184,181,180,181,184,188,190,190,187, 181,175,171,168,168,170,171,168,159,144,124,100,76 ,56,41,32,29,30,32,32,29,25,19,13,10,10,12,16,19,2 0,19,16,12,10,10,13,19,25,29,32,32,30,29,32,41,56, 76], V
CASE 5: ' 5 com 10% + 7 com 20%
lookup index, [100,122,139,149,151,147,141,136,137,145,157,172,18 6,194,197,194,188,183,181,183,188,194,197,194,186, 172,157,145,137,136,141,147,151,149,139,122,100,78 ,61,51,49,53,60,64,63,55,43,28,14,6,3,6,12,17,19,1 7,12,6,3,6,14,28,43,55,63,64,59,53,49,51,61,78], v
CASE 6:
return
CASE 7:
return
end select
return

SAIDA:
CCP1CON.4 = VA.0
CCP1CON.5 = VA.1
CCPR1L = VA >> 2
CCP2CON.4 = VB.0
CCP2CON.5 = VB.1
CCPR2L = VB >> 2
CCP3CON.4 = VC.0
CCP3CON.5 = VC.1
CCPR3L = VC >> 2
RETURN

Timer1:
TMR1H = load.highbyte
TMR1L = load.lowbyte
FLAG = 1
@ INT_RETURN

END

skimask
- 25th July 2008, 21:07
Do(does?) DT_INT's reset TMR1IF for you?

Past that, get rid of everything else and just toggle a pin, only toggle a pin, and nothing but toggle a pin...and measure that and see what happens.

sirvo
- 25th July 2008, 21:48
Yes, it DO (does) reset...

I set portd.0 to toggle on timer1 interrupt and it's been working fine.. (4.2Khz)..(i didnt get rid of those stuffs)

Then I set portd.0 to toggle inside the (if Flag = 1 then...) and it's been toggling in a frequency of 900Hz... It should be also 4Khz....

Well, any idea?

Thanks!

skimask
- 26th July 2008, 06:48
Yes, it DO (does) reset...

I set portd.0 to toggle on timer1 interrupt and it's been working fine.. (4.2Khz)..(i didnt get rid of those stuffs)

Then I set portd.0 to toggle inside the (if Flag = 1 then...) and it's been toggling in a frequency of 900Hz... It should be also 4Khz....

Well, any idea?

Thanks!

Are those GOSUBs and LOOKUPs still inside the Flag=1 If/Then block?

sirvo
- 26th July 2008, 13:48
I've measured the frequency of the block (if flag = 1 then) with and without the GOSUB/LOOKUP table.. it remains still ~900Hz...

I was thinking about the HPWM frequency generated by Timer2.. Its frequency is ~100Khz ..
Should not it be the problem? Well, I changed it to 20Khz and still got 900Hz...

:(

Thanks...

skimask
- 26th July 2008, 19:09
What does this do on PortD.0?


define OSC 20
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 10 ' 115200 Baud @ 20MHz, -1,36%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
TRISC.2=0 : TRISC.1=0 : TRISB.5=0 : TRISD.0 = 0 : CCP1CON=12 : CCP2CON=12
CCP3CON=12 : INTCON=$c0 : LOAD=64386 : TMR1H=LOAD.HIGHBYTE
TMR1L=LOAD.LOWBYTE : T1CON=1 : PIE1.0 = 1 : PR2 = 49 : PORTD.0 = 0 : T2CON = 4
ASM
INT_LIST macro ;IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _Timer1, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; Habilita interrupção do TMR1
MAIN: GOTO MAIN
Timer1: TMR1H = load.highbyte : TMR1L = load.lowbyte
if portd.0 = 0 then
portd.0 = 1
else
portd.0 = 0
endif
@ INT_RETURN
END

My point is that it looks like your program 'flow' is jacked up and needs to be reworked.

Darrel Taylor
- 26th July 2008, 20:27
Sylvio,

This may sound silly, but are you sure it's a 20mhz crystal?

A 4mhz crystal with that Timer1 reload value would give ~870 hz.
<br>

skimask
- 26th July 2008, 23:05
Sylvio,
This may sound silly, but are you sure it's a 20mhz crystal?
A 4mhz crystal with that Timer1 reload value would give ~870 hz.
<br>
For that matter, it might be running on the internal 4Mhz clock and ignoring the external completely.
Pull the crystal out and see if it still runs at all...

sirvo
- 26th July 2008, 23:30
What does this do on PortD.0?

My point is that it looks like your program 'flow' is jacked up and needs to be reworked.

I've done that. It shows 4330Hz...


Sylvio,

This may sound silly, but are you sure it's a 20mhz crystal?

A 4mhz crystal with that Timer1 reload value would give ~870 hz.
<br>

Yes, I am sure about it.. It is a 20Mhz Xtal.. Then ~900Hz is the frequency that the block (if flag = 1 ..) is running, but no the timer1 interrupt...

Thanks !

skimask
- 26th July 2008, 23:35
I've done that. It shows 4330Hz...

Yes, I am sure about it.. It is a 20Mhz Xtal.. Then ~900Hz is the frequency that the block (if flag = 1 ..) is running, but no the timer1 interrupt...

Thanks !

That's why I said you're program probably needs to be reworked.
It's spending too much time inside the 'flag if/then' updating the values, therefore it appears to not be interrupting fast enough, when it's actually trying to get everything done that you want it to do. There's just not enough instruction cycles left between interrupts to get that update accomplished.

(let's see if anybody gets this reference)
I guess you could call it a 1201 or a 1202 Program Alarm.

Darrel Taylor
- 27th July 2008, 02:15
I don't know Sylvio,
I'm running it here and I don't see the same problem.

But then, I've got a 16F887. Apples and Oranges...

Timer1 runs at 4khz, and the IF block executes once after each FLAG, so it runs at 4khz too.

The whole "block" including the LOOKUP and SAIDA: takes about 70us, so it's not taking too long.

Unless there's something in the part of the program that wasn't posted. I'm stumped.
<br>

sirvo
- 27th July 2008, 02:48
I guess you could call it a 1201 or a 1202 Program Alarm.

Gosh.. hope it isn't be happening...


Darrel, did you notice that Timer2 is also running to generate the PWM frequency?

I will remake the wires and test if the crystal is really being used (not as internal osc..)

Thanks a lot!

skimask
- 27th July 2008, 06:52
Maybe a difference or two (bug fix?) in an older version vs. newer version of the 'Instant Interrupts' related to the timers?

sirvo
- 28th July 2008, 02:49
I've been using this one:


'************************************************* ***************
'* Name : DT_INTS-14.bas *
'* Author : Darrel Taylor *
'* Version : 0.93 BETA *
'* Date : JAN 29, 2006 *
'************************************************* ***************
'* Rev 0.93 Fixed CMIF and EEIF problem with older PIC's *
'* that have the Flags in PIR1 instead of PIR2 *
'* Rev 0.92 solves a "Missed Interrupt" and *
'* banking switching problem *


Is there an update?

skimask
- 28th July 2008, 03:00
'* Version : 0.93 BETA *
Is there an update?
I thought it was farther along than .93b...but after a quick bit of looking, maybe not. Then again, maybe there are a few fixes here and there that just never had the 'official' update done.

Darrel Taylor
- 28th July 2008, 03:01
.93 is the current version for the 14-bit pics.

Do you have a CLEAR statement at the TOP of your program?
<br>

sirvo
- 28th July 2008, 03:16
Last project I used the CLEAR statement, but not in this one.. Would it be necessary since I've set all the variables at the top of the program?

Darrel Taylor
- 28th July 2008, 03:22
Last project I used the CLEAR statement, but not in this one.. Would it be necessary since I've set all the variables at the top of the program?

Maybe ... I'm not really sure.
The last problem with DT_INTS-18 was because of that.

DT_INTS-14 is at .93 now because I've never really been confident enough to call it "DONE". And I don't give it as much attention as the 18F version. My Avatar could be a clue. :o

Give it a try, couldn't hurt.
<br>

sirvo
- 8th August 2008, 02:07
One week later, I'm back.. but no luck yet..

I've tried to add the CLEAR statement but nothing happened... it still remains like it was...

Is there another tip??????

Thanks!

Darrel Taylor
- 8th August 2008, 20:42
Is there another tip??????

You could post the rest of the program.

Like I said <a href=#post59895>before</a>, I've run what you posted here (on a diff chip) and everything was fine.

There may be something in the portion of the program that wasn't included. http://www.picbasic.co.uk/forum/images/icons/icon5.gif
<br>

sirvo
- 9th August 2008, 00:50
Ok...





INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts

'@ DEVICE pic16F777, HS_OSC ; System Clock Options
'@ DEVICE pic16F777, WDT_OFF ; Watchdog Timer
'@ DEVICE pic16F777, PWRT_ON ; Power-On Timer
'@ DEVICE pic16F777, MCLR_OFF ; Brown-Out Detect
'@ DEVICE pic16F777, PROTECT_OFF
@ __CONFIG _CONFIG1, _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC


define OSC 20


DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 10 ' 115200 Baud @ 20MHz, -1,36%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

clear
MODO VAR BYTE[3]
DIST VAR BYTE
SAG VAR BYTE[3]
SAG[0] = 0
SAG[1] = 0
SAG[2] = 0
SWELL VAR BYTE
SWELL = 0

CTRL VAR BYTE
LOAD VAR WORD
RA VAR BYTE
RB VAR BYTE
RC VAR BYTE
RD VAR BYTE
RA = 0
RB = 1
RC = 0
RD = 0
V VAR BYTE
VA VAR BYTE
VB VAR BYTE
VC VAR BYTE
CONTA VAR BYTE
CONTB VAR BYTE
CONTC VAR BYTE
CONT VAR BYTE
INDEX VAR BYTE
FLAG VAR BYTE
X VAR BYTE

FLAG = 0
CONTA = 0
CONTB = 23
CONTC = 47
modo[0] = 1
modo[1] = 1
modo[2] = 1
' Set CCPx pins to outputs
TRISC.2 = 0 ' CCP1 output
TRISC.1 = 0 ' CCP2 output (could also be assigned to RB3)
TRISB.5 = 0 ' CCP3 output
TRISC.7 = 1
TRISC.6 = 0
TRISD.0 = 0
' Set CCP modules to PWM mode
CCP1CON = %00001100 ' Mode select = PWM
CCP2CON = %00001100 ' Mode select = PWM
CCP3CON = %00001100 ' Mode select = PWM

INTCON = %11000000
LOAD = 65250' 4320Hz
'LOAD = 0
TMR1H = LOAD.HIGHBYTE
TMR1L = LOAD.LOWBYTE
T1CON = %00000001
PIE1.0 = 1
PR2 = 200
'PR2 = 62
PORTD.0 = 0
' Set TMR2 up for 1:1 prescale & turn it on
T2CON = %00000100 ' TMR2 ON 1:1 prescale
'T2CON = %00011100 ' TMR2 ON 1:1 prescale


ASM
INT_LIST macro ;IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _Timer1, PBP, yes
INT_Handler RX_INT, _GetChar, PBP, yes
INT_Handler TX_INT, _SendChar, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; Habilita interrupção do TMR1
@ INT_ENABLE RX_INT ;- enable the interrupt
@ INT_ENABLE TX_INT ;- enable the interrupt


MAIN:
IF FLAG = 1 THEN
PORTD.0 = 1
flag = 0
CONTA = CONTA + 1
CONTB = CONTB + 1
CONTC = CONTC + 1
if contA = 71 then contA = 0
if contB = 71 then contB = 0
if contC = 71 then contC = 0

index = conta
if RA.0 = 1 then
DIST = RB
SAG[0] = RC
MODO[0] = DIST
ELSE
DIST = MODO[0]
ENDIF
GOSUB tabela
va = (v*(100-sag[0]))/100

index = contB
if RA.1 = 1 then
DIST = RB
SAG[1] = RC
MODO[1] = DIST
ELSE
DIST = MODO[1]
ENDIF
GOSUB tabela
vb = (v*(100-SAG[1]))/100

index = contC
if RA.2 = 1 then
DIST = RB
SAG[2] = RC
MODO[2] = DIST
ELSE
DIST = MODO[2]
ENDIF
GOSUB tabela
vc = (v*(100-SAG[2]))/100

RA = 0
GOSUB SAIDA
PORTD.0 = 0
endif
GOTO MAIN


TABELA:
SELECT CASE DIST
CASE 1: ' Fundamental
LOOKUP INDEX, [100,109,118,126,135,143,151,158,165,171,177,183,18 7,191,195,197,199,200,200,199,198,196,193,189,185, 180,175,168,162,154,147,139,130,122,113,104,96,87, 78,70,61,53,46,38,32,25,20,15,11,7,4,2,1,0,0,1,3,5 ,9,13,17,23,29,35,42,49,57,65,74,82,91], V
CASE 2: ' 3 com 20%
LOOKUP INDEX, [100,114,127,140,152,162,170,177,182,185,187,187,18 7,185,184,182,181,180,180,180,181,182,184,185,187, 187,187,185,182,177,170,162,152,140,127,114,100,86 ,73,60,48,38,30,23,18,15,13,13,13,15,16,18,19,20,2 0,20,19,18,16,15,13,13,13,15,18,23,30,38,48,60,73, 86], v
CASE 3: ' 3 com 20% + 5 com 10%
LOOKUP INDEX, [100,118,135,150,161,170,175,178,178,178,177,177,17 8,180,182,185,188,189,190,189,188,185,182,180,178, 177,177,178,178,178,175,170,161,150,135,118,100,82 ,65,50,39,30,25,22,22,22,23,23,22,20,18,15,12,11,1 0,11,12,15,18,20,22,23,23,22,22,22,25,30,39,50,65, 82], V
CASE 4: ' 3 com 20% + 5 com 10% + 7 com 10%
LOOKUP INDEX, [100,124,144,159,168,171,170,168,168,171,175,181,18 7,190,190,188,184,181,180,181,184,188,190,190,187, 181,175,171,168,168,170,171,168,159,144,124,100,76 ,56,41,32,29,30,32,32,29,25,19,13,10,10,12,16,19,2 0,19,16,12,10,10,13,19,25,29,32,32,30,29,32,41,56, 76], V
CASE 5: ' 5 com 10% + 7 com 20%
lookup index, [100,122,139,149,151,147,141,136,137,145,157,172,18 6,194,197,194,188,183,181,183,188,194,197,194,186, 172,157,145,137,136,141,147,151,149,139,122,100,78 ,61,51,49,53,60,64,63,55,43,28,14,6,3,6,12,17,19,1 7,12,6,3,6,14,28,43,55,63,64,59,53,49,51,61,78], v
CASE 6:
return
CASE 7:
return
end select
return

SAIDA:
CCP1CON.4 = VA.0
CCP1CON.5 = VA.1
CCPR1L = VA >> 2
CCP2CON.4 = VB.0
CCP2CON.5 = VB.1
CCPR2L = VB >> 2
CCP3CON.4 = VC.0
CCP3CON.5 = VC.1
CCPR3L = VC >> 2
RETURN

Timer1:
TMR1H = load.highbyte
TMR1L = load.lowbyte
FLAG = 1
@ INT_RETURN

GetChar:
HSERIN [dec RA]
HSERIN [dec RB]
HSERIN [dec RC]
HSERIN [dec RD]

@ INT_ENABLE TX_INT ;- enable the interrupt
@ INT_RETURN

SendChar:
'hserout [dec cod[0], "-", dec cod[1], "-", dec cod[2], "-", dec cod[3]]
@ INT_DISABLE TX_INT ;- disable the interrupt
@ INT_RETURN

END

Darrel Taylor
- 9th August 2008, 01:31
Ah ha, there's the missing info.

With the lines ...
va = (v*(100-sag[0]))/100
I'm measuring each one at about 125us. There's 3 of them, so that's 375us, plus the 70us I measured for the main loop last time, for a total of around 450us.

Timer1 is overflowing every ~230us, so it's definately missing the Flag's.
<br>

sirvo
- 9th August 2008, 01:36
"Ah ha..."

Funny.. I'm trying to imagine the Eureka's face you had done... :)

Well, I kind of did not get it. You are saying that the program is wasting time at this statement?

va = (v*(100-sag[0]))/100

Why would it be happening? 125us just to make 1 subtract, 1 mult and 1 div?

Thanks Darrel!

Darrel Taylor
- 9th August 2008, 02:04
Yup, multiplication and division takes a LOT of loops to do.

In this (http://www.picbasic.co.uk/forum/showpost.php?p=1272&postcount=2) thread I had measured a single 16/16 divide at over 76us (382 instructions).

Keep in mind that in PBP, ALL mutiplications and divisions are done as a 16-bit operation. So even though the variables are BYTE's, it takes the same time as if they were WORD's.

I haven't timed a 16*16 multiply yet, but from these results I'd say it's probably just under 50us.

Time to find a new way to do the math.
<br>

skimask
- 9th August 2008, 06:30
Keep in mind that in PBP, ALL mutiplications and divisions are done as a 16-bit operation. So even though the variables are BYTE's, it takes the same time as if they were WORD's.
And if I remember right, ALL mult's and div's done with PBPL in 2.50B are done as signed-31-bit operations. So, now it's even 'worse'!
Sounds like it might be time for a small assembly routine for 8 and 16 bit math when speed counts...something like: @ mult16, @ mult8, @ div16, @ div8
I've been meaning to do it...sometime...when I get time...to save time...

Darrel Taylor
- 9th August 2008, 07:08
Sounds like it might be time for a small assembly routine for 8 and 16 bit math when speed counts...something like: @ mult16, @ mult8, @ div16, @ div8
I've been meaning to do it...sometime...when I get time...to save time...
That would be really handy. And if you do, here's a good place to start ...

PIC Microcontoller Basic Math Methods
http://www.piclist.com/techref/microchip/math/basic.htm
<br>

sirvo
- 11th August 2008, 01:25
Time to find a new way to do the math.
<br>

OR, increase timer1 interrupt and decrease the number of the sine table points..

However, I think that 71 points is on the edge for generating a good signal in this aplication. Reducing this number would not let the application to create good harmonics distortion due to the big step between these number...Well, all of this would be answered trying, right?

I'll get an osc. next thursday... until there I've got to wait... :(

Thanks again!

Darrel Taylor
- 11th August 2008, 04:38
sirvo> OR, increase timer1 interrupt and decrease the number of the sine table points..

Actually, I was thinking you should have a larger table at a faster rate. :)

But it'll take a few changes.
Here's a couple things that will help speed things up.

First, change the interrupt TYPE for TMR1_INT to ASM.
The handler only set's the flag and loads the timer, so it doesn't need to save all the PBP system registers. This should save about 40us.<hr>
Then if the SAG() values ranged from 0-255 instead of 0-100, this could replace what you had ...
va = v */ (255-sag[0]+1)It will save 75us each time, which brings the whole loop down to 220us. Just barely under the Timer1_INT period. But if you want to add more features, or increase the sin table, there won't be any time left.
<hr>
Going a bit further, here's a little asm routine that'll really help.

It Scales an 8-bit value to another 8-bit value.
Essentially it does Result=Value*(Scale+1), with the actual result being in the HighByte of the R2 variable.

With this you can do ...
; va = (v*(100-sag[0]))/100
R0 = V ; Put the value in R0
R1 = 255-SAG[0] ; Inverted SAG to R1
CALL Scale8 ; Scale R0*(R1+1)
VA = R2.HighByte ; result is in R2.HighByte


Here's the ASM part. Put it somewhere above the Main loop.
ASM ; ---- [Scale8 - Scale an 8-bit value]----------
; Input: R0 = Value to scale |
; R1 = Scale (0-255) |
; Output: R2 = R0*(R1+1) |
; Result is in R2.HighByte |
;---------------------------------------------------
goto OverScale8
_Scale8
clrf R2 ; result LowWord
clrf R2 + 1 ; result HighWord
movlw 8
movwf R3 ; Loop counter

movf R1, W ; Load Scale in W reg
bcf STATUS, C ; clear carry

Scale8Loop
rrf R0, F ; Rotate the Value, lsb goes to carry
btfsc STATUS, C ; if the carry = 1 then
addwf R2 + 1, F ; add Scale to result.highbyte
rrf R2 + 1, F ; rotate the result.highbyte, lsb goes to carry
rrf R2, F ; rotate carry into result.lowbyte
decfsz R3, F ; next loop
goto Scale8Loop

addwf R2, F ; add 1 more Scale
btfsc STATUS, C ; if carry
incf R2 + 1, F ; inc highbyte

return

;----[Macro to make things easier]------------------
Scale8 macro Value, Scale, Bout
MOVE?BB Value, R0
MOVE?BB Scale, R1
L?CALL _Scale8
MOVE?BB R2 + 1, Bout
endm

OverScale8
ENDASM ; ---- [End of Scale8]-----------------------


Using the above code, each call to Scale8 takes about 18us or 54us for all three. With 70us for the rest, it ends up doing the whole thing in about 125us. Well within the 230us periods. And time left over for a bigger/faster table.

I'm not using the macro at this point. It's just there for future reference.

Just remember ... SAG is 0-255 now. So if you need to convert it...
SAG(0) = SAG0value*255/100
Which is much like what you had in the beginning. But now it's only done when setting the SAG values, instead of 12000 times a second.

HTH,

sirvo
- 14th August 2008, 20:06
I'll try all of this as soon as possible... :)

Hey, Does 16LF777 work with @20Mhz? (LF)

In the datasheet DS30498C.pdf page 208, I see a graph showing that this Industrial model does not achieve the 20MHz frequency... Am I crazy?

skimask
- 14th August 2008, 20:20
I'll try all of this as soon as possible... :)

Hey, Does 16LF777 work with @20Mhz? (LF)

In the datasheet DS30498C.pdf page 208, I see a graph showing that this Industrial model does not achieve the 20MHz frequency... Am I crazy?

That's what it looks like to me. No updates on Microchip's site for the datasheet or the part itself. I'd be inclined to think that it would run at 20Mhz though. That graph and some parameters a few pages later in the datasheet seem to conflict a bit.

sirvo
- 5th November 2008, 15:40
Hello..

This is just a feedback of the tri-phase generator.
The video is not so good but you can get it...

It uses serial comm to make choices of the sinal generated.


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

I really appreciate the support!

Thanks!

Darrel Taylor
- 5th November 2008, 22:01
Oh Yeah!
Very nice. http://www.picbasic.co.uk/forum/images/icons/icon14.gif

Just curious ...
How many points did you end up with in the table, and what freq?
<br>

sirvo
- 6th November 2008, 14:07
Hello Darrel!

Well, I ended up with 72 points in the table...
It's been working really fine!

See ya!