Generating 3-phase sine wave..


Closed Thread
Results 1 to 39 of 39
  1. #1
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108

    Smile Generating 3-phase sine wave..

    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!
    Sylvio,

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    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/show...light=inverter

  3. #3
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

    Default

    Hi Sylvio,

    (Somehow related).

    Speed Control of 3-Phase Induction Motor Using PIC18 Microcontrollers

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

    (Code and PDF).
    http://www.microchip.com/stellent/id...pnote=en012011

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

    Best regards,

    Luciano

  4. #4
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Smile

    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!
    Sylvio,

  5. #5
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    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!!!
    Sylvio,

  6. #6
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sirvo View Post
    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.

  7. #7
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    So, here we go..

    Didnt show var byte stuffs..

    Code:
    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,187,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,187,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,20,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,178,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,10,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,187,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,20,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,186,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,17,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
    Sylvio,

  8. #8
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    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.

  9. #9
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    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!
    Sylvio,

  10. #10
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sirvo View Post
    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?

  11. #11
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    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...
    Sylvio,

  12. #12
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    What does this do on PortD.0?
    Code:
    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.

  13. #13
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    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>
    DT

  14. #14
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    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...

  15. #15
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by skimask View Post
    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...

    Quote Originally Posted by Darrel Taylor View Post
    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 !
    Sylvio,

  16. #16
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sirvo View Post
    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.

  17. #17
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    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>
    DT

  18. #18
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by skimask View Post

    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!
    Sylvio,

  19. #19
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Maybe a difference or two (bug fix?) in an older version vs. newer version of the 'Instant Interrupts' related to the timers?

  20. #20
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    I've been using this one:
    Code:
    '****************************************************************
    '*  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?
    Sylvio,

  21. #21
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sirvo View Post
    '* 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.

  22. #22
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    .93 is the current version for the 14-bit pics.

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

  23. #23
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    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?
    Sylvio,

  24. #24
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sirvo View Post
    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.

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

  25. #25
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    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!
    Sylvio,

  26. #26
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sirvo View Post
    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.
    <br>
    DT

  27. #27
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    Ok...

    Code:
    
    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,187,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,187,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,20,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,178,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,10,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,187,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,20,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,186,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,17,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
    Sylvio,

  28. #28
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Ah ha, there's the missing info.

    With the lines ...
    Code:
    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>
    DT

  29. #29
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    "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?
    Code:
     va = (v*(100-sag[0]))/100
    Why would it be happening? 125us just to make 1 subtract, 1 mult and 1 div?

    Thanks Darrel!
    Last edited by sirvo; - 9th August 2008 at 01:40.
    Sylvio,

  30. #30
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Yup, multiplication and division takes a LOT of loops to do.

    In this 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>
    DT

  31. #31
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    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...

  32. #32
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by skimask View Post
    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>
    DT

  33. #33
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    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!
    Sylvio,

  34. #34
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    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 ...
    Code:
            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 ...
    Code:
    ;        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.
    Code:
    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...
    Code:
    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,
    DT

  35. #35
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Question

    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?
    Sylvio,

  36. #36
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sirvo View Post
    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.

  37. #37
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Smile

    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.



    I really appreciate the support!

    Thanks!
    Last edited by ScaleRobotics; - 15th February 2011 at 09:39. Reason: embeded video
    Sylvio,

  38. #38
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Oh Yeah!
    Very nice.

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

  39. #39
    Join Date
    Jan 2007
    Location
    Brazil
    Posts
    108


    Did you find this post helpful? Yes | No

    Default

    Hello Darrel!

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

    See ya!
    Sylvio,

Similar Threads

  1. To Generate Sine Wave Using PCPWM of PIC18F4331 (Issue)
    By Cyborg in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 22nd March 2014, 13:39
  2. Sine wave
    By Darrenmac in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 18th May 2009, 03:31
  3. 3 phase supply detector challenge
    By BobEdge in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 15th May 2009, 07:54
  4. 3 phase PWM with dsPIC30F2020
    By nemmard in forum mel PIC BASIC
    Replies: 1
    Last Post: - 21st January 2009, 14:19
  5. 3 phase sequencing
    By ardhuru in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 26th May 2007, 07:35

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts