6 HPWM signal generation with PIC18F4431


Closed Thread
Results 1 to 23 of 23

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    Default Re: 6 HPWM signal generation with PIC18F4431

    Okay, the code is now capable to calculate 3 sine waves (one for each phase).

    I can modify the frequency (by increasing or decreasing freqdiv), but I've difficulties to set a phase angle (0-120-240° for U, V and W respectively) and I've difficulties to set a sinus amplitude (for exemple, if I want a 0-50% dutycycle, I will write uduty=uduty*0.5, but PBP does not support float maths).

    Thanks for your help. I use Darrel Taylor's interrupt system for sine-wave generation loop.

    Code:
    'PIC initialization
    DEFINE LOADER_USED 1
    DEFINE OSC 40      
    
    
    'DT interrupt system include
    INCLUDE "DT_INTS-18.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"  ' Include if using PBP interrupts
    
    
    'PWM calculation variables
    uduty VAR WORD     'U phase duty
    vduty VAR WORD     'V phase duty
    wduty VAR WORD     'W phase duty
    t VAR byte         'Incremental value
    
    
    'Inverter U/F variables
    freqdiv var WORD   'Frequency diviser
    FREQdiv=0          'Range : 0-65535
    
    
    'Port registers configuration
    PORTB=%0          ' Clear ports
    TRISB=%11000000   ' PWM 0,1,2,3,4,5 outputs
    
                                
    'PCPWM registers configuration
    DTCON=%110        ' Deadtime (600ns)
    PTCON0=%100       ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
    PTCON1=%10000000  ' PWM time base is ON, counts up, 19.45kHz/4
    PTPERL=%0         ' PWM low-side
    PTPERH=%1         ' PWM high-side
    
    	
    'PWM registers configuration
    PWMCON0=%1000000  'PWM 0,1,2,3,4,5 set in pair mode
    PWMCON1=%1        'PWM timer sync configuration
    
    
    'Interrupt processor
    ASM
    INT_LIST  macro    ; IntSource, Label, Type, ResetFlag
            INT_Handler   TMR1_INT,  _pwmint,   PBP,  yes
        endm
        INT_CREATE     ; Creates the interrupt processor
    ENDASM
    
    
    'Timer configuration
    T1CON=%10000001            ; Prescaler = 1:1, TMR1ON, 16-bit counter
    @ INT_ENABLE  TMR1_INT     ; Enable Timer 1 interrupts
    
    
    'Main loop
    mainlp:
    
        pause 1000
    
    goto mainlp
    
    'PWM calculation and update interrupt
    pwmint:
    t=0
        
        for T=0 to 255 step 1
    
        'Frequency diviser
        pauseus freqdiv
    
        'PWM U phase calculation
        uduty=((sin(t)+128)*4)  
          
        'PWM V phase calculation
        vduty=((sin(t)+128)*4)
        
        'PWM W phase calculation
        wduty=((sin(t)+128)*4)
    
        'PWM U phase update
        PDC0L=uduty.LOWbyte
        PDC0H=Uduty.HIGHByte
    
        'PWM V phase update
        PDC1L=vduty.LOWbyte
        PDC1H=vduty.HIGHByte
    
        'PWM W phase update
        PDC2L=wduty.LOWbyte
        PDC2H=wduty.HIGHByte
    
        next t
    
    @ INT_RETURN
    Last edited by pxidr84; - 19th February 2011 at 11:13.

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,627


    Did you find this post helpful? Yes | No

    Default Re: 6 HPWM signal generation with PIC18F4431

    Hi,
    How about:
    Code:
    'PWM U phase calculation
    uduty=((sin(t)+128)*4)  
          
    'PWM V phase calculation
    vduty=((sin(t+85)+128)*4)
        
     'PWM W phase calculation
    wduty=((sin(t+170)+128)*4
    Name:  3-phase sin.jpg
Views: 15292
Size:  76.0 KB

    It's true that you can't mutliply by 0.5 but you can divide by 2. You can also use the ** operator to multiply by units of 1/65536 so instead of doing x=y*0.72 you do x=y**47186 (where 47186 comes from 65536*0.72)

    /Henrik.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: 6 HPWM signal generation with PIC18F4431

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    How about:
    Code:
    'PWM U phase calculation
    uduty=((sin(t)+128)*4)  
          
    'PWM V phase calculation
    vduty=((sin(t+85)+128)*4)
        
     'PWM W phase calculation
    wduty=((sin(t+170)+128)*4
    Attachment 5180

    It's true that you can't mutliply by 0.5 but you can divide by 2. You can also use the ** operator to multiply by units of 1/65536 so instead of doing x=y*0.72 you do x=y**47186 (where 47186 comes from 65536*0.72)

    /Henrik.
    Thanks a lot for your tips
    Just a question : what simulator are you using ? (because my ISIS Proteus gives me very weird results):



    It's your code with angle phase offsets...
    Last edited by pxidr84; - 19th February 2011 at 13:02.

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,627


    Did you find this post helpful? Yes | No

    Default Re: 6 HPWM signal generation with PIC18F4431

    Hi,
    I'm not using a simulator, I just sent the values to the PC and plotted them with EXCEL. Here's the exact code I used to test with:
    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    DEFINE HSER_BAUD 19200
     
    i VAR BYTE
    T VAR BYTE
    uDuty VAR WORD
    vDuty VAR WORD
    wDuty VAR WORD
     
    Main:
    For i = 0 to 2   'Make three periods
      T=0
        
       for T=0 to 255
       ' PWM U phase calculation
       uduty=((sin(t)+128)*4)  
          
       ' PWM V phase calculation
       vduty=((sin(t+85)+128)*4)
        
       ' PWM W phase calculation
       wduty=((sin(t+170)+128)*4)
       
       HSEROUT [DEC uDUTY, ",", dec vDUTY, ",", dec wDUTY, 13]
      next
    NEXT
    WereDone:
    Goto WereDone
    Try removing C3, C6 and C8 to start with.

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: 6 HPWM signal generation with PIC18F4431

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    I'm not using a simulator, I just sent the values to the PC and plotted them with EXCEL. Here's the exact code I used to test with:
    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    DEFINE HSER_BAUD 19200
     
    i VAR BYTE
    T VAR BYTE
    uDuty VAR WORD
    vDuty VAR WORD
    wDuty VAR WORD
     
    Main:
    For i = 0 to 2   'Make three periods
      T=0
        
       for T=0 to 255
       ' PWM U phase calculation
       uduty=((sin(t)+128)*4)  
          
       ' PWM V phase calculation
       vduty=((sin(t+85)+128)*4)
        
       ' PWM W phase calculation
       wduty=((sin(t+170)+128)*4)
       
       HSEROUT [DEC uDUTY, ",", dec vDUTY, ",", dec wDUTY, 13]
      next
    NEXT
    WereDone:
    Goto WereDone
    Try removing C3, C6 and C8 to start with.
    In reality, I think that my RC filter in Proteus is bad.

    If I watch the raw PWM outputs, it seems perfectly good (with correct phase angles and duty cycles). However, in extreme duty (like 0 or 1023), the PWM "jumps" (like before, I think it's a sim issue, I will try the PIC in the real life with an oscilloscope).

    In other words, my code is working quite well now, thanks for the "**", I didn't know this operator before, until now.

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,627


    Did you find this post helpful? Yes | No

    Default Re: 6 HPWM signal generation with PIC18F4431

    Hi,
    Like I said in an earlier post, I think it is the dead-time insertion that makes the waveform "jump" at the extreme ends. Do try it with real hardware and let us know how it goes. Just remember that if you low-pass filter the PWM to watch it on a scope might not see any artifacts introduced by the deadtime insertion - if indeed that is what's causing it. So make sure you watch the "raw" PWM signals as well in order to see if it behaves as in the simulator.

    As a simple test, try removing the deadtime insertion from the code and see if it still looks strange in the simulator.

    /Henrik.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: 6 HPWM signal generation with PIC18F4431

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    Like I said in an earlier post, I think it is the dead-time insertion that makes the waveform "jump" at the extreme ends. Do try it with real hardware and let us know how it goes. Just remember that if you low-pass filter the PWM to watch it on a scope might not see any artifacts introduced by the deadtime insertion - if indeed that is what's causing it. So make sure you watch the "raw" PWM signals as well in order to see if it behaves as in the simulator.

    As a simple test, try removing the deadtime insertion from the code and see if it still looks strange in the simulator.

    /Henrik.
    Yes, of course I've readed your post above. I've modified the code (add +3 to the end of each line), now the PWM signal doesn't "jump" anymore.
    However, if I remove the deadtime or even modify it, the jumpy PWM remains.

    Now signals are better, but sine are not perfect for the highest frequencies, I think that my low-pass filter hasn't good R and C values (1k and 1000nF).


Members who have read this thread : 0

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