sinusoidal PWM - Page 2


Closed Thread
Page 2 of 3 FirstFirst 123 LastLast
Results 41 to 80 of 84

Thread: sinusoidal PWM

  1. #41
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi Henrik! As always, great post!
    I've done some work with DT_INTS, and in ASM mode, they are fairly fast, as they only copy a few registers, vs the PBP type, which copies then restores about 70 registers with each interrupt. So I don't understand your warning about going above 4 Mhz? I've run it at 40 Mhz on a different chip and it worked pretty well using ASM type DT_INTS.

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


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,
    I missed the fact that the interrupt was declared as ASM. In that case, as you say, there's not that much overhead but it's also risky business since the actual handler IS written in PBP - if you don't know what you're doing here you're likely to run into trouble.

    And, with the above in mind, perhaps adding the "extra" reload code for accuracy isn't a good idea (and not needed since there's much less overhead) since it might use some PBP system variables and then the whole thing is a mess.

    I wasn't trying to say that it couldn't run at a higher oscillator speed than 4Mhz. I was trying to say that I don't think it'll be able to interrupt much faster when running AT 4Mhz, in fact that IS what I said ;-) But that was before you enlightned me of the fact that he has the ISR declared as ASM.

    bwaxing,
    You do realise the difference of declaring the interrupt as type ASM as oppesed to type PBP and what impact it might have on your code if you declare it as ASM but write the handler in PBP?

    /Henrik.

  3. #43
    Join Date
    Feb 2011
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    Several things.....
    TMR2 is the timer used for the PWM generation. The fact that you initially load it with 117 doesn't matter for either the PWM frequency or your interrupt frequency since you're using TMR1 to generate the interrupts.

    You have the prescaler for TMR2 set to 1:4 and PR2 set to 13 which indeed gives you ~18kHz PWM frequency but it'll only give you a give you 56 discrete dutycycles. Ie. the maximum value you can put in the dutycycle register is 56. The highest value in your sine table is 242 which you then shift right one time bofore putting in the CCP1L, so you're trying to put 121 in there when 56 is max.

    Changing the prescaler to 1:1 and putting 55 in PR2 gives you the same PWM frequency but allows dutycycle values of 0-222.

    TMR1 is now setup with a prescaler of 1:1 and you reload it with 64980 making it interrupt every 65536-64980=556us or at a frequency of 1798Hz, there's now 36 steps to your "cycle" so 1798/36=49.96Hz so it seems to be correct. I don't think you should expect to be able to run much faster than that at 4Mhz, the DT-ints takes quite afew cycles to save and restore all the system variables on each interrupt so you won't have much time left.

    The "accuracy thing" needs to be performed on each reload or it won't have much effect. It should be in your ISR instead of the reload code you have there now.

    /Henrik.
    i've the changes in the code as you suggested above,but the waveform is still not smooth....Simulation results..pdf

    Code:
    define OSC 4
    
    ;*****************VARIABLE DECLARATION******************************************
    wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
    wsave1  VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
    wsave2  VAR BYTE    $120    SYSTEM      ' location for W if in bank2
    wsave3  VAR BYTE    $1A0    SYSTEM      ' location for W if in bank3
    STEPCOUNT var byte                      'Define stepcount as byte type variable
    stepcount = 36
    
    ;**************SETTING THE REGISTERS WITH APPROPIATE BIT DEFINITION************* 
    ADCON0 = %00000000
    ADCON1 = %00000000  ;all anolog output
    trisb = %11111111   ;define porta as input
    trisc = %11111011   ;make ccp1/portc.2 an output pin
    trisa = %11111111   ;define porta as input
    TMR2 = 117
    PR2 = 55          ;set for 18Khz HPWM(=36 steps*10 times*50hz)        
    CCP1CON = %000001100       ;set to pwm mode
    T2CON=%00000100           ;enable timer2 and set timer2 prescaler value of 1:1
    
    ;****************A sine lookup table in an array********************************
    sineval var byte[36]
    sineval[0] = 128
    sineval[1] = 148
    sineval[2] = 167
    sineval[3] = 185
    sineval[4] = 201
    sineval[5] = 215
    sineval[6] = 227
    sineval[7] = 235
    sineval[8] = 240
    sineval[9] = 242
    sineval[10] = 240
    sineval[11] = 235
    sineval[12] = 227
    sineval[13] = 215
    sineval[14] = 201
    sineval[15] = 185
    sineval[16] = 167
    sineval[17] = 148
    sineval[18] = 128
    sineval[19] = 108
    sineval[20] = 89
    sineval[21] = 71
    sineval[22] = 55
    sineval[23] = 41
    sineval[24] = 29
    sineval[25] = 21
    sineval[26] = 16
    sineval[27] = 14
    sineval[28] = 16
    sineval[29] = 21
    sineval[30] = 29
    sineval[31] = 41
    sineval[32] = 55
    sineval[33] = 71
    sineval[34] = 89
    sineval[35] = 108
     
    timerone var word 
    TimerShadow VAR WORD 
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System
    
    ;********Define INT_Handler as ISR********************************************** 
    ASM 
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _sine,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    T1CON = %000001    ; Prescaler = 1, TMR1ON          
    TMR1L = 255    
    TMR1H = 254
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts  
    timerone = 64980           ;gives about 50 hz sine 
    Main:
            pause 5
            
    GOTO Main
     
    '---[TMR1_INT - interrupt handler]------------------------------------------
    
    
    sine:
    'accuracy thing
    T1CON.0 = 0  'Stop TMR1
    TimerShadow.HighByte = TMR1H
    TimerShadow.LowByte = TMR1L
    TimerShadow = TimerShadow + Timerone
    TMR1H = TimerShadow.HighByte
    TMR1L = TimerShadow.LowByte
    T1CON.0 = 1  'Restart TMR1
    
        TMR1L = timerone.byte0
        TMR1H = timerone.byte1     
        CCPR1L = sineval[STEPCOUNT]>>1 
        stepcount = stepcount -1
        if stepcount = 0 then stepcount = 36
    
    @    INT_RETURN

  4. #44
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    One small thing I notice is that your:

    Code:
        TMR1L = timerone.byte0
        TMR1H = timerone.byte1     
        CCPR1L = sineval[STEPCOUNT]>>1 
        stepcount = stepcount -1
        if stepcount = 0 then stepcount = 36
    will read the value of stepcount 36 (doesn't exist), and never get to read stepcount 0.

    I don't think this is the dramatic fix you are looking for, but maybe it's one small step forward.

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

  5. #45
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,
    You still don't have the reload thing correct. The way you currently have it you are first reloading the timer with the calculated value (for accuracy) then you reload it again with the default value overwriting the "correct", calculated value. However, since the overhead is much less then I initially thought you might not need this "accuracy thing". And because it might also mess up the interrupt system due the ASM/PBP type interrupt I suggest you remove it and go back to the way you had it intitially. It's also not the cause of the distroted waveform.

    Something that's more likely the cause of that is the fact that you load the dutycycle value into the top 8 bits of the dutycycle register when you really should load it to the low 8 bits. CCP1L are the 8 high bits and CCP1CON.5 and CCP1CON.4 are the two least significant bits. You are currently putting the (highest) value 121 into CCP1L which, in reallity, looks as 484 to the PWM module. But with the current PWM frequency the PWM module can't "resolve" to that kind of resolution.

    As a test, scale down you'r sinetable so that the highest value is around 200. Then use this in the interrupt:
    Code:
    Temp = SineVal[StepCount]   'Don't forget to declare Temp as BYTE.
    CCP1CON.4 = Temp.0   'Bit 0
    CCP1CON.5 = Temp.1   'Bit 1
    CCP1L = Temp >> 2     'Bit 2-7
    /Henrik.

    PS. Please don't quote the previous message all the time. There's no need to have a copy of it right after the original. If you're responding to specific questions or comment in the message quote those line only.

  6. #46
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    I have made a little house keeping on the thead and deleted all the un-necessary quotes and left only the necessary. The replies were following the answers so it it was really obvious.

    As Henrik stated quote only when absolute necessary. It makes reading the thread more comfortable and easy to follow. Saves resources too!

    Ioannis

  7. #47
    Join Date
    Feb 2011
    Posts
    37


    Did you find this post helpful? Yes | No

    Smile Re: sinusoidal PWM

    hellow,

    thanx for the useful comments and suggestions,i learn a lot from them...

    Henrik and Scalerobotics,
    i've changed the code and include this Code:

    Code:
    Temp = SineVal[StepCount]    
    CCP1CON.4 = Temp.0   'Bit 0
    CCP1CON.5 = Temp.1   'Bit 1 
    CCPR1L = Temp  >> 2     'Bit 2-7
    and i'm getting a smooth signal for 20Mhz Osc but not for 4MHz,tried to scale the sine table but it didnt work...but for 20Mhz Osc things looks fine...Simulation results..pdf
    i'm not sure if it is possible to get a smooth spwm signal with a 4Mhz osc as i've tried to modified my code as suggested above but the waveform is still not smooth.....

  8. #48
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Not sure, but you might try the code on real hardware with a scope and see how it looks. I have noticed that simulations of this type don't work out too well. General wave form maybe, but I wouldn't trust it much more than that for this application. Looks like good improvement though!
    Last edited by ScaleRobotics; - 9th May 2011 at 16:14.

  9. #49
    Join Date
    Feb 2011
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    hi,
    i've noted that my code produce inverted sine waveform and it is not the one i intend to produce,here is my complete code:
    Code:
    define OSC 20
    
    ;*****************VARIABLE DECLARATION******************************************
    wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
    wsave1  VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
    wsave2  VAR BYTE    $120    SYSTEM      ' location for W if in bank2
    wsave3  VAR BYTE    $1A0    SYSTEM      ' location for W if in bank3
    STEPCOUNT var byte                      'Define stepcount as byte type variable
    stepcount = 0
    
    ;**************SETTING THE REGISTERS WITH APPROPIATE BIT DEFINITION************* 
    ADCON0 = %00000000
    ADCON1 = %00000000  ;all anolog output
    trisb = %11111111   ;define porta as input
    trisc = %11111011   ;make ccp1/portc.2 an output pin
    trisa = %11111111   ;define porta as input
    TMR2 = 16
    PR2 = 78          ;set for 16Khz HPWM(=32 steps*10 times*50hz)        
    CCP1CON = %000001100       ;set to pwm mode
    T2CON=%00000100           ;enable timer2 and set timer2 prescaler value of 1:1
    
    ;****************A sine lookup table in an array********************************
    sineval var byte[32]
    sineval[0] = 148
    sineval[1] = 167
    sineval[2] = 185
    sineval[3] = 200
    sineval[4] = 210
    sineval[5] = 222
    sineval[6] = 228
    sineval[7] = 230
    sineval[8] = 228
    sineval[9] = 222
    sineval[10] = 212
    sineval[11] = 200
    sineval[12] = 185
    sineval[13] = 167
    sineval[14] = 148
    sineval[15] = 128
    sineval[16] = 108
    sineval[17] = 89
    sineval[18] = 71
    sineval[19] = 56
    sineval[20] = 43
    sineval[21] = 34
    sineval[22] = 28
    sineval[23] = 26
    sineval[24] = 28
    sineval[25] = 34
    sineval[26] = 43
    sineval[27] = 56
    sineval[28] = 71
    sineval[29] = 89
    sineval[30] = 108
    sineval[31] = 128
    
     
    timerone var word 
    Temp VAR byte 
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System
    
    ;********Define INT_Handler as ISR********************************************** 
    ASM           
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _sine,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    T1CON = %000001    ; Prescaler = 1, TMR1ON          
    TMR1L = 255    
    TMR1H = 254
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts  
    timerone = 62411           ;gives about 50 hz sine 
    Main:
            pause 5
            
    GOTO Main
     
    '---[TMR1_INT - interrupt handler]------------------------------------------
    
    
    sine:
        TMR1L = timerone.byte0
        TMR1H = timerone.byte1
        Temp = SineVal[StepCount]   
        CCP1CON.4 = Temp.0   'Bit 0
        CCP1CON.5 = Temp.1   'Bit 
        CCPR1L = Temp >> 2     'Bit 2-7
        stepcount = stepcount +1
        if stepcount = 32 then stepcount = 0    
    @    INT_RETURN
    any idea on how to invert the wave form...?thanx in advance

  10. #50
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Previously you started at the "end" of table and decremented the "pointer" but now you've apparently changed that so it starts at 0 and increments the pointer instead.

    If you want it phase shifted 180° ("inverted") then simply "reverse" your sin-table. 128, 108, 89, 71.... instead of 148, 167, 185....

  11. #51
    Join Date
    Feb 2011
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    hellow,

    i've managed to generate SPWM signal using 4MHz xtal ,thanx to Henrik for the tip of modifying the lookup table values,this is the screen shoot taken from the actual scope.....Name:  0000.JPG
Views: 2405
Size:  143.3 KB

    however,there are things i'm not happy with this signal...
    1)i expected to see at least one complete cycle on the screen for a single screen shoot,but this is not the case,it is either positive or negative cycle!what should i do?

    2)in theory,SPWM signal is obtained by comparing the triangular wave having a certain switching frequency with a sine wave of certain modulating frequency (50Hz for my case),now the HPWM frequency is 18KHz,is this the switching frequency?if not how do i know the switching frequency for this kind of generation?i want a switching frequency around 2KHz. i want to use this signal to control a single phase inverter.

    here is my code:
    Code:
    define OSC 4
    
    ;*****************VARIABLE DECLARATION******************************************
    wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
    wsave1  VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
    wsave2  VAR BYTE    $120    SYSTEM      ' location for W if in bank2
    wsave3  VAR BYTE    $1A0    SYSTEM      ' location for W if in bank3
    STEPCOUNT var byte                      'Define stepcount as byte type variable
    stepcount = 36
    
    ;**************SETTING THE REGISTERS WITH APPROPIATE BIT DEFINITION************* 
    ADCON0 = %00000000
    ADCON1 = %00000000  ;all anolog output
    trisb = %11111111   ;define porta as input
    trisc = %11111011   ;make ccp1/portc.2 an output pin
    trisa = %11111111   ;define porta as input
    TMR2 = 117
    PR2 = 55          ;set for 18Khz HPWM(=36 steps*10 times*50hz)        
    CCP1CON = %000001100       ;set to pwm mode
    T2CON=%00000100           ;enable timer2 and set timer2 prescaler value of 1:1
    
    ;****************A sine lookup table in an array********************************
    sineval var byte[36]
    sineval[0] = 115
    sineval[1] = 102
    sineval[2] = 90
    sineval[3] = 79
    sineval[4] = 70
    sineval[5] = 62
    sineval[6] = 57
    sineval[7] = 53
    sineval[8] = 52
    sineval[9] = 53
    sineval[10] = 57
    sineval[11] = 62
    sineval[12] = 70
    sineval[13] = 74
    sineval[14] = 90
    sineval[15] = 102
    sineval[16] = 115
    sineval[17] = 128
    sineval[18] = 141
    sineval[19] = 154
    sineval[20] = 166
    sineval[21] = 177
    sineval[22] = 186
    sineval[23] = 194
    sineval[24] = 199
    sineval[25] = 203
    sineval[26] = 204
    sineval[27] = 203
    sineval[28] = 199
    sineval[29] = 194
    sineval[30] = 186
    sineval[31] = 177
    sineval[32] = 166
    sineval[33] = 154
    sineval[34] = 141
    sineval[35] = 128
     
    timerone var word 
    Temp VAR byte 
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System
    
    ;********Define INT_Handler as ISR********************************************** 
    ASM 
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   _sine,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    T1CON = %000001    ; Prescaler = 1, TMR1ON          
    TMR1L = 255    
    TMR1H = 254
    @   INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts  
    timerone = 64980          ;gives about 50 hz sine 
    Main:
            pause 5
            
    GOTO Main
     
    '---[TMR1_INT - interrupt handler]------------------------------------------
    
    
    sine:
        TMR1L = timerone.byte0
        TMR1H = timerone.byte1     
        Temp = SineVal[StepCount]   
        CCP1CON.4 = Temp.0   'Bit 0
        CCP1CON.5 = Temp.1   'Bit 1
        CCPR1L = Temp >> 2     'Bit 2-7
        if stepcount = 0 then stepcount = 36 
        stepcount = stepcount -1
       
    
    @    INT_RETURN

  12. #52
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,
    1)i expected to see at least one complete cycle on the screen for a single screen shoot,but this is not the case,it is either positive or negative cycle!what should i do?
    I haven't checked your code but going by the comments you expect a 50Hz "sinewave", a full period at 50Hz is 20ms but your scope is set to 200us/div, there's 10 divisions so you're only displaying 2ms on the screen. I see a 10:1 note there but does that apply to the horizontal sweep?

    I don't understand the part with the triangular wave being compared with a sine etc but the switching frewuency IS the PWM frequency, or 18kHz in this case. If you want 2kHz you need to reconfigure the PWM module to output 2kHz which might also require adjusting the sine-table depending on how the numbers play out.

  13. #53
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    I see you help bwax to susscced his project, can you help me an idea of how to create sinelookuptable thankx

  14. #54
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    That has been discussed in this very thread... Easiest is probably to use a spreadsheet program like Excel.

  15. #55
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Thankx HenrikOlsson but I 'm still have I problem which formular should I use to get the value ,cause I want to generate three phase SPWM

  16. #56
    Join Date
    Jan 2006
    Location
    New Hampshire, USA
    Posts
    107


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Check into Don Lancaster's Magic Sinewaves here: http://www.tinaja.com/
    I did it with a basic stamp BS1 several years ago when I was a newby, it is quite simple and works great.

  17. #57
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,
    Attached is an Excel spreadsheet showing an examle of a 72 steps/cycle SIN table with an 8bit dutycycle. You can modify it for any number of steps and resolution you see fit or you may want to create one half cycle and then have your code invert it for the second half and so on - it's up to you.

    To get three phases there's no need to have three tables, you use three pointers 120° appart indexing the same table. So, with the table in the attached .xls you start at steps 0, 24 and 48 respectively.

    /Henrik.

    EDIT: Crap, can't attach the .xls here. Send me a PM with your email adress and I'll send it to you.

  18. #58
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    EDIT: Crap, can't attach the .xls here. Send me a PM with your email adress and I'll send it to you.
    Add ".txt" to the extension...
    Dave
    Always wear safety glasses while programming.

  19. #59
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Ahh, OK, should've thought about that.
    So, here it is - remove the .txt extenstion and open with Excel or compatible.

    /Henrik.
    Attached Files Attached Files

  20. #60
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: Lab X1 and 16F877 examples for beginners

    Hi ! demon
    I want to generator 3 Phase spwm signal for my final year project but I, m started by understanding single phase SPWM by reading the example from
    Microchip appliction notes for sine wave with the 16F series chip..http://ww1.microchip.com/downloads/e...tes/00655a.pdf together with the examples given in http://www.picbasic.co.uk/forum/cont...wave-using-DT- interrupts and http://www.picbasic.co.uk/forum/showthread.php?t=14359.

    there are number of things which i've not understand from these readings and i'm asking for help from anyone who can help me to understand.these things are:
    1)which formular used to generate a lookup table for the sine waveforms
    3)what is the purpose of this piece of code and how to get this values from example of http://www.picbasic.co.uk/forum/cont...-DT-interru and
    TMR2 = 117
    PR2 = 63

    TMR1L = 255
    TMR1H = 254

  21. #61
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Thankx again HenrikOlsson here are some things which I dont understand I ask for the help from any one
    (1) ask for the help again which formula should I use to generate this sine look up table I need some detail on it thankx.

    (2) and how this portion of code work , what is function, and how to get values of TMR1L AND TMR1H
    ASM

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

    T1CON = 000001 ; Prescaler = 8, TMR1ON
    TMR1L = 255
    TMR1H = 254
    @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts

  22. #62
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Quote Originally Posted by HenrikOlsson View Post
    Ahh, OK, should've thought about that.
    So, here it is - remove the .txt extenstion and open with Excel or compatible.

    /Henrik.
    thankx HenrikOlsson when I download your Excel fileI didn't able to open it please can you help me how to take it so I can open it. thankx

  23. #63
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hello sangaboy,
    1) Download the file then rename it SIN-table.xls (or whatever ending with .xls) then open it with EXCEL 2003 - or compatible software. I just tried that here and it works fine. If you don't have Excel 2003 perhaps you can find a free viewer or converter online.

    2) The first code snippet you posted is a setup section of DT-Ints which are a set of files making interrupts with PBP a whole lot easier. The second code snippet sets up TMR1 to operate in a specific way and then preloads it with 65534 (which seems a bit strange) but that's what you get when you just copy code. You really need to start a bit further back here. Before taking on a project a like a 3-phase inverter you need to understand the basics of PIC and PBP - at least. How the timers work, how interrupts work and so on.


    Read up on the DT-Ints routines, there are several threads on this forum. Read up on how TMR1 operates, there's a lot of info in the datasheet and a bit of searching here will give a lot, I mean a LOT, of usefull information and examples. Start small otherwise you'll never learn how it works.

    If you get stuck ask specific questions regarding the particular task at hand and tell us what the actual problem is and what you've tried, post the code and so on.

    I really don't want to sound like a smart-ass but if you can't figure out the formula to create a SIN-lookup table then designing and programming a 3-phase inverter drive is going to quite a challange.

  24. #64
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hii! to all
    I read DT-Ints routines from ttp://darreltaylor.com/DT_INTS-14/order.html here are some problems I faced any one can help me.
    (1)the difference between PBP AND ASM interrupt handler is not clear to me.
    (2) what the effects of ResetFlag on this code definition.

    INT_LIST macro ; IntSource, Label, Type, ResetFlag?

    Thankx

  25. #65
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,

    1) Internally PBP works with a bunch of system variables in RAM. These are used to store intermediate results when doinf calculations and comparisons, loop counters etc etc. When you define the type of handler as PBP in the interrupt declaration DT-Ints saves all the PBP system variables on entry of the interrupt service routine and restores them on exit. This allows the code the in interrupt handler to be written in PBP just like any normal PBP program and execute without destroying the content of the system variables for the code that was executing when the intterupt occurs. When the execution returns from the interrupt handler the system variables looks exactly as they did when the interrupt occured and the "normal" program can continue to execute.

    If you define the type of handler as ASM DT-Ints does not save and restore the PBP system variables. This means that if you have code in the interrupt handler which happens to use any system variables it's very likely that you'll run into trouble. So, type PBP write the handler in PBP. Type ASM, write the handler in ASM.

    The difference is that it takes time for the system to save and restor all the PBP system variables (and the take up space i RAM). No you should not declare the type as ASM and still write the handler in PBP if you don't konw and understand exactly what's happening and what system variables your code uses.


    2) When an interrupt occurs the hardware in the PIC sets the interrupt flag for the particular interrupt. The ResetFlag option tells the interrupt system if IT should reset the flag after it's handled the interrupt or if it should leave it alone. Generally you set this to YES but for USART interrupt, for example, the flag is automatically cleared by the hardware when the RCReg is read so there's no need for the code to clear it as well.

  26. #66
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Thankx HenrikOlsson
    for your help .

  27. #67
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi HenrikOlsson
    I now I understand to gerate sine lookup table using excel sheet , thi is after working on the sheet you upload to me, The sheet contain the formular
    (SIN(Ai*PI()/180)+1)/2 from what I know the portion (Ai*PI())/180)change degrees into radians. but there to thing I need to understand so that I can generate my 32 steps sine look up table for 3 SPWM.
    (1) why (sine results+1)
    (2) why (sine results+1) is diveded by the factor of 2
    (3) why the (sine results+1)/2 are multiplied by 255 to get the scale value.

    THANKX

  28. #68
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,
    Yes, convert from degrees which is the number in column A to radians which is what Excel wants.

    1) The SIN of an angle of 0-360° varies from -1 to +1 since we're going to use the values to set a PWM dutycycle we can't have negative numbers, we can't have a dutycycle of LESS than 0. So we add 1 to get a value ranging from 0 to 2 instead of +/-1.

    2) Then we divide that by 2 to get the value ranging from 0 to 1 to make the next step more logical...

    3) Again, since we're going to use the final value to set the dutycycle produced by the PWM generator we can't have the value ranging from 0 to 1, we need to scale the value up to match the number of bits of resolution we have in the PWM generator. If it's 8 bits multiply by 255 to get a value ranging from 0 to 255 (0 is 0% dutycycle, 255 is 100% dutycycle). If you have 9 bits resolution multiply by 512 and so on.

    /Henrik.

  29. #69
    Join Date
    Feb 2005
    Location
    Kolkata-India
    Posts
    563


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,
    The Standard Hardware PWM modules on the PICs are generally 10 bits CCPRxL (8 bits) plus the 2 LSBs being in the CCPxCON<5:4>. How many bits you can obtain from the PWM module is dependent on the frequency. Sometimes updating the registers could be a bit troublesome and not within a single instruction cycle. What I do personally is select a 10 bit resolution and use only the higher 8 bits. A straight loading of the CCPRxL does the job with the benefit of not hitting 100% duty cycle which is required for the bootstrap gate drivers.
    For the PICs with the PowerControl PWM module (sometimes also referred to as a motor control PWM) you can get upto 14 bits of resolution with a dedicated register pairs. And generally they at least have 3 PWM units with complementary outputs / dead time / Fault Input which simplifies the design and control of 3 phase systems greatly.

    My choices are the PIC18F1330 and PIC18F4431(has 4 channel sequential sampling capability like the 16bit PIC24/dsPICs).
    Regards

    Sougata

  30. #70
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi !

    Thankx sougata and HenrikOlsson for your helpwhich take me into good stages

    there some challenges have any one can help me
    (1) My PIC is16cF877 having CCP1 and CCP2 can it able to generate three phase SPWM?. for my little knowledge I know that for single phase the duty cycle is stored into CCP1 to generate SPWM. for three phase should I have a pic of three CCP modules?.

    (2) how can I improves these my small number of steps(10) cause I read page 63/281 of PIC 16F87X data sheet and microchip application note AN655 page 1/16 I saw the formular for resolution and number of steps respectively.

    The maximum PWM resolution (bits) for a given PWM frequensy is given by the formular below


    Resolution = log(FOSC/FWPM)/log(2) bits

    I want to set my PWM frequency = 5kHZ
    my FOSC = 4MHZ
    which gives resolution of 10 it's ok and scale factor of 1023

    but
    from microchip application note AN655
    PWM_Freq = (Sine_freq) • (# of steps) • 10

    my sine frequency is 50Hz
    PWM_Freq =5kHZ

    gives me 10 steps which I think is very small to give clear SPWM.

    thankx

  31. #71
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi !

    Thankx sougata and HenrikOlsson for your helpwhich take me into good stages

    there some challenges I have any one can help me:

    (1) My PIC is16cF877 have CCP1 and CCP2 can it able to generate three phase SPWM?. for my little knowledge I know that for single phase the duty cycle is stored into CCP1 to generate SPWM. for three phase should I have a pic with three CCP modules?.

    (2) how can I improves these small number of steps(10) cause I read page 63/281 of PIC 16F87X data sheet and microchip application note AN655 page 1/16 I .http://ww1.microchip.com/downloads/e...tes/00655a.pdf I read the formular for bits resolution and number of steps respectively.

    The maximum PWM resolution (bits) for a given PWM frequensy is given by the formular below


    Resolution = log(FOSC/FWPM)/log(2) bits

    I want to set my PWM frequency = 5kHZ
    my FOSC = 4MHZ
    which gives resolution of 10 it's ok and scale factor of 1023

    but
    from microchip application note AN655
    PWM_Freq = (Sine_freq) • (# of steps) • 10

    my sine frequency is 50Hz
    PWM_Freq =5kHZ

    gives me 10 steps which I think is very small to give clear SPWM .

    thankx

  32. #72
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,
    What exactly do you mean with SPWM? What does the S mean?

    If you're generating the PWM signal with CCP-module you'll need 3 CCP-modules to generate three individual PWM signals. As have already been suggested ditch the '877 and take a look at the 18F2431/4431 which is designed for motor control providing deadtime control and dedicated hardware fault inputs to disable the PWM signals - and more.

    If you need to stick to a 16 series PIC then use the parametric search tool at Microchips website to look up a PIC with three CCP-modules, perhaps the 16F777.

    I just looked briefly at the app-note you reference and they seem to be using a low-pass filter to get a "true" sine-wave output, to do that they calculated/estimated that at least 10PWM cycles is needed to bring the output voltage to the desired value.

    How many "steps" do you want, per period? Let's say you have a lookup table of 32 'steps'. Ie it takes 32 "updates" to create one full cycle of the sinewave, so at 50Hz you need to change the PWM dutycycle 50*32=1600 times per second, which means that you'll get atleast three full PWM cycles for each "step" with a 5kHz PWM frequency, I think that'll work.

    /Henrik.

  33. #73
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi !


    SPWM stands for Sinusoidal Pulse With Modulation.These signals will be used to control Three phase inverter.

    thankx

  34. #74
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    I'm afraid the letter sequence SPWM actually was derived by Darrel for his contribution of Software Pulse Width Modulation.
    Dave Purola,
    N8NTA
    EN82fn

  35. #75
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    That's what I thought but figured it couldn't be since we're talking about CCP-modules etc. Doesn't matter, now I know what the OP means although I've never heard the term before.

    /Henrik.

  36. #76
    Join Date
    Apr 2007
    Location
    Pennsylvania, USA
    Posts
    158


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Perhaps this thread will be of use to you.

    http://www.picbasic.co.uk/forum/showthread.php?t=1846
    Shawn

  37. #77
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi
    I download the pic16f777 datasheet from microchip website I go through it I found it does not much differ from that of pic16f7877 so it easy for me to shift from the PIC16877 to 16F777 which has three ccp modules for SPWM generation.

    thanx

    Sorry for delay in reply, now I 'm in seventh semister exam of my BSc in electrical eng.
    Last edited by sangaboy; - 27th January 2012 at 08:07. Reason: word correction

  38. #78
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    hi to all
    I try to simulator my code on IMPLAB simulator but I have not yet sussceed til now so I decide to simulator with pic 16F877 which is found in ISIS but when it comes to real environment(actual implementation) I 'm going to use pic16f777 , which I 'm waiting for it to come.

    Then
    can any one help me !
    how to take my waveform from digital oscilloscope in ISIS cauz I want to uploaad in this forum ,I try to print but the file does not contain any waveform. I have some problem on my ouputs.
    thankx.

  39. #79
    Join Date
    Oct 2011
    Posts
    52


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi!

    I manage to compile and modify the example from that link www.picbasic.co.uk/forum/cont...-DT-interrupts, for pic 16877. Because the pic I want to use for three phase spwm signal is (16f777) which has 3 CCP module and I' m waiting for it to come the problem it is not includeded in ISIS simulator that is why I used pic 168777 having 2 CCP module for simulation and is present in ISIS and my college lab. I belive if I manage to generate two phase spwm it became eaasy for 3 phase spmw.

    here is the code and attachement of my output from ISIS and mysinelooktable and
    define OSC 4

    STEPCOUNT var byte
    STEPCOUNT1 var byte
    STEPCOUNT = 0 'pointer for phase one in sinearray
    STEPCOUNT1 = 0 'pointer for phase two in sine array
    ADCON0 = %00000000
    ADCON1 = %00000000

    TRISB = %11111111
    TRISC = %11111001 'PMW output for CCP1 AND CCP2
    TRISA = %11111111
    TMR2 = 117
    PR2 = 55 'set for 18Khz HPWM
    CCP1CON = %00001100 'set CCP1 for PWM OPERATION
    CCP2CON = %00001100 'set CCP2 for PWM OPERATION
    T2CON = %00000100 'TIMER2ON and prescale of 1:1

    sineval var byte[36]
    sineval[0] = 128
    sineval[1] = 150
    sineval[2] = 171
    sineval[3] = 191
    sineval[4] = 209
    sineval[5] = 225
    sineval[6] = 238
    sineval[7] = 247
    sineval[8] = 253
    sineval[9] = 255
    sineval[10] = 253
    sineval[11] = 247
    sineval[12] = 238
    sineval[13] = 225
    sineval[14] = 209
    sineval[15] = 191
    sineval[16] = 171
    sineval[17] = 150
    sineval[18] = 128
    sineval[19] = 105
    sineval[20] = 84
    sineval[21] = 64
    sineval[22] = 46
    sineval[23] = 30
    sineval[24] = 17
    sineval[25] = 8
    sineval[26] = 2
    sineval[27] = 0
    sineval[28] = 2
    sineval[29] = 8
    sineval[30] = 17
    sineval[31] = 30
    sineval[32] = 46
    sineval[33] = 64
    sineval[34] = 84
    sineval[35] = 105

    timerone var word
    Temp var byte
    Temp1 var byte

    INCLUDE "DT_INTS-14.bas" ; Base Interrupt System emp


    ASM

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

    T1CON = 000001 ; Prescaler = 1;1, TMR1 ON
    TMR1L = 255
    TMR1H = 254
    @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts

    timerone = 64980 ;gives about 50 htz sine
    Main:
    PAUSE 5

    GOTO Main

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

    sine:
    TMR1L = timerone.byte0
    TMR1H = timerone.byte1

    TeMP = sineval[STEPCOUNT]
    CCP1CON.4 = Temp.0 ' bit 0
    CCP1CON.5 = Temp.1 ' bit 1
    CCPR1L = Temp >>2 'Bit 2-7

    TeMP1 = sineval[STEPCOUNT1]
    CCP2CON.4 = Temp.0 ' bit 0
    CCP2CON.5 = Temp.1 ' bit 1
    CCPR2L = Temp >>2 'Bit 2-7
    if stepcount = 36 then stepcount =0
    if stepcount1 = 24 then stepcount1 =0
    stepcount = stepcount +1
    stepcount = stepcount1 +1

    @ INT_RETURN



    any one can help me
    Attached Files Attached Files

  40. #80
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: sinusoidal PWM

    Hi,

    First of all, please don't post the same question in several threads. It makes it really hard for people to help you then when someone answers in one thread and someone else in the other. It gets impossible to get the whole picture then.

    Second, when posting code put it in between code-tags so it shows up in a scrollable window instead of just cut and paste it.

    Right, your code then...
    1)
    Code:
    TMR1L = 255
    TMR1H = 254
    This doesn't make much sense, all it does is cause an interrupt after a single cycle. The timer reloading is done in the ISR so just remove those two lines.

    2) It's best to stop the timer before reloading it as it can otherwise overflow between writing to the low and high byte. Even better is to stop it and then ADD the calculated reload value to the timer register as this will account for the otherwsie lost time that occurs when entering the ISR.

    3) You have two index variables pointing into the the array (StepCount and StepCount1). To get the phase shift you need to start at different places in the SIN-table, if you don't the phases will be "in sync".

    4)
    Code:
    if stepcount = 36 then stepcount =0
    if stepcount1 = 24 then stepcount1 =0
    stepcount = stepcount +1
    stepcount = stepcount1 +1
    Here you have three problems.
    4.1) There are 36 entries the table, numbered 0-35. Because you are incrementing your pointers AFTER you check if it's 36 you're actually trying to ACCESS sinval[36] which isn't that good since it doesn't exist. Swap that around so that you increment the pointer FIRST then check if its beyond the boundry of the array.

    4.2) You reset stepcount1 to 0 when it reach 24 so you won't get a full cycle out of it. It needs to get to 36 and then be reset but again, you need to "start" it at 12 instead of 0.

    4.3) If you look at the last two lines of your code above you never actually increment StepCount1.

    Start by fixing that and see what happens. May I also suggest you toggle an output or something in the ISR to verify that you've got the correct interrupt frequency.

    /Henrik.
    Last edited by HenrikOlsson; - 12th February 2012 at 13:08.

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