Changing the sines frequency?


Closed Thread
Results 1 to 33 of 33
  1. #1

    Default Changing the sines frequency?

    Hi everyone,

    I'm again here with my three-phase sines.

    All works great, I can change the frequency (by varying the interrupt "timer" variable) and the amplitude of my sines (by varying the "amplitude" variable).

    But something is strange with the timer : the output sines frequency is not proportinal with the timer value. There is what I get from real experimentations :


    Of course, for the calculation of U/F variables, is far more complicated.

    So, how I can calculate the output frequency of my sines internally by the PIC?
    Or how I can change the sines frequency proportionally with an another method than varying "timer" variable?

    Thanks.

    Code :
    Code:
    ' PIC initialization
    DEFINE OSC 40      
    DEFINE LCD_DREG PORTC
    DEFINE LCD_EREG PORTD
    DEFINE LCD_RSREG PORTD
    DEFINE LCD_EBIT 0
    DEFINE LCD_RSBIT 1
    DEFINE LCD_COMMANDUS 4000
    DEFINE LCD_DATAUS 100
    DEFINE USE_LOWPRIORITY 1
    
    
    ' BAS includes
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "ReEnterPBP-18LP.bas"
    INCLUDE "Sine_table.bas"
    INCLUDE "Freq_table.bas"
    
    
    ' Port registers configuration
    TRISB=%11000000   ' PWM 0,1,2,3,4,5 outputs
    TRISC=%00110000   ' +/- buttons
    
    
    ' PCPWM registers configuration
    DTCON=%110        ' Deadtime (600ns)
    PTCON0=%0         ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
    PTCON1=%10000000  ' PWM time base is ON, counts up, 19.45kHz/4
    PWMCON0=%1000000  ' PWM 0,1,2,3,4,5 set in pair mode
    PWMCON1=%1        ' PWM timer sync configuration
    
    
    ' PWM calculation variables
    ustep var byte
    vstep var byte
    wstep var byte
    uduty var word
    vduty var word
    wduty var word
    timer var word
    amplitude var word
    carrier VAR word
    flag var bit
    
    
    ' Variables definition
    ustep=72          ' 360 degrees phase angle
    vstep=48          ' 240 degrees phase angle
    wstep=24          ' 120 degrees phase angle
    timer=64120       ' Timer adjust (64120=120Hz) 
    amplitude=65535   ' Sinewave amplitude adjust (65535=max amplitude)
    carrier=1023      ' Carrier frequency adjust (1023=13kHz)
    flag=%0           ' Menu flag
    
    
    ' PWM carrier frequency register configuration
    PTPERL=carrier.lowbyte  
    PTPERH=carrier.highbyte
    
      
    ' Interrupt processors 
    ASM
    INT_LIST macro
             INT_Handler TMR1_INT,_pwmint,PBP,yes
             endm
             INT_CREATE 
        
    INT_LIST_L macro
               INT_Handler TMR0_INT,_mainint,PBP,no
               endm
               INT_CREATE_L       
    ENDASM
    
        
    ' Timers configuration
    T1CON=%10000001
    T0CON=%10000111
    
    
    ' Interrupts enable
    @ INT_ENABLE TMR1_INT
    @ INT_ENABLE TMR0_INT
    
    
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
    
    ' Timer 1 update
    TMR1L=timer.lowbyte
    TMR1H=timer.highbyte
    
    ' PWM U phase calculation
    uduty=sine[ustep]
    uduty=uduty<<4**amplitude+3
    
    ' PWM V phase calculation
    vduty=sine[vstep]
    vduty=vduty<<4**amplitude+3
    
    ' PWM W phase calculation
    wduty=sine[wstep]
    wduty=wduty<<4**amplitude+3
    
    ' PWM U, V and W update
    PDC0L=uduty.lowbyte
    PDC0H=uduty.highbyte
    PDC1L=vduty.lowbyte
    PDC1H=vduty.highbyte
    PDC2L=wduty.lowbyte
    PDC2H=wduty.highbyte
    
    ' Phase angle calculation
    ustep=ustep-1
    vstep=vstep-1
    wstep=wstep-1
    
    ' Phase angle reinitialization
    if ustep=0 then ustep=72
    if vstep=0 then vstep=72
    if wstep=0 then wstep=72
    
    @ INT_RETURN
    
    
    ' Main program loop interrupt (Timer 0)
    mainint:
    
    ' Debug display
    if flag=0 then
    LCDOUT $FE,$2,"Timer adjust :"
    LCDOUT $FE,$C0,DEC5 timer
    if PORTC.4=1 then timer=timer-1
    if PORTC.5=1 then timer=timer+1
    IF PORTC.4 AND PORTC.5=1 then flag=%1
    else
    LCDOUT $FE,$2,"Amp. adjust :"
    LCDOUT $FE,$C0,DEC5 amplitude
    if PORTC.4=1 then amplitude=amplitude-1
    if PORTC.5=1 then amplitude=amplitude+1
    endif
    
    @ INT_RETURN
    Last edited by pxidr84; - 2nd March 2011 at 14:40.

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


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Hi,
    Running the PIC at 40Mhz and having a prescaler on TMR1 of 1:1 (no prescaler) makes it "tick" at 10MHz. Your sine-table, if I understand correctly contains 72 "steps" so you need 72 interrupts per second per Hz output frequency.

    At 120 Hz output frequency you need 120*72= 8640Hz or an interrupt interval of 115.7us. At 10Mhz one "tick" is 0.1us so you need 1116 ticks between interrupts and therefor you should (theoretically) reload the timer with: 65536-1116 = 64420.

    At 10Hz you need 720 interrupts per second or an interrupt interval of 1388.9us. That's 13889 ticks so you need to reload the timer with 65536-13889 = 51647.


    Now, when the timer overflows and trips the interrupt a lot of things has to happend. The DT-Ints interrupt "engine" has to save all the PBP system varibles and this takes time. By the time the code actually gets to reloading TMR1 with your calculated reload value several hundred cycles have passed. If you then reload it with the "original", calculated value you are effectively "turning back the time" or reclaiming time that has already passed.

    What you usually do is stop the timer, make a copy of its content and then ADD the reload value to the value of the copy. Then you put the value back in the timer and restart it. Obviously this too takes a couple of cycles so to be really accurate you need to tweak the reload values to account for it. Basically
    Code:
    TimerShadow VAR WORD
     
    T1CON.0 = 0  'Stop TMR1
    TimerShadow.HighByte = TMR1H
    TimerShadow.LowByte = TMR1L
    TimerShadow = TimerShadow + TimerReload
    TMR1H = TimerShadow.HighByte
    TMR1L = TimerShadow.LowByte
    T1CON.0 = 1  'Restart TMR1
    I see that you have 16bit read/write of TMR1 enabled, I don't know how that affects the above but I'd probably turn that off to begin with.

    In the INT_List for the low priority interrupt you have the Reset_Flag set to NO for TMR0 - why is that? You don't seem to reset it "manually" in the ISR.

    Finally, in your TMR0 interupt, don't do the LCDOUT etc in there. Set a flag and get out of there, then in your main routine you check the flag, if set do whatever and reset the flag.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Thanks Henrik (again), I will make some experiments with your tips.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    Running the PIC at 40Mhz and having a prescaler on TMR1 of 1:1 (no prescaler) makes it "tick" at 10MHz. Your sine-table, if I understand correctly contains 72 "steps" so you need 72 interrupts per second per Hz output frequency.

    At 120 Hz output frequency you need 120*72= 8640Hz or an interrupt interval of 115.7us. At 10Mhz one "tick" is 0.1us so you need 1116 ticks between interrupts and therefor you should (theoretically) reload the timer with: 65536-1116 = 64420.

    At 10Hz you need 720 interrupts per second or an interrupt interval of 1388.9us. That's 13889 ticks so you need to reload the timer with 65536-13889 = 51647.


    Now, when the timer overflows and trips the interrupt a lot of things has to happend. The DT-Ints interrupt "engine" has to save all the PBP system varibles and this takes time. By the time the code actually gets to reloading TMR1 with your calculated reload value several hundred cycles have passed. If you then reload it with the "original", calculated value you are effectively "turning back the time" or reclaiming time that has already passed.

    What you usually do is stop the timer, make a copy of its content and then ADD the reload value to the value of the copy. Then you put the value back in the timer and restart it. Obviously this too takes a couple of cycles so to be really accurate you need to tweak the reload values to account for it. Basically
    Code:
    TimerShadow VAR WORD
     
    T1CON.0 = 0  'Stop TMR1
    TimerShadow.HighByte = TMR1H
    TimerShadow.LowByte = TMR1L
    TimerShadow = TimerShadow + TimerReload
    TMR1H = TimerShadow.HighByte
    TMR1L = TimerShadow.LowByte
    T1CON.0 = 1  'Restart TMR1
    I see that you have 16bit read/write of TMR1 enabled, I don't know how that affects the above but I'd probably turn that off to begin with.

    In the INT_List for the low priority interrupt you have the Reset_Flag set to NO for TMR0 - why is that? You don't seem to reset it "manually" in the ISR.

    Finally, in your TMR0 interupt, don't do the LCDOUT etc in there. Set a flag and get out of there, then in your main routine you check the flag, if set do whatever and reset the flag.
    Excuse me for my misunderstanding...
    I've made some experiments with your routine, I can change the frequency, but even not proportionnaly, how do you integrate your routine into my program?
    Last edited by pxidr84; - 4th March 2011 at 16:54.

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


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Hi,
    It's possible that you are simply trying to interrupt to fast and that it's overrunning it self - ie, another interrupt occurs before while servicing the first one. Try removing the all code from your ISR and replace with a simple TOGGLE PORTB.0 or whatever, measure the frequency of the output, that should give a clue as to what is going on.

  6. #6


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Now I use this DT routine -> http://darreltaylor.com/DT_INTS-14/TimerTemplate.html

    Hurray, I can set my desired interrupt frequency, so I can get my desired output frequency. It's the same principle of your code above.

    But I've a little problem :

    I like to define this ASM variable (@Freq = 10 ) to a PBP variable (for modify it in PBP and display it on the LCD for example).

    I've tried this :
    intfreq VAR WORD
    intfreq=5000
    @Freq = _intfreq

    But it doesn't work at all.

    Here's the DT timer template code :

    Code:
    ; Initialize your hardware first
    
    DEFINE OSC 20
    
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ; Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   ReloadTMR1,   ASM,  no    ; MUST be first
            INT_Handler   TMR1_INT,   _T1handler,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    ;--- Change these to match the desired interrupt frequency -------------------
    ;--- See http://DarrelTaylor.com/DT_INTS-14/TimerTemplate.html for more Info.
    @Freq       = 10                  ; Frequency of Interrupts in Hz
    @Prescaler  = 8                   ; Timers Prescaler setting
    T1CON = $30                       ; $30 = Prescaler 1:8, TMR1 OFF
    ; $00=1:1, $10=1:2, $20=1:4, $30=1:8 --  Must match @Prescaler value
    
    @ INT_ENABLE  TMR1_INT            ; enable Timer 1 interrupts
    GOSUB StartTimer                  ; Start the Timer
    
    ;____Your Main Program goes here______________________________________________
    Main:
      ;   ---- Your Main Program goes here ----
    GOTO Main
    
    ;____This routine is Called on each TMR1 Interrupt____________________________
    T1handler:
      ;   ---- Your interrupt routine goes here ----
      
    @ INT_RETURN
    
    ;---[TMR1 reload - interrupt handler]-----------------------------------------
    ASM                               ; Calculate Timer Reload Constant
    ReloadInst  = 8                   ; # of Intructions used to reload timer
      if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
    MaxCount    = 65536 + (ReloadInst / Prescaler)
    TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
        if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
            error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
        endif
      else
          error Invalid Prescaler
      endif
    ENDASM
    
    @Timer1 = TMR1L                   ; map timer registers to a word variable
    Timer1       VAR WORD EXT
    TimerReload  CON EXT              ; Get the External Constant
    TMR1ON       VAR T1CON.0          ; Alias the Timers ON/OFF bit
    
    ;---Reload Timer1------
    ASM
    ReloadTMR1
        MOVE?CT  0, T1CON, TMR1ON     ;  1     stop timer
        MOVLW    LOW(TimerReload)     ;  1     Add TimerReload to the 
        ADDWF    TMR1L,F              ;  1     value in Timer1
        BTFSC    STATUS,C             ;  1/2
        INCF     TMR1H,F              ;  1
        MOVLW    HIGH(TimerReload)    ;  1
        ADDWF    TMR1H,F              ;  1
        MOVE?CT  1, T1CON, TMR1ON     ;  1     start timer
      INT_RETURN
    ENDASM
    
    ;---Start/Stop controls -----
    StartTimer:
        Timer1  = TimerReload         ; Load Timer
        TMR1ON = 1                    ; start timer
    RETURN
    
    StopTimer:
        TMR1ON = 0                    ; stop timer
    RETURN

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,610


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Hi
    Aren't you using a PIC18F4431? If so you should use DT-INTS-18 but I suspect that is what you are doing even if you posted the DT-INTS-14 code?

    Right, as far as I know the Freq variable isn't a variable it's an assembler constant. The TimerReload value is calculated at assembly time (not runtime) so once the code is assembled Freq no longer exists and can't be changed.

    If you're using the timer template then it's the TimerReload value you should change in order to change the frequency - which is the same thing as we've been thru earlier in the thread.

    /Henrik.

  8. #8


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Of course I'm using DT-INTS_18. Above is the sample code provided by Darrel.

    I've misreaded this line : "The frequency will remain constant and cannot be changed during Run-Time." F*ck.

    You tell me to stop the timer, make a copy, and restart it. Only the "Timer1" variable can be changed in this DT's routine. Some routines are already made on this program : "StartTimer" and "StopTimer".

    I'm sorry, but I'd like you modify my program, because I'm completly stuck at this point so many days...

    The only thing I want is control the TMR1 interrupt frequency precisely, even in runtime.

    I've tried
    Code:
    TimerShadow VAR WORD
    TimerShadow=5000
    
    .
    .
    .
    
    StartTimer:
    Timer1=TimerReload+TimerShadow         
    TMR1ON=1                    
    RETURN
    But of course it didn't works.

    I've also modified the code assuming your tips :

    Code:
    ' PIC initialization
    DEFINE OSC 40      
    DEFINE LCD_DREG PORTC
    DEFINE LCD_EREG PORTD
    DEFINE LCD_RSREG PORTD
    DEFINE LCD_EBIT 0
    DEFINE LCD_RSBIT 1
    DEFINE LCD_COMMANDUS 4000
    DEFINE LCD_DATAUS 1000
    
    
    ' BAS includes
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "Sine_table.bas"
    
    
    ' Port registers configuration
    TRISB=%11000000   ' PWM 0,1,2,3,4,5 outputs
    TRISC=%00110000   ' +/- buttons
    
    
    ' PCPWM registers configuration
    DTCON=%110        ' Deadtime (600ns)
    PTCON0=%0         ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
    PTCON1=%10000000  ' PWM time base is ON, counts up, 19.45kHz/4
    PWMCON0=%1000000  ' PWM 0,1,2,3,4,5 set in pair mode
    PWMCON1=%1        ' PWM timer sync configuration
    
    
    ' PWM calculation variables
    ustep var byte
    vstep var byte
    wstep var byte
    uduty var word
    vduty var word
    wduty var word
    frequency var word
    amplitude var word
    carrier VAR word
    flag var bit
    
    
    ' Variables definition
    ustep=90          ' 360 degrees phase angle
    vstep=60          ' 240 degrees phase angle
    wstep=30          ' 120 degrees phase angle
    frequency=1200    ' Frequency adjust
    amplitude=65535   ' Sinewave amplitude adjust (65535=max amplitude)
    carrier=1023      ' Carrier frequency adjust (1023=13kHz)
    flag=%0           ' Menu flag
    
    
    ' PWM carrier frequency register configuration
    PTPERL=carrier.lowbyte  
    PTPERH=carrier.highbyte
    
      
    ' Interrupt processors 
    ASM
    INT_LIST macro
    INT_Handler TMR1_INT,ReloadTMR1,ASM,no
    INT_Handler TMR1_INT,_pwmint,PBP,yes
    endm
    INT_CREATE       
    ENDASM
    
        
    ' Timers configuration
    @Freq=4050   
    @Prescaler=1                  
    T1CON=$00
    
    
    ' Interrupts enable
    @INT_ENABLE TMR1_INT
    GOSUB StartTimer 
    
    
    ' Main program loop
    mainlp:
    
    ' Debug display
    if flag=0 then
    LCDOUT $FE,$2,"Freq. adjust :"
    LCDOUT $FE,$C0, DEC frequency
    if PORTC.4=1 then frequency=frequency-1
    if PORTC.5=1 then frequency=frequency+1
    IF PORTC.4 AND PORTC.5=1 then flag=%1
    else
    LCDOUT $FE,$2,"Amp. adjust :"
    LCDOUT $FE,$C0,DEC4 amplitude
    if PORTC.4=1 then amplitude=amplitude-1
    if PORTC.5=1 then amplitude=amplitude+1
    endif
    
    goto mainlp
    
    
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
    
    ' PWM U phase calculation
    uduty=sine[ustep]
    uduty=uduty<<4**amplitude
    
    ' PWM V phase calculation
    vduty=sine[vstep]
    vduty=vduty<<4**amplitude
    
    ' PWM W phase calculation
    wduty=sine[wstep]
    wduty=wduty<<4**amplitude
    
    ' PWM U, V and W update
    PDC0L=uduty.lowbyte
    PDC0H=uduty.highbyte
    PDC1L=vduty.lowbyte
    PDC1H=vduty.highbyte
    PDC2L=wduty.lowbyte
    PDC2H=wduty.highbyte
    
    ' Phase angle calculation
    ustep=ustep-1
    vstep=vstep-1
    wstep=wstep-1
    
    ' Phase angle reinitialization
    if ustep=0 then ustep=90
    if vstep=0 then vstep=90
    if wstep=0 then wstep=90
    
    @INT_RETURN
    
    
    ' Timer1 interrupt handler
    ASM                               
    ReloadInst=8                  
    MaxCount=65536+(ReloadInst/Prescaler)
    TimerReload=MaxCount-(OSC*1000000/4/Prescaler/Freq)
    ENDASM
    
    
    ' Timer1 variables
    @Timer1=TMR1L                   
    Timer1 VAR WORD EXT
    TimerReload CON EXT              
    TMR1ON VAR T1CON.0        
    
    
    ' Timer1 reload
    ASM
    ReloadTMR1
    MOVE?CT 0,T1CON,TMR1ON     
    MOVLW LOW(TimerReload)    
    ADDWF TMR1L,F             
    BTFSC STATUS,C             
    INCF TMR1H,F           
    MOVLW HIGH(TimerReload)   
    ADDWF TMR1H,F             
    MOVE?CT 1,T1CON,TMR1ON     
    INT_RETURN
    ENDASM
    
    
    ' Timer1 start/stop control
    StartTimer:
    Timer1=TimerReload         
    TMR1ON=1                    
    RETURN
    
    StopTimer:
    TMR1ON=0                 
    RETURN
    Also, this afternoon, I will modify the ISR and replace it with TOGGLE PORTB.0, to measure interrupt frequency. I'll give you results.
    Last edited by pxidr84; - 6th March 2011 at 10:28.

  9. #9
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,610


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Now you are mixing your original code with Darrels template and what I tried to tell you earlier into a complete mess....

    The only thing I want is control the TMR1 interrupt frequency precisely, even in runtime.
    Yes, and to do that you change the reload value which you load TMR1 with at each interrupt. In the timer1 intterupt stop the timer, add your reload value to the value of the timer and restart it. Then do whatever else needs to be done in the ISR. Did you try the code I posted in my first reply?

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


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Adding to previous message: The higher in interrupt frequency you go the less "resolution" in interrupt frequency you'll get. As an example, preloading the the timer with 65535 would make it go a single tick bwetween interrupts, in other words an interrupt frequency of 2.5Mhz when using a 20MHz crystal. (Won't work in reality but serves the purpose of this discussion).

    Now, preloading the timer with 65534 would cut that interrupt frequency in half to 1.25Mhz.

    At the other end of the spectrum, going from a preload value of 0 to a preload value of 1 only changes the interrupt frequency by something like 0.001Hz.

    The higher the "base frequency" is (the PIC clock in this case) the more resolution you'll get at the upper end.

    So, in order to get a linear output frequency you need to calculate the correct preload value, either at runtime ot use a lookuptable and interpolate between points or something.

  11. #11


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Quote Originally Posted by HenrikOlsson View Post
    Now you are mixing your original code with Darrels template and what I tried to tell you earlier into a complete mess....


    Yes, and to do that you change the reload value which you load TMR1 with at each interrupt. In the timer1 intterupt stop the timer, add your reload value to the value of the timer and restart it. Then do whatever else needs to be done in the ISR. Did you try the code I posted in my first reply?

    Of course I've readed your first reply, and it's how I integrated your routine into my code :
    Code:
    ' PIC initialization
    DEFINE OSC 40      
    DEFINE LCD_DREG PORTC
    DEFINE LCD_EREG PORTD
    DEFINE LCD_RSREG PORTD
    DEFINE LCD_EBIT 0
    DEFINE LCD_RSBIT 1
    DEFINE LCD_COMMANDUS 4000
    DEFINE LCD_DATAUS 1000
    
    
    ' BAS includes
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "Sine_table.bas"
    
    
    ' Port registers configuration
    TRISB=%11000000   ' PWM 0,1,2,3,4,5 outputs
    TRISC=%00110000   ' +/- buttons
    
    
    ' PCPWM registers configuration
    DTCON=%110        ' Deadtime (600ns)
    PTCON0=%0         ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
    PTCON1=%10000000  ' PWM time base is ON, counts up, 19.45kHz/4
    PWMCON0=%1000000  ' PWM 0,1,2,3,4,5 set in pair mode
    PWMCON1=%1        ' PWM timer sync configuration
    
    
    ' PWM calculation variables
    ustep var byte
    vstep var byte
    wstep var byte
    uduty var word
    vduty var word
    wduty var word
    timer var word
    amplitude var word
    carrier VAR word
    flag var bit
    
    
    ' Variables definition
    ustep=90          ' 360 degrees phase angle
    vstep=60          ' 240 degrees phase angle
    wstep=30          ' 120 degrees phase angle
    timer=64120       ' Timer adjust
    amplitude=65535   ' Sinewave amplitude adjust (65535=max amplitude)
    carrier=1023      ' Carrier frequency adjust (1023=13kHz)
    flag=%0           ' Menu flag
    
    
    ' PWM carrier frequency register configuration
    PTPERL=carrier.lowbyte  
    PTPERH=carrier.highbyte
    
      
    ' Interrupt processors 
    ASM
    INT_LIST macro
    INT_Handler TMR1_INT,_pwmint,PBP,yes
    endm
    INT_CREATE       
    ENDASM
    
        
    ' Timers configuration
    T1CON=%1
    
    
    ' Interrupts enable
    @INT_ENABLE TMR1_INT
    
    
    ' Main program loop
    mainlp:
    
    ' Debug display
    if flag=0 then
    LCDOUT $FE,$2,"Freq. adjust :"
    LCDOUT $FE,$C0,DEC timer
    if PORTC.4=1 then timer=timer-1
    if PORTC.5=1 then timer=timer+1
    IF PORTC.4 AND PORTC.5=1 then flag=%1
    else
    LCDOUT $FE,$2,"Amp. adjust :"
    LCDOUT $FE,$C0,DEC4 amplitude
    if PORTC.4=1 then amplitude=amplitude-1
    if PORTC.5=1 then amplitude=amplitude+1
    endif
    
    goto mainlp
    
    TimerShadow VAR WORD
    TimerReload VAR WORD
    
    TimerReload=64000 'Test
    
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
    
    ' Timer 1 update
    TMR1L=timer.lowbyte
    TMR1H=timer.highbyte
    
    T1CON.0 = 0  'Stop TMR1
    TimerShadow.HighByte = TMR1H
    TimerShadow.LowByte = TMR1L
    TimerShadow = TimerShadow + TimerReload
    TMR1H = TimerShadow.HighByte
    TMR1L = TimerShadow.LowByte
    T1CON.0 = 1  'Restart TMR1
    
    ' PWM U phase calculation
    uduty=sine[ustep]
    uduty=uduty<<4**amplitude
    
    ' PWM V phase calculation
    vduty=sine[vstep]
    vduty=vduty<<4**amplitude
    
    ' PWM W phase calculation
    wduty=sine[wstep]
    wduty=wduty<<4**amplitude
    
    ' PWM U, V and W update
    PDC0L=uduty.lowbyte
    PDC0H=uduty.highbyte
    PDC1L=vduty.lowbyte
    PDC1H=vduty.highbyte
    PDC2L=wduty.lowbyte
    PDC2H=wduty.highbyte
    
    ' Phase angle calculation
    ustep=ustep-1
    vstep=vstep-1
    wstep=wstep-1
    
    ' Phase angle reinitialization
    if ustep=0 then ustep=90
    if vstep=0 then vstep=90
    if wstep=0 then wstep=90
    
    @INT_RETURN
    It doesnt work at all, but I think it's how I integrate your routine in the code, badly I think.

    And with this :
    Code:
    pwmint:
    
    toggle PORTD.7
    
    @INT_RETURN
    I get a 100Hz output frequency on PORTD.7.
    Last edited by pxidr84; - 6th March 2011 at 18:14.

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


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    I get a 100Hz output frequency on PORTD.7.
    Yes, but you still need to keep the reloading code in the interrupt routine otherwise the timer will "freewheel" again.

    In your code, as the very first thing in the ISR, you are currently overwriting the TMR1 register with the value of a variable called timer.
    Code:
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
     
    ' Timer 1 update
    TMR1L=timer.lowbyte     '<---This is overwriting the TMR1 registers!
    TMR1H=timer.highbyte
    So, once the code gets to "copying" the TMR1 registers and adding the reload value to it you have overwritten it with something else.

    I've just tested the following code here:
    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
     
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "IncPID.pbp"
     
    TMRCopy VAR WORD
    TimerReloadValue VAR WORD
    TimerReloadValue = 63000
     
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,  _TimezUp,   PBP,  yes
        endm
        INT_CREATE              ; Creates the interrupt processor
    ENDASM
     
    @ INT_ENABLE  TMR1_INT      ; enable Timer 1 interrupts
     
    TRISB.0 = 1                 ' +button
    TRISA.4 = 1                 ' -button
    TRISB.3 = 0                 ' Output to measure interrupt frequency 
     
    CMCON = 7
    ADCON1 = %00001111          ' No analog inputs.
    T1CON.0 = 1                 ' Start TMR1
     
    Main:
    If PortB.0 = 0 then
      TimerReloadValue = TimerReloadValue + 1
      LCDOUT $FE,1,#TimerReloadValue
    ENDIF
    If PortA.4 = 0 then
      TimerReloadValue = TimerReloadValue - 1
      LCDOUT $FE,1,#TimerReloadValue
    ENDIF
    Pause 20
    Goto Main
     
    ' ---------- Interrupt handler ------------
    TimezUp:
      T1CON.0 = 0                             ' Stop TMR1
      TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
      TMRCopy.LowByte = TMR1L 
      TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
      TMR1H = TMRCOPY.HighByte                ' And back to TMR1
      TMR1L = TMRCopy.LowByte
      T1CON.0 = 1                             ' Restart Timer
    Toggle PortB.3
    @ INT_RETURN
    And it works fine. Pushing the buttons connected to PortB.0 and PortA.4 increases/decreases the reload value for the timer and the interrupt frequency.

    But, again, a change of 1 at the "top" will not result in the same change in interrupt frequency as a change of 1 at the "botton".

  13. #13


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Quote Originally Posted by HenrikOlsson View Post
    Yes, but you still need to keep the reloading code in the interrupt routine otherwise the timer will "freewheel" again.

    In your code, as the very first thing in the ISR, you are currently overwriting the TMR1 register with the value of a variable called timer.
    Code:
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
     
    ' Timer 1 update
    TMR1L=timer.lowbyte     '<---This is overwriting the TMR1 registers!
    TMR1H=timer.highbyte
    So, once the code gets to "copying" the TMR1 registers and adding the reload value to it you have overwritten it with something else.

    I've just tested the following code here:
    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
     
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "IncPID.pbp"
     
    TMRCopy VAR WORD
    TimerReloadValue VAR WORD
    TimerReloadValue = 63000
     
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,  _TimezUp,   PBP,  yes
        endm
        INT_CREATE              ; Creates the interrupt processor
    ENDASM
     
    @ INT_ENABLE  TMR1_INT      ; enable Timer 1 interrupts
     
    TRISB.0 = 1                 ' +button
    TRISA.4 = 1                 ' -button
    TRISB.3 = 0                 ' Output to measure interrupt frequency 
     
    CMCON = 7
    ADCON1 = %00001111          ' No analog inputs.
    T1CON.0 = 1                 ' Start TMR1
     
    Main:
    If PortB.0 = 0 then
      TimerReloadValue = TimerReloadValue + 1
      LCDOUT $FE,1,#TimerReloadValue
    ENDIF
    If PortA.4 = 0 then
      TimerReloadValue = TimerReloadValue - 1
      LCDOUT $FE,1,#TimerReloadValue
    ENDIF
    Pause 20
    Goto Main
     
    ' ---------- Interrupt handler ------------
    TimezUp:
      T1CON.0 = 0                             ' Stop TMR1
      TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
      TMRCopy.LowByte = TMR1L 
      TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
      TMR1H = TMRCOPY.HighByte                ' And back to TMR1
      TMR1L = TMRCopy.LowByte
      T1CON.0 = 1                             ' Restart Timer
    Toggle PortB.3
    @ INT_RETURN
    And it works fine. Pushing the buttons connected to PortB.0 and PortA.4 increases/decreases the reload value for the timer and the interrupt frequency.

    But, again, a change of 1 at the "top" will not result in the same change in interrupt frequency as a change of 1 at the "botton".
    Tried this in my code with the sines, it works.

    Code:
    But, again, a change of 1 at the "top" will not result in the same change in interrupt frequency as a change of 1 at the "botton".
    So what the point since the first program? It is impossible to change proportionally this interrupt frequency in run time? Or any math relation/equation to calculate the correct timer value according to the desired frequency?

    Like you said, I can make a lookup table, but this program is intended to make a 3-phase VFD AC motor drive, adjustable from 0 to 120Hz with 0.1Hz increments... so if I use a lookup table, it will take 1200 variables! Doesn't sure that my PIC had enough memory capacity...
    And how to calculate the "correct preload value"?
    Last edited by pxidr84; - 6th March 2011 at 20:27.

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


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    The difference is that it takes the overhead of saving all the PBP system variables into account. There's nothing you can do about the non linearity really - it's just the way it is. One way to reduce the effect of it is to have less "steps" in the SIN table, that willm bring the interrupt frequency down which makes the relationship between interrupt frequency and reload value more linear.

    You CAN calculate the reload value at runtime, Darrels timer template even shows you HOW to do it (at compile/assembly time) but you need to play some tricks to do it runtime. The following is NOT tested:
    Code:
    Dummy VAR WORD
    Dummy2 VAR WORD
    Dummy3 VAR WORD
    ReloadInstructions VAR BYTE
    TimerReload VAR WORD
    Frequency VAR WORD
    
    ReloadInstruction = 0  'Number of instructioncycles it takes to actually reload the timer. I don't know how many it is in this case. Tune later.
    
    'For 40Mhz operation and 1:1 prescaler the timer ticks at 10Mhz
    Dummy2 = 10000     'These can not be constants because 
    Dummy3 = 10000     'constants doesn't work with DIV32
    
    Frequency = 200    'Lowest possible frequency is ~153Hz. Don't go below that.
    
    Dummy = Dummy2 * Dummy3        'Intermediate result is now 10.000.000
    TimerReload = DIV32 Frequency       'Divide 10.000.000 in Frequency (200 in this case) 
    TimerReload = 65535 - TimerReload + 1 + ReloadInstructions  ' =15536 for 200Hz
    
    'Reloading the timer with 15536 makes it time out in 50000 ticks, one tick is 0.1us so
    'it times out it 5000us or 5ms, 1/0.005=200Hz which is the frequency we wanted.
    This should calculate the reload value, at runtime (don't do this IN the interrupt service routine). But I don't think you'll get 0.1Hz resolution at the top end.

  15. #15


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Thanks, I will make some experiments with this code.

  16. #16


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Unfortuntely, it doesn't works.

    The problem is that TimerReload variable overwrites TimerReload EXT constant, defined later in DT routine.

    Code:
    ' PIC initialization
    DEFINE OSC 40      
    DEFINE LCD_DREG PORTC
    DEFINE LCD_EREG PORTD
    DEFINE LCD_RSREG PORTD
    DEFINE LCD_EBIT 0
    DEFINE LCD_RSBIT 1
    DEFINE LCD_COMMANDUS 4000
    DEFINE LCD_DATAUS 1000
    
    
    ' BAS includes
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "Sine_table.bas"
    
    
    ' Port registers configuration
    TRISB=%11000000   ' PWM 0,1,2,3,4,5 outputs
    TRISC=%00110000   ' +/- buttons
    
    
    ' PCPWM registers configuration
    DTCON=%110        ' Deadtime (600ns)
    PTCON0=%0         ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
    PTCON1=%10000000  ' PWM time base is ON, counts up, 19.45kHz/4
    PWMCON0=%1000000  ' PWM 0,1,2,3,4,5 set in pair mode
    PWMCON1=%1        ' PWM timer sync configuration
    
    
    ' PWM calculation variables
    ustep var byte
    vstep var byte
    wstep var byte
    uduty var word
    vduty var word
    wduty var word
    amplitude var word
    carrier VAR word
    flag var bit
    
    
    ' Variables definition
    ustep=90          ' 360 degrees phase angle
    vstep=60          ' 240 degrees phase angle
    wstep=30          ' 120 degrees phase angle
    amplitude=65535   ' Sinewave amplitude adjust (65535=max amplitude)
    carrier=1023      ' Carrier frequency adjust (1023=13kHz)
    flag=%0           ' Menu flag
    
    
    ' PWM carrier frequency register configuration
    PTPERL=carrier.lowbyte  
    PTPERH=carrier.highbyte
    
    Dummy VAR WORD
    Dummy2 VAR WORD
    Dummy3 VAR WORD
    ReloadInstruction VAR BYTE
    TimerReload VAR WORD
    Frequency VAR WORD
    
    
    ReloadInstruction = 0  'Number of instructioncycles it takes to actually reload the timer. I don't know how many it is in this case. Tune later.
    
    'For 40Mhz operation and 1:1 prescaler the timer ticks at 10Mhz
    Dummy2 = 10000     'These can not be constants because 
    Dummy3 = 10000     'constants doesn't work with DIV32
    
    Frequency = 5000    'Lowest possible frequency is ~153Hz. Don't go below that.
    
    Dummy = Dummy2 * Dummy3        'Intermediate result is now 10.000.000
    TimerReload = DIV32 Frequency       'Divide 10.000.000 in Frequency (200 in this case) 
    TimerReload = 65535 - TimerReload + 1 + ReloadInstruction  ' =15536 for 200Hz
    
    
    ' Interrupt processors 
    ASM
    INT_LIST macro
    INT_Handler TMR1_INT,ReloadTMR1,ASM,no
    INT_Handler TMR1_INT,_pwmint,PBP,yes
    endm
    INT_CREATE       
    ENDASM
    
        
    ' Timers configuration
    @Freq=4050   
    @Prescaler=1                  
    T1CON=$00
    
    
    ' Interrupts enable
    @INT_ENABLE TMR1_INT
    GOSUB StartTimer 
    
    
    ' Main program loop
    mainlp:
    
    ' Debug display
    if flag=0 then
    LCDOUT $FE,$2,"Freq. adjust :"
    LCDOUT $FE,$C0, DEC frequency
    if PORTC.4=1 then frequency=frequency-1
    if PORTC.5=1 then frequency=frequency+1
    IF PORTC.4 AND PORTC.5=1 then flag=%1
    else
    LCDOUT $FE,$2,"Amp. adjust :"
    LCDOUT $FE,$C0,DEC4 amplitude
    if PORTC.4=1 then amplitude=amplitude-1
    if PORTC.5=1 then amplitude=amplitude+1
    endif
    
    goto mainlp
    
    
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
    
    ' PWM U phase calculation
    uduty=sine[ustep]
    uduty=uduty<<4**amplitude
    
    ' PWM V phase calculation
    vduty=sine[vstep]
    vduty=vduty<<4**amplitude
    
    ' PWM W phase calculation
    wduty=sine[wstep]
    wduty=wduty<<4**amplitude
    
    ' PWM U, V and W update
    PDC0L=uduty.lowbyte
    PDC0H=uduty.highbyte
    PDC1L=vduty.lowbyte
    PDC1H=vduty.highbyte
    PDC2L=wduty.lowbyte
    PDC2H=wduty.highbyte
    
    ' Phase angle calculation
    ustep=ustep-1
    vstep=vstep-1
    wstep=wstep-1
    
    ' Phase angle reinitialization
    if ustep=0 then ustep=90
    if vstep=0 then vstep=90
    if wstep=0 then wstep=90
    
    @INT_RETURN
    
    
    ' Timer1 interrupt handler
    ASM                               
    ReloadInst=8                  
    MaxCount=65536+(ReloadInst/Prescaler)
    TimerReload=MaxCount-(OSC*1000000/4/Prescaler/Freq)
    ENDASM
    
    
    ' Timer1 variables
    @Timer1=TMR1L                   
    Timer1 VAR WORD EXT
    'TimerReload VAR EXT              
    TMR1ON VAR T1CON.0        
    
    
    ' Timer1 reload
    ASM
    ReloadTMR1
    MOVE?CT 0,T1CON,TMR1ON     
    MOVLW LOW(TimerReload)    
    ADDWF TMR1L,F             
    BTFSC STATUS,C             
    INCF TMR1H,F           
    MOVLW HIGH(TimerReload)   
    ADDWF TMR1H,F             
    MOVE?CT 1,T1CON,TMR1ON     
    INT_RETURN
    ENDASM
    
    
    ' Timer1 start/stop control
    StartTimer:
    Timer1=TimerReload         
    TMR1ON=1                    
    RETURN
    
    StopTimer:
    TMR1ON=0                 
    RETURN
    Last edited by pxidr84; - 7th March 2011 at 20:30.

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


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Yes of course it does. I thought we came to the conclusion that you couldn't use Darrels timer template because it calculated the reload value at build time and you wanted to calculate it at runtime. Now you're trying to use it anyway....I don't get it.
    Code:
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
     
    InterruptFrequency VAR WORD
    Dummy VAR WORD
    Dummy2 VAR WORD
    Dummy3 VAR WORD
    TMRCopy VAR WORD
    TimerReloadValue VAR WORD
    Dummy2 = 10000
    Dummy3 = 10000
     
    InterruptFrequency = 5000
     
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,  _TimezUp,   PBP,  yes
        endm
        INT_CREATE              ; Creates the interrupt processor
    ENDASM
     
    @ INT_ENABLE  TMR1_INT      ; enable Timer 1 interrupts
     
    TRISB.3 = 0                 ' Output to measure interrupt frequency 
    CMCON = 7
    ADCON1 = %00001111          ' No analog inputs.
     
    T1CON.0 = 1                 ' Start TMR1
     
      Dummy = Dummy2 * Dummy3
      TimerReloadValue = Div32 InterruptFrequency
      TimerReloadValue = 65535 - TimerReloadValue + 1
      LCDOUT $FE,1,"F: ", #InterruptFrequency, " Reload: ", #TimerReloadValue
     
    Main:
     Pause 20
    Goto Main
     
    ' ---------- Interrupt handler ------------
    TimezUp:
      T1CON.0 = 0                             ' Stop TMR1
      TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
      TMRCopy.LowByte = TMR1L 
      TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
      TMR1H = TMRCOPY.HighByte                ' And back to TMR1
      TMR1L = TMRCopy.LowByte
      T1CON.0 = 1                             ' Restart Timer
    Toggle PortB.3
     
    @ INT_RETURN

  18. #18


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Quote Originally Posted by HenrikOlsson View Post
    Yes of course it does. I thought we came to the conclusion that you couldn't use Darrels timer template because it calculated the reload value at build time and you wanted to calculate it at runtime. Now you're trying to use it anyway....I don't get it.
    Code:
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
     
    InterruptFrequency VAR WORD
    Dummy VAR WORD
    Dummy2 VAR WORD
    Dummy3 VAR WORD
    TMRCopy VAR WORD
    TimerReloadValue VAR WORD
    Dummy2 = 10000
    Dummy3 = 10000
     
    InterruptFrequency = 5000
     
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,  _TimezUp,   PBP,  yes
        endm
        INT_CREATE              ; Creates the interrupt processor
    ENDASM
     
    @ INT_ENABLE  TMR1_INT      ; enable Timer 1 interrupts
     
    TRISB.3 = 0                 ' Output to measure interrupt frequency 
    CMCON = 7
    ADCON1 = %00001111          ' No analog inputs.
     
    T1CON.0 = 1                 ' Start TMR1
     
      Dummy = Dummy2 * Dummy3
      TimerReloadValue = Div32 InterruptFrequency
      TimerReloadValue = 65535 - TimerReloadValue + 1
      LCDOUT $FE,1,"F: ", #InterruptFrequency, " Reload: ", #TimerReloadValue
     
    Main:
     Pause 20
    Goto Main
     
    ' ---------- Interrupt handler ------------
    TimezUp:
      T1CON.0 = 0                             ' Stop TMR1
      TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
      TMRCopy.LowByte = TMR1L 
      TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
      TMR1H = TMRCOPY.HighByte                ' And back to TMR1
      TMR1L = TMRCopy.LowByte
      T1CON.0 = 1                             ' Restart Timer
    Toggle PortB.3
     
    @ INT_RETURN
    Excuse me, I thought that your code was destinated for the DT template, I'm quite lost in reality.
    I will try this tonight.

  19. #19


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    I've tested your code, and the results are quite encouraging.

    Some tests I've done :
    INTF=38000 Output=56Hz
    INTF=35000 Output=51.6Hz
    INTF=30000 Output=44.3Hz
    For each, INTF/Output=678, so it's "linear" now.

    But when the interrupt frequency is above ~39060Hz, the ReloadTimer jumps from ~62975 to ~63405 ! Of course, the sines jumps ~10Hz upper.

    Code:
    ' PIC initialization
    DEFINE OSC 40      
    DEFINE LCD_DREG PORTC
    DEFINE LCD_EREG PORTD
    DEFINE LCD_RSREG PORTD
    DEFINE LCD_EBIT 0
    DEFINE LCD_RSBIT 1
    DEFINE LCD_COMMANDUS 4000
    DEFINE LCD_DATAUS 1000
    
    
    ' BAS includes
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "Sine_table.bas"
    
    
    ' Port registers configuration
    TRISB=%11000000   ' PWM 0,1,2,3,4,5 outputs
    TRISC=%00110000   ' +/- buttons
    
    
    ' PCPWM registers configuration
    DTCON=%110        ' Deadtime (600ns)
    PTCON0=%0         ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
    PTCON1=%10000000  ' PWM time base is ON, counts up, 19.45kHz/4
    PWMCON0=%1000000  ' PWM 0,1,2,3,4,5 set in pair mode
    PWMCON1=%1        ' PWM timer sync configuration
    
    
    ' PWM calculation variables
    ustep var byte
    vstep var byte
    wstep var byte
    uduty var word
    vduty var word
    wduty var word
    amplitude var word
    carrier VAR word
    flag var bit
    
    
    ' Variables definition
    ustep=90          ' 360 degrees phase angle
    vstep=60          ' 240 degrees phase angle
    wstep=30          ' 120 degrees phase angle
    amplitude=65535   ' Sinewave amplitude adjust (65535=max amplitude)
    carrier=1023      ' Carrier frequency adjust (1023=13kHz)
    flag=0           ' Menu flag
    
    
    ' PWM carrier frequency register configuration
    PTPERL=carrier.lowbyte  
    PTPERH=carrier.highbyte
    
    
    InterruptFrequency VAR WORD
    Dummy VAR WORD
    Dummy2 VAR WORD
    Dummy3 VAR WORD
    TMRCopy VAR WORD
    TimerReloadValue VAR WORD
    InterruptFrequency = 38000
    
    
    ' Interrupt processors 
    ASM
    INT_LIST macro
    INT_Handler TMR1_INT,_pwmint,PBP,yes
    endm
    INT_CREATE       
    ENDASM
    
    
    ' Interrupts enable
    @INT_ENABLE TMR1_INT
    T1CON.0=1
    
    recalc:
    Dummy2 = 10000
    Dummy3 = 10000
    Dummy = Dummy2 * Dummy3
    TimerReloadValue = Div32 InterruptFrequency
    TimerReloadValue = 65535 - TimerReloadValue  + 1
    
    ' Main program loop
    mainlp:
    
    flag=0
    LCDOUT $FE,2,"F: ", #InterruptFrequency
    lcdout $FE, $C0," R: ", #TimerReloadValue
    if PORTC.4=1 then InterruptFrequency=InterruptFrequency-1 : flag=1
    if PORTC.5=1 then InterruptFrequency=InterruptFrequency+1 : flag=1
    if flag=1 then goto recalc
    
    goto mainlp
    
    
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
    
    T1CON.0 = 0                             ' Stop TMR1
    TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
    TMRCopy.LowByte = TMR1L 
    TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
    TMR1H = TMRCOPY.HighByte                ' And back to TMR1
    TMR1L = TMRCopy.LowByte
    T1CON.0 = 1                             ' Restart Timer
    
    ' PWM U phase calculation
    uduty=sine[ustep]
    uduty=uduty<<4**amplitude
    
    ' PWM V phase calculation
    vduty=sine[vstep]
    vduty=vduty<<4**amplitude
    
    ' PWM W phase calculation
    wduty=sine[wstep]
    wduty=wduty<<4**amplitude
    
    ' PWM U, V and W update
    PDC0L=uduty.lowbyte
    PDC0H=uduty.highbyte
    PDC1L=vduty.lowbyte
    PDC1H=vduty.highbyte
    PDC2L=wduty.lowbyte
    PDC2H=wduty.highbyte
    
    ' Phase angle calculation
    ustep=ustep-1
    vstep=vstep-1
    wstep=wstep-1
    
    ' Phase angle reinitialization
    if ustep=0 then ustep=90
    if vstep=0 then vstep=90
    if wstep=0 then wstep=90
    
    @INT_RETURN
    Last edited by pxidr84; - 8th March 2011 at 21:03.

  20. #20
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,610


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Hi,
    Interrupt frequency of 39060Hz?

    Previously you said you wanted an output of 120Hz and with 72 steps per sin-cycle that's 120*72=8640Hz interrupt frequency. The math is then like this

    65535 - (10,000,000 / 8640) + 1 = 64378

    64378 is what the timer reload value is and this means that there's 65536-64378=1158 cycles between interrupts. 1158 cycles times 100ns per cycle equals 115.8us between interrupts 1/115.8us = 8635Hz so it's pretty close.

    This means that there's only 1158 cycles (or instructions if you will) between interrupts. In this time the PIC has to save all the PBP system variables, reload the timer, execute your interrupt service routine and then restore all the PBP system variables.

    Why are you trying to interrupt at ~39kHz? That's only about 256 cycles between interrupts which I'm pretty sure won't be enough time to do all that needs to get done in the interrupt.

    Finally, this line:
    Code:
    If PortC.4 = 1 Then InterruptFrequency = InterruptFrequency -1 : Flag = 1
    Probably doesn't work like you think. Here, Flag gets set no matter what the state of of PortC.4 actually is. So you are always running the recalc routine. If you want Flag to be set only when PortC.4 is high you need to change it to:
    Code:
    If PortC.4 = 1 THEN
      InterruptFrequency = InterruptFrequency - 1
      Flag = 1
    ENDIF

  21. #21


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    Interrupt frequency of 39060Hz?

    Previously you said you wanted an output of 120Hz and with 72 steps per sin-cycle that's 120*72=8640Hz interrupt frequency. The math is then like this

    65535 - (10,000,000 / 8640) + 1 = 64378

    64378 is what the timer reload value is and this means that there's 65536-64378=1158 cycles between interrupts. 1158 cycles times 100ns per cycle equals 115.8us between interrupts 1/115.8us = 8635Hz so it's pretty close.

    This means that there's only 1158 cycles (or instructions if you will) between interrupts. In this time the PIC has to save all the PBP system variables, reload the timer, execute your interrupt service routine and then restore all the PBP system variables.

    Why are you trying to interrupt at ~39kHz? That's only about 256 cycles between interrupts which I'm pretty sure won't be enough time to do all that needs to get done in the interrupt.

    Finally, this line:
    Code:
    If PortC.4 = 1 Then InterruptFrequency = InterruptFrequency -1 : Flag = 1
    Probably doesn't work like you think. Here, Flag gets set no matter what the state of of PortC.4 actually is. So you are always running the recalc routine. If you want Flag to be set only when PortC.4 is high you need to change it to:
    Code:
    If PortC.4 = 1 THEN
      InterruptFrequency = InterruptFrequency - 1
      Flag = 1
    ENDIF
    Well, for 120Hz, I need an interrupt frequency of 120*90=10800Hz.
    If I configure this in my program, I get output sines of only ~16Hz.

    So what's wrong?

    The code :
    Code:
    ' PIC initialization
    DEFINE OSC 40      
    DEFINE LCD_DREG PORTC
    DEFINE LCD_EREG PORTD
    DEFINE LCD_RSREG PORTD
    DEFINE LCD_EBIT 0
    DEFINE LCD_RSBIT 1
    DEFINE LCD_COMMANDUS 4000
    DEFINE LCD_DATAUS 1000
    
    
    ' BAS includes
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "Sine_table.bas"
    
    
    ' Port registers configuration
    TRISB=%11000000   ' PWM 0,1,2,3,4,5 outputs
    TRISC=%00110000   ' +/- buttons
    
    
    ' PCPWM registers configuration
    DTCON=%110        ' Deadtime (600ns)
    PTCON0=%0         ' 1:1 postscale, Fosc/4 1:1 prescale, free running mode
    PTCON1=%10000000  ' PWM time base is ON, counts up, 19.45kHz/4
    PWMCON0=%1000000  ' PWM 0,1,2,3,4,5 set in pair mode
    PWMCON1=%1        ' PWM timer sync configuration
    
    
    ' PWM calculation variables
    ustep var byte
    vstep var byte
    wstep var byte
    uduty var word
    vduty var word
    wduty var word
    amplitude var word
    carrier VAR word
    flag var bit
    Dummy VAR WORD
    Dummy2 VAR WORD
    Dummy3 VAR WORD
    InterruptFrequency VAR WORD
    TMRCopy VAR WORD
    TimerReloadValue VAR WORD
    
    
    ' Variables definition
    ustep=90          ' 360 degrees phase angle
    vstep=60          ' 240 degrees phase angle
    wstep=30          ' 120 degrees phase angle
    amplitude=65535   ' Sinewave amplitude adjust (65535=max amplitude)
    carrier=1023      ' Carrier frequency adjust (1023=13kHz)
    flag=0           ' Menu flag
    Dummy2 = 10000
    Dummy3 = 10000
    InterruptFrequency = 10800
    
    
    ' PWM carrier frequency register configuration
    PTPERL=carrier.lowbyte  
    PTPERH=carrier.highbyte
    
    
    ' Interrupt processors 
    ASM
    INT_LIST macro
    INT_Handler TMR1_INT,_pwmint,PBP,yes
    endm
    INT_CREATE       
    ENDASM
    
    
    ' Interrupts enable
    @INT_ENABLE TMR1_INT
    T1CON.0=1
    
    recalc:
    Dummy = Dummy2 * Dummy3
    TimerReloadValue = Div32 InterruptFrequency
    TimerReloadValue = 65535 - TimerReloadValue  + 1
    flag=0
    
    
    ' Main program loop
    mainlp:
    
    LCDOUT $FE,2,"F: ",#InterruptFrequency
    lcdout $FE,$C0,"R: ",#TimerReloadValue
    if PORTC.4=1 then 
    InterruptFrequency=InterruptFrequency-1 
    flag=1
    ENDIF
    if PORTC.5=1 then 
    InterruptFrequency=InterruptFrequency+1
    flag=1
    ENDIF
    
    if flag=1 then goto recalc
    
    goto mainlp
    
    
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
    
    T1CON.0 = 0                             ' Stop TMR1
    TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
    TMRCopy.LowByte = TMR1L 
    TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
    TMR1H = TMRCOPY.HighByte                ' And back to TMR1
    TMR1L = TMRCopy.LowByte
    T1CON.0 = 1                             ' Restart Timer
    
    ' PWM U phase calculation
    uduty=sine[ustep]
    uduty=uduty<<4**amplitude
    
    ' PWM V phase calculation
    vduty=sine[vstep]
    vduty=vduty<<4**amplitude
    
    ' PWM W phase calculation
    wduty=sine[wstep]
    wduty=wduty<<4**amplitude
    
    ' PWM U, V and W update
    PDC0L=uduty.lowbyte
    PDC0H=uduty.highbyte
    PDC1L=vduty.lowbyte
    PDC1H=vduty.highbyte
    PDC2L=wduty.lowbyte
    PDC2H=wduty.highbyte
    
    ' Phase angle calculation
    ustep=ustep-1
    vstep=vstep-1
    wstep=wstep-1
    
    ' Phase angle reinitialization
    if ustep=0 then ustep=90
    if vstep=0 then vstep=90
    if wstep=0 then wstep=90
    
    @INT_RETURN
    The "flag" problem is corrected now, I can change frequency during runtime.

    And there is my sine table (if needed) :
    Code:
    ' Sine table (4 degrees/step, 90*4=360 degrees)
    sine var byte[90]
    sine[1]=128
    sine[2]=137
    sine[3]=146
    sine[4]=155
    sine[5]=163
    sine[6]=172
    sine[7]=180
    sine[8]=188
    sine[9]=196
    sine[10]=203
    sine[11]=210
    sine[12]=217
    sine[13]=223
    sine[14]=229
    sine[15]=234
    sine[16]=239
    sine[17]=243
    sine[18]=247
    sine[19]=250
    sine[20]=252
    sine[21]=254
    sine[22]=255
    sine[23]=255
    sine[24]=255
    sine[25]=255
    sine[26]=254
    sine[27]=252
    sine[28]=250
    sine[29]=247
    sine[30]=243
    sine[31]=239
    sine[32]=234
    sine[33]=229
    sine[34]=223
    sine[35]=217
    sine[36]=210
    sine[37]=203
    sine[38]=196
    sine[39]=188
    sine[40]=180
    sine[41]=172
    sine[42]=163
    sine[43]=155
    sine[44]=146
    sine[45]=137
    sine[46]=128
    sine[47]=119
    sine[48]=110
    sine[49]=101
    sine[50]=93
    sine[51]=84
    sine[52]=76
    sine[53]=68
    sine[54]=60
    sine[55]=53
    sine[56]=46
    sine[57]=39
    sine[58]=33
    sine[59]=27
    sine[60]=22
    sine[61]=17
    sine[62]=13
    sine[63]=9
    sine[64]=6
    sine[65]=4
    sine[66]=2
    sine[67]=1
    sine[68]=0
    sine[69]=0
    sine[70]=1
    sine[71]=2
    sine[72]=4
    sine[73]=6
    sine[74]=9
    sine[75]=13
    sine[76]=17
    sine[77]=22
    sine[78]=27
    sine[79]=33
    sine[80]=39
    sine[81]=46
    sine[82]=53
    sine[83]=60
    sine[84]=68
    sine[85]=76
    sine[86]=84
    sine[87]=93
    sine[88]=101
    sine[89]=110
    sine[90]=119
    Last edited by pxidr84; - 9th March 2011 at 15:57.

  22. #22
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,610


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Hi,
    OK, I don't know from where I got that you had 72 steps in the lookup table. Now I know it's 90. If can live with fewer steps you'll be able to increase the output frequency.

    I'm pretty sure you're simply running out of time. I made some quick tests here but in order to do so I had to change your code a little bit (don't have 4431 handy to test on). So I'm not sure exactly how much we can depend on these.

    I'm using a 18F4520 @20Mhz.

    The interrupt routine itself runs in about 70us, the overhead introduced by the interrupt system (DT-ints) is from previous tests I've done about 29us (again at 20Mhz) at interrupt entry and I would guess about the same on exit. This means each interrupt takes a total of ~130us.

    1/0.000130 = 7700Hz

    I've verified this by specifying InterruptFrequency of 7700Hz and it works, I get 7700 Hz with nice, steady pulses. If I specify 8500Hz I can see on the scope that the trace is starting to get jittery indicating that it's starting to overrun it self, missing pulses so think I'm pretty close to the absolute max at 7500-8000Hz.

    Now, in theory, since you're running at 40MHz you should be able to get twice that, ~15kHz but apparently you're not. Can you set a pin high at the beginning of the interrupt service routine and set it low just before @INT_RETURN, then measure how long that output is high. That will tell you the execution time of the actual handler (where I got 70us).

    Are you sure that the PIC is running at 40Mhz? Simply specifying DEFINE OSC40 doesn't make it run at 40MHZ, you need to enable the PLL thru the CONFIG bits as well.

    /Henrik.

  23. #23


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    OK, I don't know from where I got that you had 72 steps in the lookup table. Now I know it's 90. If can live with fewer steps you'll be able to increase the output frequency.

    I'm pretty sure you're simply running out of time. I made some quick tests here but in order to do so I had to change your code a little bit (don't have 4431 handy to test on). So I'm not sure exactly how much we can depend on these.

    I'm using a 18F4520 @20Mhz.

    The interrupt routine itself runs in about 70us, the overhead introduced by the interrupt system (DT-ints) is from previous tests I've done about 29us (again at 20Mhz) at interrupt entry and I would guess about the same on exit. This means each interrupt takes a total of ~130us.

    1/0.000130 = 7700Hz

    I've verified this by specifying InterruptFrequency of 7700Hz and it works, I get 7700 Hz with nice, steady pulses. If I specify 8500Hz I can see on the scope that the trace is starting to get jittery indicating that it's starting to overrun it self, missing pulses so think I'm pretty close to the absolute max at 7500-8000Hz.

    Now, in theory, since you're running at 40MHz you should be able to get twice that, ~15kHz but apparently you're not. Can you set a pin high at the beginning of the interrupt service routine and set it low just before @INT_RETURN, then measure how long that output is high. That will tell you the execution time of the actual handler (where I got 70us).

    Are you sure that the PIC is running at 40Mhz? Simply specifying DEFINE OSC40 doesn't make it run at 40MHZ, you need to enable the PLL thru the CONFIG bits as well.

    /Henrik.
    With this :
    Code:
    ' PWM calculation and update interrupt (Timer 1) 
    pwmint:
    
    T1CON.0 = 0                             ' Stop TMR1
    TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
    TMRCopy.LowByte = TMR1L 
    TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
    TMR1H = TMRCOPY.HighByte                ' And back to TMR1
    TMR1L = TMRCopy.LowByte
    T1CON.0 = 1                             ' Restart Timer
    
    TOGGLE PORTD.7
    
    @INT_RETURN
    And a interrupt freq of 10800Hz, I get an output square wave of 720Hz on the oscilloscope.

    Here is my config bits in MPLAB :


    Note I'm using the HS oscillator with PLL enabled. My crystal (40MHz) is connected between OSC1 and OSC2 pins, with 2*47pF ceramic capacitors. On the oscilloscope, it's okay, I can see the oscillation.
    Last edited by pxidr84; - 9th March 2011 at 18:08.

  24. #24
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,610


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Hi,
    Something must be wrong with your setup. I tried the same ISR as your one, with InterruptFrequency = 10800:
    Code:
    ' ---------- Interrupt handler ------------
    TimezUp:
    PortB.3 = 1
      T1CON.0 = 0                             ' Stop TMR1
      TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
      TMRCopy.LowByte = TMR1L 
      TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
      TMR1H = TMRCOPY.HighByte                ' And back to TMR1
      TMR1L = TMRCopy.LowByte
      T1CON.0 = 1                             ' Restart Timer
    PortB.3 = 0
    @ INT_RETURN
    And I get ~10500Hz even when running at 20Mhz. Here you can see that I, instead of using TOGGLE set the output high at the entry point and low at the exit which allows me to measure the execution time of the code in between. This exact code executes in ~3us on this 18F4520 running at 20MHz, if you try the same on yours it should be 1.5us - if it's not then you're not running at 40MHz.

    You say you have a 40MHz x-tal, is that really correct? To run at 40MHz with the PLL you should use a 10MHz x-tal.

    Try the above, what's the pulsewidth on the output? If it's not 1.5us you're not running at 40MHz.

    /Henrik.

  25. #25


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Quote Originally Posted by HenrikOlsson View Post
    Hi,
    Something must be wrong with your setup. I tried the same ISR as your one, with InterruptFrequency = 10800:
    Code:
    ' ---------- Interrupt handler ------------
    TimezUp:
    PortB.3 = 1
      T1CON.0 = 0                             ' Stop TMR1
      TMRCopy.HighByte = TMR1H                ' Copy value of TMR1 registers
      TMRCopy.LowByte = TMR1L 
      TMRCopy = TMRCopy + TimerReloadValue    ' Add reload value (compensates for overhead)
      TMR1H = TMRCOPY.HighByte                ' And back to TMR1
      TMR1L = TMRCopy.LowByte
      T1CON.0 = 1                             ' Restart Timer
    PortB.3 = 0
    @ INT_RETURN
    And I get ~10500Hz even when running at 20Mhz. Here you can see that I, instead of using TOGGLE set the output high at the entry point and low at the exit which allows me to measure the execution time of the code in between. This exact code executes in ~3us on this 18F4520 running at 20MHz, if you try the same on yours it should be 1.5us - if it's not then you're not running at 40MHz.

    You say you have a 40MHz x-tal, is that really correct? To run at 40MHz with the PLL you should use a 10MHz x-tal.

    Try the above, what's the pulsewidth on the output? If it's not 1.5us you're not running at 40MHz.

    /Henrik.
    With your exact code (the same you're using) and a INTF of 10800Hz, I get 2,76ms between each pulse. Very weird, and very slow. I've disabled the PLL, the oscilator is configured as a HS oscillator.

  26. #26
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,610


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Hi,
    1) What's the width of the pulses? Not the time between them but the width?
    2) What's the value stamped on your x-tal?
    3) The timing calculations that I provided are based on the fact that your chip is SUPPOSED to run at 40MHz, if it's not running at 40MHz then the timing will be wrong and the interrupt frequency will wrong as well.
    4) Please don't quote the complete message you're responding to. It clutters the thread and it gets hard read because everything is quoted all the time - that's my personal view.

  27. #27


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    The pulses are very very thin :



    The width of a pulse is 4,4µs.

    Of course the crystal is stamped at 40MHz, I've difficulties with the setup of this timer, but I hope I'm not an idiot

    The circuit :


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


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Of course the crystal is stamped at 40MHz
    Well, then that is likely the problem - or one of them... If you look at page 355 in the datasheet you'll see that the maximum x-tal frequency WITHOUT PLL is 25 MHz and with using the PLL it's 10MHz (resulting in 40Mhz). You're trying to use 40Mhz which is out of specs in both cases.

    The fact that your pulses are 4.4us wide while mine are 3us means that your chip is running way SLOWER than mine while in fact it "should" be running twice as fast.

    Get the oscillator sorted and verify that the PIC is running at the speed you think. One way to do that is a simple program like:
    Code:
    DEFINE OSC 20    'Don't forget to DEFINE the correct OSC speed.
    TRISB.0 = 0
    Main:
      PortB.0 = 1
      Pause 1
      PortB.0 = 0
      Pause 1
    Goto Main.
    If you DON't get a 500Hz signal with 1ms wide pulses the chip isn't running at the correct and/or DEFINE'd oscillator speed.

  29. #29


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Okay, sincelery I'm quite new with the PICs, so I doesn't know this "problem" (in reality is not a problem).

    I'll try to find a slower crystal tomorrow.

  30. #30


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Okay, so I've unsoldered an 8MHz xtal (not an 10MHz unfortunately) on a old board, and I connected this one to the PIC.
    I've enabled the PLL, so my PIC clocks at 8*4=32MHz.

    On the oscilloscope, I get now a 2µs pulse, it's a little better.

  31. #31
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,610


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Now it seems to run properly - finally.

    In order to make the calculations of the preload value match your new (32MHz) oscillator speed you need to change the Dummy2 value from 10000 to 8000.

    Then keep the same test code in the interrupt service routine and try with InterruptFrequency = 10800, check the scope, there should now be pulses at 10800 or likely a little bit slower.

    The reason it's not 10800 exactly is, again, due to time that the timer is actually stopped while reloading it. To tune it simply tweak the +1 in the following line:
    Code:
    TimerReload = 65535 - TimerReload + 1
    Try +12 or something and see what happens.

    Then try adding code to your interrupt, not all at once, add it in little by little and keep an eye on the scope. If you start to see jitter or "missed" pulses then you're "overloading" the PIC - ie interrupting to fast. Keep the code in the ISR as tight and short and possible. Think thru it, is there any other way to achive this or that to make this execute faster. Every cycle counts here. Verify with the scope, the pulsewidth shows the execution time of the ISR.

    Trying to make a 3-phase inverter when you're new to PICs are quite a challange - as you probably/hopefully know by now - take baby steps.

  32. #32


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Hurray, now I got something who works flawlessly.

    I've played with the dummy values (Dummy2=8745 and Dummy3=100), now I get the exact sines I want.

    For 1200 for example (120*10=120.0Hz), I get 120Hz, for 500 (50*10=50.0Hz) I get 50Hz, for 357 (35.7*10=35.7Hz) I get 35.7Hz...

    So now it works, I can go ahead in my project.

    Thanks a lot Henrik for your help and your support.

  33. #33
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,610


    Did you find this post helpful? Yes | No

    Default Re: Changing the sines frequency?

    Great!

    I have no idea why you changed the Dummy2 and Dummy3 variables as you did (8750 and 100 (?) ) But then again, as long as it works for you....

    Good luck with the rest of the project!

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