Shop OBEX P1 Docs P2 Docs Learn Events
sx52 timers phase — Parallax Forums

sx52 timers phase

Vertex78Vertex78 Posts: 51
edited 2006-11-05 05:57 in General Discussion
I have written a program in asm that creates a square wave on both of the timers. Now I am trying to figure out how to shift one of them so that that one of them is 45' out of phase with the other.


Here is what I have:
    ___     ___     ___     ___
 __|   |___|   |___|   |___|   |__  timer 1

    ___     ___     ___     ___
 __|   |___|   |___|   |___|   |__  timer 2




and this is what I want to do:

    ___     ___     ___     ___
 __|   |___|   |___|   |___|   |__  timer 1

  ___     ___     ___     ___
 |   |___|   |___|   |___|   |__  timer 2




I thought I could accomplish this by setting up both timers then clearing the counter in timer1 so that it starts creating the timer 1 signal. Then have a delay that waits for however long I want to wait before timer 2 starts up, then clearing the counter in timer 2. It seems that this should work but when I tried it and hooked it up to my scope it did not show any phase change. Is there a way to do this in sx/b? If so I could do as Bean suggested in another post of mine about the timers to look at the listing generated by the compiler to see how its done in asm.

Post Edited (Vertex78) : 11/2/2006 7:44:57 PM GMT

Comments

  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2006-11-03 22:41
    Vertex78,

    I thought maybe someone else would jump in here to help you.

    On the surface, what you are trying to accomplish and how you are trying to accomplish it seems quite reasonable to me. However, I should disclose that I have not actually tried to use or even read much about the timers! So I may be of little help. With that word of warning, I am willing explore the timer issue with you if you care to post the code you are trying to use.


    - Sparks
  • Vertex78Vertex78 Posts: 51
    edited 2006-11-04 00:12
    Sure, I welcome the help. This is causing me a big headache trying to figure out!

    ;DEVICE          SX52, OSC4MHZ 
    DEVICE SX52
    IRC_CAL IRC_SLOW
    DEVICE        OSCHS3        ; High-speed external oscillator
    RESET initialize
    FREQ 80_000_000
     
    
    ;**********
    ; EQUATES
    ;**********
    ;timer1
    rT1CPL            EQU        $00
    rT1CPH            EQU        $01
    rT1R2CML        EQU        $02
    rT1R2CMH        EQU        $03
    rT1R1CML        EQU        $04
    rT1R1CMH        EQU        $05
    rT1CNTB            EQU        $06
    rT1CNTA            EQU        $07
    wT1R2CML        EQU        $12
    wT1R2CMH        EQU        $13
    wT1R1CML        EQU        $14
    wT1R1CMH        EQU        $15
    wT1CNTB            EQU        $16
    wT1CNTA            EQU        $17
    
    ;timer2
    rT2CPL            EQU        $00
    rT2CPH            EQU        $01
    rT2R2CML        EQU        $02
    rT2R2CMH        EQU        $03
    rT2R1CML        EQU        $04
    rT2R1CMH        EQU        $05
    rT2CNTB            EQU        $06
    rT2CNTA            EQU        $07
    wT2R2CML        EQU        $12
    wT2R2CMH        EQU        $13
    wT2R1CML        EQU        $14
    wT2R1CMH        EQU        $15
    wT2CNTB            EQU        $16
    wT2CNTA            EQU        $17
    
    FLAG1            EQU        %00001000
    FLAG2            EQU        %00010000
    
    org $0a
    d1    ds    1
    d2     ds    1
    d3     ds    1
    
    org $0
        
        
    isr
    
    
        
    reti
    
    initialize
     
        mov !rb, #%00001111 ;timer 1
        mov !rc, #%11110000 ;timer 2
    
    ;----------------------------------------------------
    ; timer 1 setup
    ;----------------------------------------------------
    
        ;setup for prescale of 1:64 and pwm mode
        mov w,#wT1CNTB ;16
        mov m,w
        mov w,#%00011001
        mov !rb,w
    
        ;setup interrupts(turned off)
        mov w,#wT1CNTA
        mov m,w
        mov w,#%00000000
        mov !rb,w
    
        ;r1
        ;load t1 compare register1 
        mov w,#wT1R1CML ;14h
        mov m,w
        mov w, #96
        mov !rb,w
        mov w,#wT1R1CMH ;15h
        mov m,w
        mov w,#4
        mov !rb,w
    
        ;r2
        ;load t1 compare register2 
        mov w,#wT1R2CML ;12h
        mov m,w
        mov w, #96
        mov !rb,w
        mov w,#wT1R2CMH ;13h
        mov m,w
        mov w,#4
        mov !rb,w
    ;----------------------------------------------------
    ;timer2 setup
    ;----------------------------------------------------
        ;clear timer 2
        mov w,#$10
        mov m,w
        mov !rc,w
    
        ;setup for prescale of 1:64 and pwm mode
        mov w,#wT2CNTB ;16
        mov m,w
        mov w,#%00011001
        mov !rc,w
    
        ;setup interrupts(turned off)
        mov w,#wT2CNTA
        mov m,w
        mov w,#%00000000
        mov !rc,w
    
        ;r1
        ;load t2 compare register1 
        mov w,#wT2R1CML ;14h
        mov m,w
        mov w, #96 
        mov !rc,w
        mov w,#wT2R1CMH ;15h
        mov m,w
        mov w,#4
        mov !rc,w
    
        ;r2
        ;load t2 compare register2 
        mov w,#wT2R2CML ;12h
        mov m,w
        mov w, #96
        mov !rc,w
        mov w,#wT2R2CMH ;13h
        mov m,w
        mov w,#4
        mov !rc,w
        
    ;----------------------------------------------------
    ;clear timers
    ;----------------------------------------------------
        mov w,#$10
        mov m,w
        mov !rb,w
    
        ;delay here to cause timer 2 to be out of phase with timer 1(but does not work for some reason)
        ;14us delay
        mov    w, #$9F
        mov    d1, w
        mov    w, #$01
        mov    d2, w
    Delay_0:
        decsz    d1
        jmp    $+2
        decsz    d2
        jmp    Delay_0
    
                ;6 cycles
        jmp    $+1
        jmp    $+1
        
    
        ;clear timer2
        mov w,#$10
        mov m,w
        mov !rc,w
    
        mov w,#$1f
        mov m,w
    
    main
        
    jmp main
    
    
  • PJMontyPJMonty Posts: 983
    edited 2006-11-04 00:21
    Vertex78,

    If this were my project/problem, I would set up some code that would allow me to turn timer two on and off from an external bit. I would then hook up my o-scope probes to watch as I turned timer two on and off using an external physical switch. I would also slow the clock way down initially so that I would have a better chance of having some meaningful (and random) phase delay when I turned the timer on and off.

    The idea here is to make sure that you are indeed controlling the timers like you think you are. It's possible that there is some other subtle issue going on. If you keep turning timer 2 on and off while observing (and run at a much slower clock), you should be able to see if you are affecting phase like you think you are. If you're not, then there's something wrong with you handling of timer setup and control. If you are, then the problem is likely in your delay function.
      Thanks, PeterM
  • BeanBean Posts: 8,129
    edited 2006-11-04 01:48
    Vertex78,
    · Here it is in SX/B. You might have to tweak the PAUSEUS value to get EXACTLY the phase you want.

    DEVICE SX48, OSCHS3
    FREQ 80_000_000
     
    PWM1 PIN RB.6 OUTPUT
    PWM2 PIN RC.2 OUTPUT
     
    PROGRAM Start
     
    Start:
      TIMER1 PRESCALE, 6 ' 1:64
      TIMER2 PRESCALE, 6 ' 1:64
      TIMER1 PWM, 1120, 2240
      TIMER2 PWM, 1120, 2240
      TIMER1 CLEAR
      PAUSEUS 448
      TIMER2 CLEAR
      END
    

    Bean


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com

    "People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
    792 x 545 - 97K
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2006-11-05 00:05
    Vertex78,

    I studied the SX 48/52 timer information last night. Today I looked at your code and the code Bean posted. (Thanks Bean!)

    Taking the advise of PJMonty (Thanks Peter!) to slow the clock down, I adjusted the timing of the code posted by Bean so that I could Step/Walk through it easily to see what is happening and when. Since I do not have a dual-trace scope, I decided to use LEDs to observe the output. This worked fine since I was manually stepping through the code and not using a free running clock.

    The code that follows is what I used to verify the phase shift between the two timers. (It is Bean's program with timing values that are easy to step though for those without osciloscopes.) You can run the code in the debugger until the breakpoint. Then use the Step/Walk options to observe the timer outputs via two LED's. One should be connected from RB.6 to Vss and the other between RC.2 and Vss. I found that a Walk setting of 3 gives easily observable results.

    ' Demonstrates setting the two SX 48/52 timers 90 degrees out of phase.
    '
    ' Connect one LED between RB.6 and Vss and another between RC.2 and Vss
    ' Observe using the SX-Key in Debug mode.
    ' A Walk setting of 3 gives easily observable results.
    
    DEVICE SX48, OSCHS3
    FREQ 4_000_000
     
    PWM1 PIN RB.6 OUTPUT        ' Setup Timer 1 Output Pin.
    PWM2 PIN RC.2 OUTPUT        ' Setup Timer 2 Output Pin.
    
    
    PROGRAM Start
     
    Start:
      TIMER1 PRESCALE, 0 ' 1:1    ' Selected for easier observation in Debug mode.
      TIMER2 PRESCALE, 0 ' 1:1    ' Selected for easier observation in Debug mode.
    
      TIMER1 PWM, 8, 16        ' 8 Cycles on, 16 cycles total, so 50% duty cycle.
      TIMER2 PWM, 8, 16        ' 8 Cycles on, 16 cycles total, so 50% duty cycle.
    
    BREAK                ' Stop the Debugger.
                    ' Step or Walk through the rest of the code
                    ' from here.
    
      TIMER1 CLEAR                  ' Clearing Timer1 takes three clock cycles.
    
      NOP                ' Do nothing for one clock cycle.
    
                    ' Normally there would be a much longer pause here
                    ' but for the demonstration values given, one cycle
                    ' plus the three required to clear the timer gives
                    ' enough of a pause to introduce a 90 degree phase
                    ' shift with the values being used.
    
      TIMER2 CLEAR                  ' Clearing Timer2 takes three clock cycles.
                    ' (1) NOP + (3) TIMER2 CLEAR = (4) clock cycles
    
                    ' (16) cycles in duration / ( 90 degrees / 360 degrees)
                    ' is (16) / (4) = (4) cycles which is the delay required
                    ' to create the desired phase shift of 90 degrees.
      END
    




    I am still looking at your code trying to figure out what is not right; but I wanted to post an update since I told you I would work on it.


    - Sparks
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2006-11-05 05:57
    Vertex78,

    I checked out your code, line by line. Most of it looks fine to me. I really think it should do what you want... save for the timing. I think the time delay for the phase offset is incorrect.

    Some Data:
    • 80,000,000 Hz = 80,000,000 cycles / sec
    • You are using a 1:64 prescaler. (This means the timers record one count every 64 clock cycles.)
    • The timers are set to count 1120 prescaled cycles, toggle the output, then count another 1120 prescaled cycles before toggling the output and repeating.
    • A complete on/off sequence occurs every 2240 timer counts or (2240 x 64 = 143360 clock cycles)
    Doing some math...
    80,000,000 (clock cycles / sec) * 1/64 (counts / clock cycles) / 2240 (counts) = 558 (1/sec) = 0.001792 sec = 1.792 ms

    Half of that (1.792 ms / 2 = 0.896 ms or 896 uSec) is the duration an output spends being on (or off) during a single cycle. You want to start the second timer halfway through the first half of the first timer cycle. In other words, you want to start the second timer one quarter of the way into the cycle of the first timer. If a full cycle takes 1.792 ms then a quarter of it takes only 1.792 ms / 4 = 448 uSec. I think your delay of 14 uSec is 448 / 14 = 32 times shorter than it ought to be. So you are starting Timer 2 too soon. You need a pause 32 times as great as the one you are using. Therefore the ouputs should have been nearly in phase with Timer 2 being just slightly offset by 1/32 of a complete cycle resulting in a 360 / 32 = 11.25 degree phase shift.

    So, the good news is that I think your code should work just fine. You only need to adjust your time delay!

    One other minor thing that I noticed was that after setting up timer 1, you clear Timer 2. I do not think this is necessary though it should not cause any problems.

    I think that should solve your problem. I learned a lot about the SX 48/52 timers in the process! smile.gif

    - Sparks

    Post Edited (Sparks-R-Fun) : 11/5/2006 2:37:12 PM GMT
Sign In or Register to comment.