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

    A last question : I've doubts about the duty cycle. What's the exact range of the duty cycle?

    If I define a duty cycle between 0-10, the simulator oscilloscope gives me weird things (the inverted signal "jumps")...
    If I define a duty cycle above 1023, same thing...

    The code used :
    Code:
        ' At 20MHz, to figure a PWM frequency of 19.455kHz
        ' TPWM = time period of PWM frequency
        ' PTPER = 12-bit period register PTPERL and PTPERH
        ' PTMRPS = PWM time base prescaler
        ' 
        '        (PTPER+1)*PTMRPS  257
        ' TPWM = ----------------  =  ------------ = 0.0000514 
        '             Fosc/4            5000000
        '
        ' Frequency = 1/TPWM = 1/0.0000514 = 19.455kHz
        '
        ' PWM resolution (bits resolution for duty cycle)
        '
        '              log(20MHz/19.455kHz)    3.01
        ' Resolution = ------------------ = ----------- = 10 bits
        '                    .301              .301
     
    'PIC initialization
    DEFINE LOADER_USED 1
    DEFINE OSC 40      
    
    'Port registers configuration
    PORTB = 0               ' Clear ports
    TRISB = %11000000       ' PWM 0,1,2,3,4,5 outputs
    TRISC = 2               ' RC1 = FLTA input (ground RC1 to halt PWM), pull-up resistor on RC1
                                
    'PCPWM registers configuration
    DTCON = %00001010       ' Deadtime (500ns)
    PTCON0 = %00000100      ' 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 = %01000000     'PWM 0,1,2,3,4,5 set in pair mode
    PWMCON1 = %00000001     'PWM timer sync configuration
    FLTCONFIG = %00000011   'Fault configuration
    
    'U, V and W duty variables
    uduty VAR WORD
    vduty VAR WORD
    wduty VAR WORD
    
    'Phases duty
    uduty = 1         
    vduty = 1000
    wduty = 1000
            
    pwmlp: ' PWM update loop
    
    'PWM U phase 
    PDC0L = uduty.LOWbyte
    PDC0H = Uduty.HIGHByte
    
    'PWM V phase
    PDC1L = vduty.LOWbyte
    PDC1H = vduty.HIGHByte
    
    'PWM W phase  
    PDC2L = wduty.LOWbyte
    PDC2H = wduty.HIGHByte
    
    goto pwmlp

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


    Did you find this post helpful? Yes | No

    Default Re: 6 HPWM signal generation with PIC18F4431

    Hi,
    The available resolution depends on the actual PWM frequency, you can see in the code how Bruce has calculated it for you. If you haven't changed the code the resolution is 10 bits (0-1023).

    The PCPWM module have a configurable dead-time generator which inserts a deadtime between turning off the upper switch and turning on the lower switch. When aproaching the "ends" of the available resolution this can distort the output waveform and I suspect that is what you're seeing.

    If you don't need deadtime you can turn it off. If you do need deadtime you should make sure that the dutycyle never aproaches the values where you're starting to see distortion. You usually can't use extreme dutycycles anyway due to the MOSFET/IGBT highside drivers need to refresh its bootstrap capacitor charge.

  3. #3


    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.

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


    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: 14056
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.

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

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


    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.

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

Members who have read this thread : 1

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