Elapsed timer not working as expected at 64MHz
+ Reply to Thread
Page 1 of 2 12 LastLast
Results 1 to 40 of 62
  1. #1
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Elapsed timer not working as expected at 64MHz

    Has anyone else had problems using DT's Elapsed Timer at 64MHz?


    When I run a 18F44K22 at 64MHz, 99 TICKS = .247 second.

    Name:  Saleae 99 TICKS 64MHz.PNG
Views: 274
Size:  23.3 KB


    When I run at 16MHz, 99 TICKS = .988 second.

    Name:  Saleae 99 TICKS 16MHz.PNG
Views: 265
Size:  35.2 KB


    It's as if the timer runs at a default 16MHz when the PIC is at 64MHz (exactly 1/4 speed).
    Not as dumb as yesterday, but stupider than tomorrow!

  2. #2
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working at 64MHz

    When I look at Elapsed Timer include, Darryl has adjusted it to run at any oscillator frequency.

    Code:
    '***************************************************************************
    '*  Name    : Elapsed_INT-18.bas                                           *
    '*  Author  : Darrel Taylor                                                *
    '*  Date    : JUL 11, 2006 : 7/11/2010                                     *
    '*  Version : 1.2                                                          *
    '*  Notes   : Must have DT_INTS-18.bas loaded first                        *
    '*   ver 1.2: Now works at any OSC frequency without using the prescaler   *
    '***************************************************************************
    DISABLE DEBUG
    
    ; syntax =     Handler  IntSource,        Label, Type, ResetFlag?
    DEFINE  Elapsed_Handler  TMR1_INT,  _ClockCount,  asm,  yes
    ; the above define can be used in the INT_LIST macro, if desired (optional)
    
    Ticks            VAR BYTE   ; Counts timer Overflows
    T1Post           VAR BYTE   ; Timer1 postscaler
    Seconds          VAR BYTE
    Minutes          VAR BYTE
    Hours            VAR BYTE
    Days             VAR WORD
    
    SecondsChanged   VAR BIT    ; idicates that the value has changed
    MinutesChanged   VAR BIT
    HoursChanged     VAR BIT
    DaysChanged      VAR BIT
    
    GOSUB ResetTime             ; initialize the Elapsed Timer
    
    Goto OverElapsed            ; skip over the routines
    
    ' -------------- calc timer reload Constants -------------------------------
    ASM
    T1PS = 1                             ; start with 1:1 postscaler
    TimerConst = ((OSC*1000000)/4/100)   ; how many timer ticks will it take
      while TimerConst > 65400           ; if it's more than the timer can count
    T1PS = T1PS * 2                      ;   double the postscaler
    TimerConst = TimerConst / 2          ;   halve the count
      endw
    TimerConst = 65536 - TimerConst + 8  ; final reload value
      
      
    ; -----------------  ADD TimerConst to TMR1H:TMR1L -------------------------
    ADD2_TIMER   macro
        BCF     T1CON,TMR1ON, 0       ;  1 Turn off timer
        MOVLW   LOW(TimerConst)       ;  1
        ADDWF   TMR1L,F, 0            ;  1    
        BTFSC   STATUS,C              ;  1/2
        INCF    TMR1H,F, 0            ;  1
        MOVLW   HIGH(TimerConst)      ;  1
        ADDWF   TMR1H,F, 0            ;  1
        endm
    
    ; -----------------  ADD TimerConst to TMR1H:TMR1L and restart TIMER1 ------
    RELOAD_TIMER  macro
        ADD2_TIMER
        BSF     T1CON,TMR1ON, 0       ;  1   Turn TIMER1 back on  (8 cycles)
        endm
    
    ; -----------------  Load TimerConst into TMR1H:TMR1L ----------------------
    LOAD_TIMER  macro
        MOVE?CT  0, T1CON,TMR1ON
        MOVE?CB  0, TMR1L
        MOVE?CB  0, TMR1H
        ADD2_TIMER
        endm
    ENDASM
    
    ' ------[ This is the Interrupt Handler ]-----------------------------------
    T1PS  CON EXT
    ClockCount:
    @ RELOAD_TIMER                   ; Reload TIMER1
        Ticks = Ticks + 1
        IF Ticks = 100 THEN
           Ticks = 0
           T1Post = T1Post + 1
           IF T1Post = T1PS THEN
               T1Post = 0
               Seconds = Seconds + 1
               SecondsChanged = 1
               IF Seconds = 60 THEN
                  Seconds = 0
                  Minutes = Minutes + 1
                  MinutesChanged = 1
               ENDIF
               IF Minutes = 60 THEN
                  Minutes = 0
                  Hours = Hours + 1
                  HoursChanged = 1
               ENDIF
               IF Hours = 24 THEN
                  Days = Days + 1
                  DaysChanged = 1
                  Hours = 0
               ENDIF
           ENDIF
        ENDIF
    @ INT_RETURN                     ; Restore context and return from interrupt
    
    '-----====[ END OF TMR1 Interrupt Handler ]====-----------------------------
    
    StartTimer:
        T1CON = 1                    ; 1:1, FOSC4, TMR1ON
    RETURN
    
    ; --------------------------------------------------------------------------
    StopTimer:
        T1CON.0 = 0                  ; Turn OFF Timer1
    RETURN
    
    ; --------------------------------------------------------------------------
    BitSave  VAR  BIT
    
    ResetTime:
        BitSave = T1CON.0            ; Save TMR1ON bit
    @   LOAD_TIMER                   ; Load TimerConst
        T1CON.0 = BitSave            ; Restore TMR1ON bit
        T1Post = 0                   ; clear the postscaler
        Ticks = 0
        Seconds = 0
        Minutes = 0
        Hours = 0
        Days = 0
        SecondsChanged = 1           ; indicate everything has changed
        MinutesChanged = 1           ; so that 00:00:00 is processed
        HoursChanged = 1
        DaysChanged = 1
    RETURN
    
    
    OverElapsed:
    ENABLE DEBUG
    The only thing that caught my eye was the TimerConst calculation. At 64MHz it is 160,000 on the first loop, well beyond the range of a WORD variable.

    I don't have LONGs enabled right now. I can't seem to find the definition for TimerConst to see if it's a WORD or LONG.

    It should be a WORD 'cause he ends up moving the high and low bytes.
    Not as dumb as yesterday, but stupider than tomorrow!

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,243

    Default Re: Elapsed timer not working at 64MHz

    Hi Robert,
    The first piece of code is executed by the assembler at the time the code is built. It doesn't execute when the PIC actually runs so there's no WORD size limit at play as far as I know.

    The second piece you've marked in red is of course run time code but by the TimerConst should be less than 65400 so no problem.

    With that said something is apparently not working as expected. Darrels code, relies on you having DEFINE OSC xx correctly. It's easy enough to have a 16MHz clock with the corresponding DEFINE and then enable the PLL to get 64MHz but forget to change to DEFINE OSC 64.

    /Henrik.

  4. #4
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working at 64MHz

    I bet this is my Saleae probe biting me in the nose again; not being able to run it fast enough.

    The interrupt is working faster, I'm probably missing signals.

    Name:  Saleae 64MHz VS 16MHz.PNG
Views: 158
Size:  34.7 KB

    EDIT: And I notice I didn't align the marker the same way on Probe 1 - Port = 1 / 0, but it's the same interval as described in the WIDTH; 0.250uS, I just rechecked.


    Code:
    asm
    ; __CONFIG    _CONFIG1H, _FOSC_INTIO67_1H & _PLLCFG_OFF_1H & _PRICLKEN_OFF_1H & _FCMEN_ON_1H & _IESO_OFF_1H
     __CONFIG    _CONFIG1H, _FOSC_INTIO67_1H & _PLLCFG_ON_1H & _PRICLKEN_OFF_1H & _FCMEN_ON_1H & _IESO_OFF_1H
     __CONFIG    _CONFIG2L, _PWRTEN_ON_2L & _BOREN_SBORDIS_2L & _BORV_285_2L
     __CONFIG    _CONFIG2H, _WDTEN_OFF_2H
     __CONFIG    _CONFIG3H, _CCP2MX_PORTC1_3H & _PBADEN_OFF_3H & _CCP3MX_PORTE0_3H & _HFOFST_OFF_3H & _T3CMX_PORTB5_3H & _P2BMX_PORTC0_3H & _MCLRE_EXTMCLR_3H
     __CONFIG    _CONFIG4L, _STVREN_OFF_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
    endasm
    
    ;DEFINE OSC 16
    ;OSCTUNE = %10000000
    
    DEFINE OSC 64
    OSCTUNE = %11000000
    
    OSCCON  = %01110000
    OSCCON2 = %00000100
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "ReEnterPBP-18LP.bas"
    INCLUDE "Elapsed_INT-18.bas"
    ASM
    INT_LIST  macro    ; IntSource,        Label,           Type,   ResetFlag?
    ;        INT_Handler    RX1_INT,    _RX1Interrupt,    PBP,    yes
        endm
        INT_CREATE                  ; Creates the interrupt processor
    INT_LIST_L  macro  ; IntSource,        Label,           Type,   ResetFlag?
            INT_Handler   TMR1_INT,   _ClockCount,   PBP,  yes
        endm
        INT_CREATE_L                ; Creates the Low Priority interrupt processor
    ENDASM
    ANSELA = %00000000
    ANSELB = %00000000
    ANSELC = %00000000
    ANSELD = %00000000
    ANSELE = %00000000
    ADCON0 = %00000000
    PMD0 = %10111110
    PMD1 = %11011111
    PMD2 = %00001111
    DEFINE USE_LOWPRIORITY 1
    TRISA = %00000000
    TRISB = %00000000
    TRISC = %00000000
    TRISD = %00000000
    TRISE = %00000000
    PORTA = %00000000
    PORTB = %00000000
    PORTC = %00000000
    PORTD = %00000000
    PORTE = %00000000
        pause 100
    @ INT_ENABLE  TMR1_INT                  ; enable Timer 1 interrupts
        GOSUB ResetTime                     ' Reset Time to  0d-00:00:00.00
    MainProgram:
    
        PortD.2 = 1
    
        if T1CON.0 = 0 then
            GOSUB StartTimer                    ' Start the Elapsed Timer
            PortD.3 = 1
        endif
    
        PortD.2 = 0
    
        if ticks = 25 then
            PortD.3 = 0
            GOSUB StopTimer                    ' Stop the Elapsed Timer
            GOSUB ResetTime                     ' Reset Time to  0d-00:00:00.00
        endif
    
        goto MainProgram
    end

    Switch bouncing becomes much more pronounced at 64MHz. I think I'm going to change approach and go the long way and use just a 0.1uF ceramic cap on each pin (I remember that helped somewhat on previous tests).

    Master PIC @ 64MHz
    LED Slave PIC @ 64MHz
    Keypad Slave PIC at 16MHz

    I start DT Timer on a keypress and ignore inputs during that interval. I just have to make tests to see how fast I can press the same button and tweak the delay.

    I wanted to handle both the LEDs and Keypad on the same PIC, but it'll be a lot easier and reliable to just split them up.
    Last edited by Demon; - 22nd December 2014 at 21:05.
    Not as dumb as yesterday, but stupider than tomorrow!

  5. #5
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working at 64MHz

    So I minimized the code:

    Code:
    asm
     __CONFIG    _CONFIG1H, _FOSC_INTIO67_1H & _PLLCFG_ON_1H & _PRICLKEN_OFF_1H & _FCMEN_ON_1H & _IESO_OFF_1H
     __CONFIG    _CONFIG2L, _PWRTEN_ON_2L & _BOREN_SBORDIS_2L & _BORV_285_2L
     __CONFIG    _CONFIG2H, _WDTEN_OFF_2H
     __CONFIG    _CONFIG3H, _CCP2MX_PORTC1_3H & _PBADEN_OFF_3H & _CCP3MX_PORTE0_3H & _HFOFST_OFF_3H & _T3CMX_PORTB5_3H & _P2BMX_PORTC0_3H & _MCLRE_EXTMCLR_3H
     __CONFIG    _CONFIG4L, _STVREN_OFF_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
    endasm
    
    DEFINE OSC 16
    OSCCON  = %01010000
    '     R/W       111 = HFINTOSC – (16 MHz)
    '               110 = HFINTOSC/2 – (8 MHz)
    '               101 = HFINTOSC/4 – (4 MHz)
    
    OSCTUNE = %11000000
    OSCCON2 = %00000100
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"
    INCLUDE "Elapsed_INT-18.bas"
    ASM
    INT_LIST  macro    ; IntSource,        Label,           Type,   ResetFlag?
            INT_Handler   TMR1_INT,   _ClockCount,   PBP,  yes
        endm
        INT_CREATE
    ENDASM
    ANSELA = %00000000
    ANSELB = %00000000
    ANSELC = %00000000
    ANSELD = %00000000
    ANSELE = %00000000
    ADCON0 = %00000000
    TRISA = %00000000
    TRISB = %00000000
    TRISC = %00000000
    TRISD = %00000000
    TRISE = %00000000
    PORTA = %00000000
    PORTB = %00000000
    PORTC = %00000000
    PORTD = %00000000
    PORTE = %00000000
        pause 100
    @ INT_ENABLE  TMR1_INT 
        GOSUB ResetTime
    MainProgram:
    
        if T1CON.0 = 0 then
            PortD.3 = 1
            GOSUB StartTimer
        endif
    
        if ticks = 5 then
            PortD.3 = 0
            GOSUB StopTimer                    ' Stop the Elapsed Timer
            GOSUB ResetTime                     ' Reset Time to  0d-00:00:00.00
        endif
    
        goto MainProgram
    end
    5 TICK Timer

    OSC 16MHz (4MHz+PLL) 50ms
    OSC 32MHz (8MHz+PLL) 25ms
    OSC 64MHz (16MHz+PLL) 12.5ms

    I can't help but feel I'm doing something wrong, it's just too proportional a variance. If the Saleae probe would miss pulses, there wouldn't be a regular pattern.
    Not as dumb as yesterday, but stupider than tomorrow!

  6. #6
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    debug T1PS and TimerConst to see what's going on would be a good start

  7. #7
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Roger, oveur.
    Not as dumb as yesterday, but stupider than tomorrow!

  8. #8
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    765

    Default Re: Elapsed timer not working as expected at 64MHz

    tips value will be 4 at 64mhz , i played a lot with this elasped timer code , for up down timer

  9. #9
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    765

    Default Re: Elapsed timer not working as expected at 64MHz

    for 64mhz
    each tick should be 2.5ms , to confirm the internal osc trim i enable a i/o pin to check its pulse per tick rate , it not the best way but it showed me that the most the time the internal osc needed some adj to ensure that it was as close as possable to 2.5ms

    here is a snip of modifed code for the timer, i left the asm as it stands, but cos i wanted the 100th sec reading and the same structure of code , i changed / removed the t1post varable and used the MOD



    Code:
    EL_Ticks = EL_Ticks  + 1    ; each tick is 2.5ms 
     '    IF LATG.0 = 0 THEN           ' debug 
     '        LATG.0 = 1
     '    ELSE 
     '        LATG.0 = 0
     '    ENDIF   
      if EL_ticks // T1PS = 0  THEN      ' if modulas of tips (4) = 0 
         '    IF LATG.0 = 0 THEN           ' debug 
         '       LATG.0 = 1
         '    ELSE 
         '       LATG.0 = 0
         '    ENDIF   
              EL_100th = EL_100th + 1 
              EL_100thChanged = 1
              IF EL_100TH  = 100 THEN
                  EL_100TH = 0
                  EL_Seconds = EL_Seconds + 1      
                  EL_SecondsChanged = 1
                  IF EL_Seconds = 60 THEN
                     EL_Seconds = 0
                     EL_Minutes = EL_Minutes + 1
                     EL_MinutesChanged = 1
                  eNDIF
                  IF EL_Minutes = 60 THEN
                     EL_Minutes = 0
                     EL_Hours = EL_Hours + 1
                     EL_HoursChanged = 1
                  ENDIF
                  IF EL_Hours = 24 THEN
                     EL_Hours = 0 
                     EL_Days = EL_Days + 1
                     EL_DaysChanged = 1
                  ENDIF
              eNDIF
          endif

  10. #10
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    765

    Default Re: Elapsed timer not working as expected at 64MHz

    each 100th is 10ms on the i/o debug section btw

  11. #11
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    765

    Default Re: Elapsed timer not working as expected at 64MHz

    Code:
    OSCTUNE = %01000111     ' Bit 7  - INTSRC - internal LF Source Select 1 = 31.25 from 16Mhz Internal /512 HF-INTOSC ) 0 = Internal 31khz OSC 
                                ' Bit 6 - PLLEN - 1 PLL enabled  , 0 = PLL disabled 
                                ' Bits 5-0 Frequancy callibaration 00000 = centre Frq   - FREQ ADJ = 5-7  ( the higher the number the slower the osc timing )

  12. #12
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Quote Originally Posted by richard View Post
    debug T1PS and TimerConst to see what's going on would be a good start
    I started by making my version of the Elapsed include and adding 2 variables at the end of the timer calc:
    Code:
    ...
    ' -------------- calc timer reload Constants -------------------------------
    ASM
    T1PS = 1                             ; start with 1:1 postscaler
    TimerConst = ((OSC*1000000)/4/100)   ; how many timer ticks will it take
      while TimerConst > 65400           ; if it's more than the timer can count
    T1PS = T1PS * 2                      ;   double the postscaler
    TimerConst = TimerConst / 2          ;   halve the count
      endw
    TimerConst = 65536 - TimerConst + 8  ; final reload value
    ; ---------------------------- DEBUG SCALER --------------------------------
    DebugT1PS = T1PS
    DebugTC = TimerConst
    ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ...
    Before Main of my program I added:
    Code:
    DebugT1PS CON EXT
    DebugTC   CON EXT
    Right now I'm wiring up a LCD to display the 2 variables.

    Am I on the right track to look at them?

    I've never tried to display something from inside Darryl's includes before. My plan was to copy them into 2 words and then displaying the lower and upper bytes on the LCD.
    Not as dumb as yesterday, but stupider than tomorrow!

  13. #13
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    Am I on the right track to look at them?
    probably not if yours fails try this

    Code:
    DISABLE DEBUG
    
    ; syntax =     Handler  IntSource,        Label, Type, ResetFlag?
    DEFINE  Elapsed_Handler  TMR1_INT,  _ClockCount,  asm,  yes
    ; the above define can be used in the INT_LIST macro, if desired (optional)
    
    Ticks            VAR BYTE   ; Counts timer Overflows
    T1Post           VAR BYTE   ; Timer1 postscaler
    Seconds          VAR BYTE
    Minutes          VAR BYTE
    Hours            VAR BYTE
    Days             VAR WORD
    DebugT1PS     var byte
    DebugTCL       var byte 
    DebugTCh       var byte 
    
    SecondsChanged   VAR BIT    ; idicates that the value has changed
    MinutesChanged   VAR BIT
    HoursChanged     VAR BIT
    DaysChanged      VAR BIT
    
    GOSUB ResetTime             ; initialize the Elapsed Timer
    
    Goto OverElapsed            ; skip over the routines
    
    ' -------------- calc timer reload Constants -------------------------------
    ASM
    T1PS = 1                             ; start with 1:1 postscaler
    TimerConst = ((OSC*1000000)/4/100)   ; how many timer ticks will it take
      while TimerConst > 65400           ; if it's more than the timer can count
    T1PS = T1PS * 2                      ;   double the postscaler
    TimerConst = TimerConst / 2          ;   halve the count
      endw
    TimerConst = 65536 - TimerConst + 8  ; final reload value
     _DebugT1PS =T1PS
     _DebugTCH=TimerConst /256 
     _DebugTCL = TimerConst - _DebugTCH*256
    
    ; -----------------  ADD TimerConst to TMR1H:TMR1L -------------------------
    ADD2_TIMER   macro

  14. #14
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Actually, it worked.

    I deleted my debug include 'cause I can work without it.

    Code:
    ...
    ;T1PS        CON EXT    ' Already defined in include
    TimerConst  CON EXT
    
    varT1PS   var word
    varTC     var word
        varT1PS = T1PS
        varTC   = TimerConst
        
        Lcdout $fe, 1, "Timer 1"
        Lcdout $fe, $94, "PS:", BIN8 varT1PS.byte1, " ", BIN8 varT1PS.byte0
        Lcdout $fe, $D4, "TC:", BIN8 varTC.byte1, " ", BIN8 varTC.byte0
    
    MainProgram:
    And I get:
    PS:00000000 00000001
    TC:01100011 11001000 <--- Dec=25544

    EDIT: Woooops, still using OSC 16, BRB.
    Not as dumb as yesterday, but stupider than tomorrow!

  15. #15
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    OSC 64 (16 + PLL)

    PS:00000000 00000100 <--- Dec=4
    TC:01100011 11001000 <--- Dec=25544

    I had same results manually this afternoon.

    Robert
    Not as dumb as yesterday, but stupider than tomorrow!

  16. #16
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    ok next whats in T1CON ?

  17. #17
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Looking at the datasheet for 18F44K22, timer 1 has a 2 bit prescaler.

    4 (100) takes 3 bits.

    Gonna try timer 2.

    ...
    13.0 TIMER2/4/6 MODULE p.175
    ...
    • 8-bit Timer and Period registers (TMRx and PRx,
    respectively)
    • Readable and writable (both registers)
    • Software programmable prescaler (1:1, 1:4, 1:16)
    • Software programmable postscaler (1:1 to 1:16)
    ...

    EDIT: Darn, DT Elapsed include only has Timer1...

    Robert
    Last edited by Demon; - 23rd December 2014 at 03:31.
    Not as dumb as yesterday, but stupider than tomorrow!

  18. #18
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Was looking at T1CON register and noticed this:

    TxCKPS<1:0>: Timer1/3/5 Input Clock Prescale Select bits
    11 = 1:8 Prescale value
    10 = 1:4 Prescale value
    01 = 1:2 Prescale value
    00 = 1:1 Prescale value
    So that is 2 bits.


    Code:
    bit 7-6 TMRxCS<1:0>: Timer1/3/5 Clock Source Select bits
      11 =Reserved. Do not use.
      10 =Timer1/3/5 clock source is pin or oscillator:
        If TxSOSCEN = 0:
          External clock from TxCKI pin (on the rising edge)
        If TxSOSCEN = 1:
          Crystal oscillator on SOSCI/SOSCO pins
      01 =Timer1/3/5 clock source is system clock (FOSC)
      00 =Timer1/3/5 clock source is instruction clock (FOSC/4)
    
    bit 5-4 TxCKPS<1:0>: Timer1/3/5 Input Clock Prescale Select bits
      11 = 1:8 Prescale value
      10 = 1:4 Prescale value
      01 = 1:2 Prescale value
      00 = 1:1 Prescale value
    
    bit 3 TxSOSCEN: Secondary Oscillator Enable Control bit
      1 = Dedicated Secondary oscillator circuit enabled
      0 = Dedicated Secondary oscillator circuit disabled
    
    bit 2 TxSYNC: Timer1/3/5 External Clock Input Synchronization Control bit
        TMRxCS<1:0> = 1X
      1 = Do not synchronize external clock input
      0 = Synchronize external clock input with system clock (FOSC)
        TMRxCS<1:0> = 0X
      This bit is ignored. Timer1/3/5 uses the internal clock when TMRxCS<1:0> = 1X.
    
    bit 1 TxRD16: 16-Bit Read/Write Mode Enable bit
      1 = Enables register read/write of Timer1/3/5 in one 16-bit operation
      0 = Enables register read/write of Timer1/3/5 in two 8-bit operation
    
    bit 0 TMRxON: Timer1/3/5 On bit
      1 = Enables Timer1/3/5
      0 = Stops Timer1/3/5
        Clears Timer1/3/5 Gate flip-flop
    T1CON=00000000

    Robert
    Last edited by Demon; - 23rd December 2014 at 03:42.
    Not as dumb as yesterday, but stupider than tomorrow!

  19. #19
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    ITS NOT using the prescaler those bits need to be 00 ie 1:1
    @64mhz with a preload of 25544 you get a tmr1 int every 2.5mS dt's int routine inc's the tips counter till its 4 then inc's the elapsed time clock I count ie once every 10mS

    next step after confirming t1con is ok is to toggle a pin in the int routine as per what Sheldon suggested and verify 2.5mS ints are occurring

  20. #20
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    In the Elapsed include:

    Code:
    ...
    ' -------------- calc timer reload Constants -------------------------------
    ASM
    T1PS = 1                             ; start with 1:1 postscaler
    TimerConst = ((OSC*1000000)/4/100)   ; how many timer ticks will it take
      while TimerConst > 65400           ; if it's more than the timer can count
    T1PS = T1PS * 2                      ;   double the postscaler
    TimerConst = TimerConst / 2          ;   halve the count
      endw
    TimerConst = 65536 - TimerConst + 8  ; final reload value
    ...
    Darryl talks about a post-scaler. Timers 1, 3 and 5 have none for a 18F44K22?

    Neither does Timer 0, only Timers 2,4 and 6 have pre and post-scalers.

    Robert
    Not as dumb as yesterday, but stupider than tomorrow!

  21. #21
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    t1con looks good should be 0 or 1 (on or off) depending on what the int routine is up to

  22. #22
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    Darryl talks about a post-scaler. Timers 1, 3 and 5 have none for a 18F44K22?

    Neither does Timer 0, only Timers 2,4 and 6 have pre and post-scalers
    hence the T1PS VAR

  23. #23
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    765

    Default Re: Elapsed timer not working as expected at 64MHz

    for DT's elasped timer , i dont setup timer 1 at all

    Code:
     'Note:  Programming the T1GCON prior to T1CON is recommended
        T1GCON = %00000000     ' Timer 1 Gate Control bit7 0= counts regardless of gate 1 = gates in use  , bit6 gate active when 1= High  ,0=low
                               ' bit5 0= toggle mode diabled 1= enabled  bit4 single pulse mode 1- en 0= dis, bit 2 -status bit,1-0 - gate source sel
                  ' 1
        T1CON  = %00000000     ' Timer 1 ,bit7-6 = TMR1 CLK source 00 = Instuction Clk(Fosc/4),01 =sys clk,10=ext clk,11=cap sense osc
                               ' bit5-4 = TMR1 prescale 00= 1:1 ,bit3=0 LP off,bit2=1 no sync ext CLK ,bit1= 0 n/a,Bit0=0 Timer 1 on/off
      
        TMR1H = 0              ' CLEAR TMR1H MODULE REGISTER
        TMR1L = 0              ' CLEAR TMR1L MODULE REGISTER

  24. #24
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    I just noticed dt's ass code makes it impossible to stuff the t1con up it sets it to 0 anyway no matter what you may try to set it to . but worth checking anyway I suppose

  25. #25
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Quote Originally Posted by longpole001 View Post
    each 100th is 10ms on the i/o debug section btw
    My output pin changes state every 2.5ms at 64MHz.

    Code:
    '***************************************************************************
    '*  Name    : Elapsed_INT-18.bas                                           *
    '*  Author  : Darrel Taylor                                                *
    '*  Date    : JUL 11, 2006 : 7/11/2010                                     *
    '*  Version : 1.2                                                          *
    '*  Notes   : Must have DT_INTS-18.bas loaded first                        *
    '*   ver 1.2: Now works at any OSC frequency without using the prescaler   *
    '***************************************************************************
    DISABLE DEBUG
    
    ; syntax =     Handler  IntSource,        Label, Type, ResetFlag?
    DEFINE  Elapsed_Handler  TMR1_INT,  _ClockCount,  asm,  yes
    ; the above define can be used in the INT_LIST macro, if desired (optional)
    
    EL_Ticks            VAR BYTE   ; Counts timer Overflows
    EL_100th            VAR BYTE
    ;T1Post           VAR BYTE   ; Timer1 postscaler
    EL_Seconds          VAR BYTE
    EL_Minutes          VAR BYTE
    EL_Hours            VAR BYTE
    EL_Days             VAR WORD
    
    EL_100thChanged     VAR BIT
    EL_SecondsChanged   VAR BIT    ; idicates that the value has changed
    EL_MinutesChanged   VAR BIT
    EL_HoursChanged     VAR BIT
    EL_DaysChanged      VAR BIT
    
    GOSUB ResetTime             ; initialize the Elapsed Timer
    
    Goto OverElapsed            ; skip over the routines
    
    ' -------------- calc timer reload Constants -------------------------------
    ASM
    T1PS = 1                             ; start with 1:1 postscaler
    TimerConst = ((OSC*1000000)/4/100)   ; how many timer ticks will it take
      while TimerConst > 65400           ; if it's more than the timer can count
    T1PS = T1PS * 2                      ;   double the postscaler
    TimerConst = TimerConst / 2          ;   halve the count
      endw
    TimerConst = 65536 - TimerConst + 8  ; final reload value
      
      
    ; -----------------  ADD TimerConst to TMR1H:TMR1L -------------------------
    ADD2_TIMER   macro
        BCF     T1CON,TMR1ON, 0       ;  1 Turn off timer
        MOVLW   LOW(TimerConst)       ;  1
        ADDWF   TMR1L,F, 0            ;  1    
        BTFSC   STATUS,C              ;  1/2
        INCF    TMR1H,F, 0            ;  1
        MOVLW   HIGH(TimerConst)      ;  1
        ADDWF   TMR1H,F, 0            ;  1
        endm
    
    ; -----------------  ADD TimerConst to TMR1H:TMR1L and restart TIMER1 ------
    RELOAD_TIMER  macro
        ADD2_TIMER
        BSF     T1CON,TMR1ON, 0       ;  1   Turn TIMER1 back on  (8 cycles)
        endm
    
    ; -----------------  Load TimerConst into TMR1H:TMR1L ----------------------
    LOAD_TIMER  macro
        MOVE?CT  0, T1CON,TMR1ON
        MOVE?CB  0, TMR1L
        MOVE?CB  0, TMR1H
        ADD2_TIMER
        endm
    ENDASM
    
    ' ------[ This is the Interrupt Handler ]-----------------------------------
    T1PS  CON EXT
    ClockCount:
    @ RELOAD_TIMER                   ; Reload TIMER1
    EL_Ticks = EL_Ticks  + 1    ; each tick is 2.5ms 
           IF LATD.3 = 0 THEN           ' debug 
              LATD.3 = 1
           ELSE 
              LATD.3 = 0
           ENDIF   
      if EL_ticks // T1PS = 0  THEN      ' if modulas of tips (4) = 0 
           IF LATD.3 = 0 THEN           ' debug 
              LATD.3 = 1
           ELSE 
              LATD.3 = 0
           ENDIF   
              EL_100th = EL_100th + 1 
              EL_100thChanged = 1
              IF EL_100TH  = 100 THEN
                  EL_100TH = 0
                  EL_Seconds = EL_Seconds + 1      
                  EL_SecondsChanged = 1
                  IF EL_Seconds = 60 THEN
                     EL_Seconds = 0
                     EL_Minutes = EL_Minutes + 1
                     EL_MinutesChanged = 1
                  eNDIF
                  IF EL_Minutes = 60 THEN
                     EL_Minutes = 0
                     EL_Hours = EL_Hours + 1
                     EL_HoursChanged = 1
                  ENDIF
                  IF EL_Hours = 24 THEN
                     EL_Hours = 0 
                     EL_Days = EL_Days + 1
                     EL_DaysChanged = 1
                  ENDIF
              eNDIF
          endif
    '    Ticks = Ticks + 1
    '    IF Ticks = 100 THEN
    '       Ticks = 0
    '       T1Post = T1Post + 1
    '       IF T1Post = T1PS THEN
    '           T1Post = 0
    '           Seconds = Seconds + 1
    '           SecondsChanged = 1
    '           IF Seconds = 60 THEN
    '              Seconds = 0
    '              Minutes = Minutes + 1
    '              MinutesChanged = 1
    '           ENDIF
    '           IF Minutes = 60 THEN
    '              Minutes = 0
    '              Hours = Hours + 1
    '              HoursChanged = 1
    '           ENDIF
    '           IF Hours = 24 THEN
    '              Days = Days + 1
    '              DaysChanged = 1
    '              Hours = 0
    '           ENDIF
    '       ENDIF
    '    ENDIF
    @ INT_RETURN                     ; Restore context and return from interrupt
    
    '-----====[ END OF TMR1 Interrupt Handler ]====-----------------------------
    
    StartTimer:
        T1CON = 1                    ; 1:1, FOSC4, TMR1ON
    RETURN
    
    ; --------------------------------------------------------------------------
    StopTimer:
        T1CON.0 = 0                  ; Turn OFF Timer1
    RETURN
    
    ; --------------------------------------------------------------------------
    BitSave  VAR  BIT
    
    ResetTime:
        BitSave = T1CON.0            ; Save TMR1ON bit
    @   LOAD_TIMER                   ; Load TimerConst
        T1CON.0 = BitSave            ; Restore TMR1ON bit
    ;    T1Post = 0                   ; clear the postscaler
        EL_Ticks = 0
        EL_100th = 0
        EL_Seconds = 0
        EL_Minutes = 0
        EL_Hours = 0
        EL_Days = 0
        EL_100thChanged = 1
        EL_SecondsChanged = 1           ; indicate everything has changed
        EL_MinutesChanged = 1           ; so that 00:00:00 is processed
        EL_HoursChanged = 1
        EL_DaysChanged = 1
    RETURN
    
    
    OverElapsed:
    ENABLE DEBUG
    Not as dumb as yesterday, but stupider than tomorrow!

  26. #26
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Quote Originally Posted by longpole001 View Post
    each 100th is 10ms on the i/o debug section btw
    My output pin changes state every 2.5ms at 64MHz.

    Code:
    '***************************************************************************
    '*  Name    : Elapsed_INT-18.bas                                           *
    '*  Author  : Darrel Taylor                                                *
    '*  Date    : JUL 11, 2006 : 7/11/2010                                     *
    '*  Version : 1.2                                                          *
    '*  Notes   : Must have DT_INTS-18.bas loaded first                        *
    '*   ver 1.2: Now works at any OSC frequency without using the prescaler   *
    '***************************************************************************
    DISABLE DEBUG
    
    ; syntax =     Handler  IntSource,        Label, Type, ResetFlag?
    DEFINE  Elapsed_Handler  TMR1_INT,  _ClockCount,  asm,  yes
    ; the above define can be used in the INT_LIST macro, if desired (optional)
    
    EL_Ticks            VAR BYTE   ; Counts timer Overflows
    EL_100th            VAR BYTE
    ;T1Post           VAR BYTE   ; Timer1 postscaler
    EL_Seconds          VAR BYTE
    EL_Minutes          VAR BYTE
    EL_Hours            VAR BYTE
    EL_Days             VAR WORD
    
    EL_100thChanged     VAR BIT
    EL_SecondsChanged   VAR BIT    ; idicates that the value has changed
    EL_MinutesChanged   VAR BIT
    EL_HoursChanged     VAR BIT
    EL_DaysChanged      VAR BIT
    
    GOSUB ResetTime             ; initialize the Elapsed Timer
    
    Goto OverElapsed            ; skip over the routines
    
    ' -------------- calc timer reload Constants -------------------------------
    ASM
    T1PS = 1                             ; start with 1:1 postscaler
    TimerConst = ((OSC*1000000)/4/100)   ; how many timer ticks will it take
      while TimerConst > 65400           ; if it's more than the timer can count
    T1PS = T1PS * 2                      ;   double the postscaler
    TimerConst = TimerConst / 2          ;   halve the count
      endw
    TimerConst = 65536 - TimerConst + 8  ; final reload value
      
      
    ; -----------------  ADD TimerConst to TMR1H:TMR1L -------------------------
    ADD2_TIMER   macro
        BCF     T1CON,TMR1ON, 0       ;  1 Turn off timer
        MOVLW   LOW(TimerConst)       ;  1
        ADDWF   TMR1L,F, 0            ;  1    
        BTFSC   STATUS,C              ;  1/2
        INCF    TMR1H,F, 0            ;  1
        MOVLW   HIGH(TimerConst)      ;  1
        ADDWF   TMR1H,F, 0            ;  1
        endm
    
    ; -----------------  ADD TimerConst to TMR1H:TMR1L and restart TIMER1 ------
    RELOAD_TIMER  macro
        ADD2_TIMER
        BSF     T1CON,TMR1ON, 0       ;  1   Turn TIMER1 back on  (8 cycles)
        endm
    
    ; -----------------  Load TimerConst into TMR1H:TMR1L ----------------------
    LOAD_TIMER  macro
        MOVE?CT  0, T1CON,TMR1ON
        MOVE?CB  0, TMR1L
        MOVE?CB  0, TMR1H
        ADD2_TIMER
        endm
    ENDASM
    
    ' ------[ This is the Interrupt Handler ]-----------------------------------
    T1PS  CON EXT
    ClockCount:
    @ RELOAD_TIMER                   ; Reload TIMER1
    EL_Ticks = EL_Ticks  + 1    ; each tick is 2.5ms 
           IF LATD.3 = 0 THEN           ' debug 
              LATD.3 = 1
           ELSE 
              LATD.3 = 0
           ENDIF   
      if EL_ticks // T1PS = 0  THEN      ' if modulas of tips (4) = 0 
           IF LATD.3 = 0 THEN           ' debug 
              LATD.3 = 1
           ELSE 
              LATD.3 = 0
           ENDIF   
              EL_100th = EL_100th + 1 
              EL_100thChanged = 1
              IF EL_100TH  = 100 THEN
                  EL_100TH = 0
                  EL_Seconds = EL_Seconds + 1      
                  EL_SecondsChanged = 1
                  IF EL_Seconds = 60 THEN
                     EL_Seconds = 0
                     EL_Minutes = EL_Minutes + 1
                     EL_MinutesChanged = 1
                  eNDIF
                  IF EL_Minutes = 60 THEN
                     EL_Minutes = 0
                     EL_Hours = EL_Hours + 1
                     EL_HoursChanged = 1
                  ENDIF
                  IF EL_Hours = 24 THEN
                     EL_Hours = 0 
                     EL_Days = EL_Days + 1
                     EL_DaysChanged = 1
                  ENDIF
              eNDIF
          endif
    '    Ticks = Ticks + 1
    '    IF Ticks = 100 THEN
    '       Ticks = 0
    '       T1Post = T1Post + 1
    '       IF T1Post = T1PS THEN
    '           T1Post = 0
    '           Seconds = Seconds + 1
    '           SecondsChanged = 1
    '           IF Seconds = 60 THEN
    '              Seconds = 0
    '              Minutes = Minutes + 1
    '              MinutesChanged = 1
    '           ENDIF
    '           IF Minutes = 60 THEN
    '              Minutes = 0
    '              Hours = Hours + 1
    '              HoursChanged = 1
    '           ENDIF
    '           IF Hours = 24 THEN
    '              Days = Days + 1
    '              DaysChanged = 1
    '              Hours = 0
    '           ENDIF
    '       ENDIF
    '    ENDIF
    @ INT_RETURN                     ; Restore context and return from interrupt
    
    '-----====[ END OF TMR1 Interrupt Handler ]====-----------------------------
    
    StartTimer:
        T1CON = 1                    ; 1:1, FOSC4, TMR1ON
    RETURN
    
    ; --------------------------------------------------------------------------
    StopTimer:
        T1CON.0 = 0                  ; Turn OFF Timer1
    RETURN
    
    ; --------------------------------------------------------------------------
    BitSave  VAR  BIT
    
    ResetTime:
        BitSave = T1CON.0            ; Save TMR1ON bit
    @   LOAD_TIMER                   ; Load TimerConst
        T1CON.0 = BitSave            ; Restore TMR1ON bit
    ;    T1Post = 0                   ; clear the postscaler
        EL_Ticks = 0
        EL_100th = 0
        EL_Seconds = 0
        EL_Minutes = 0
        EL_Hours = 0
        EL_Days = 0
        EL_100thChanged = 1
        EL_SecondsChanged = 1           ; indicate everything has changed
        EL_MinutesChanged = 1           ; so that 00:00:00 is processed
        EL_HoursChanged = 1
        EL_DaysChanged = 1
    RETURN
    
    
    OverElapsed:
    ENABLE DEBUG
    Not as dumb as yesterday, but stupider than tomorrow!

  27. #27
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Yes, I'm an idiot.

    T1CON becomes 00000001 once it is STARTED! D'OH!
    Not as dumb as yesterday, but stupider than tomorrow!

  28. #28
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Sheldon,

    It's not perfect, I'm missing some pulses on the Saleae probe, but it's sticking to a 2.5ms tick as you describe in your Elapsed include comment.

    Name:  Saleae 64MHz 2-5ms.PNG
Views: 119
Size:  27.7 KB

    EDIT: I just noticed that the skipped pulse happens at every 4 ticks.

    And that skipped pulse is between 20-21uS.


    EDIT SOME MORE: Got it, it's that 2nd LED toggle. I commented it out and now I have a regular 2.5ms pulse.

    Robert
    Last edited by Demon; - 23rd December 2014 at 04:43.
    Not as dumb as yesterday, but stupider than tomorrow!

  29. #29
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Quote Originally Posted by longpole001 View Post
    each 100th is 10ms on the i/o debug section btw
    Yup, I get 10ms if I comment out the 1st LED toggle.

    Attachment 7542

    I understand quickly as long as you explain 10 times.

    Robert
    Not as dumb as yesterday, but stupider than tomorrow!

  30. #30
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Well that toggle from Sheldon confirms DT's is not working perfectly at 64MHz.

    I get 2.5ms on each LED toggle.

    Code:
    T1PS  CON EXT
    ClockCount:
    @ RELOAD_TIMER                   ; Reload TIMER1
        Ticks = Ticks + 1
           IF LATD.3 = 0 THEN           ' debug 
              LATD.3 = 1
           ELSE 
              LATD.3 = 0
           ENDIF   
        IF Ticks = 100 THEN
           Ticks = 0
           T1Post = T1Post + 1
           IF T1Post = T1PS THEN
               T1Post = 0
               Seconds = Seconds + 1
               SecondsChanged = 1
               IF Seconds = 60 THEN
                  Seconds = 0
                  Minutes = Minutes + 1
                  MinutesChanged = 1
               ENDIF
               IF Minutes = 60 THEN
                  Minutes = 0
                  Hours = Hours + 1
                  HoursChanged = 1
               ENDIF
               IF Hours = 24 THEN
                  Days = Days + 1
                  DaysChanged = 1
                  Hours = 0
               ENDIF
           ENDIF
        ENDIF
    @ INT_RETURN                     ; Restore context and return from interrupt
    Thanks a lot Sheldon for having figured this one out.

    Robert



    GAAAAA must not click on MeProg PROGRAM icon when I want to click on POST, it won't work.
    Not as dumb as yesterday, but stupider than tomorrow!

  31. #31
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    now I'm confused
    Well that toggle from Sheldon confirms DT's is not working perfectly at 64MHz.
    or
    Well that toggle from Sheldon confirms DT's is working perfectly at 64MHz.

    ps
    IF LATD.3 = 0 THEN ' debug
    LATD.3 = 1
    ELSE
    LATD.3 = 0
    ENDIF
    can be replaced with

    latd.3=!latd.3

    lets not have too much unnecessary overhead in the interrupt
    Last edited by richard; - 23rd December 2014 at 05:20.

  32. #32
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Quote Originally Posted by richard View Post
    now I'm confused

    or
    Well that toggle from Sheldon confirms DT's is working perfectly at 64MHz.
    DT's Elapsed include doesn't work perfectly at 64MHz (1 tick = 2.5ms), Sheldon's modified version does (1/100th = 10ms). Sheldon has added a new variable. I'm cleaning up the new include now to put it on the forum, somewhere.

    Robert
    Not as dumb as yesterday, but stupider than tomorrow!

  33. #33
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    New version of Darrel Taylor's Elapsed include for 64MHz:

    Code:
    '***************************************************************************
    '*  Name    : Elapsed_INT-18.bas                                           *
    '*  Author  : Darrel Taylor                                                *
    '*  Date    : JUL 11, 2006 : 7/11/2010 : Dec 23, 2014                      *
    '*  Version : 1.3                                                          *
    '*  Notes   : Must have DT_INTS-18.bas loaded first                        *
    '*   ver 1.2: Now works at any OSC frequency without using the prescaler   *
    '*   ver 1.3: will work with 64MHz thanks to Sheldon                       *
    '*            New field ONEHUNDRETH is now used instead of TICKS           *
    '***************************************************************************
    DISABLE DEBUG
    
    ; syntax =     Handler  IntSource,        Label, Type, ResetFlag?
    DEFINE  Elapsed_Handler  TMR1_INT,  _ClockCount,  asm,  yes
    ; the above define can be used in the INT_LIST macro, if desired (optional)
    
    Ticks            VAR BYTE   ; Counts timer Overflows
    OneHundreth      VAR BYTE    ; New field for 64MHz
    ;T1Post           VAR BYTE   ; Timer1 postscaler
    Seconds          VAR BYTE
    Minutes          VAR BYTE
    Hours            VAR BYTE
    Days             VAR WORD
    
    OneHundrethChanged     VAR BIT    ; New field for 64MHz
    SecondsChanged   VAR BIT    ; idicates that the value has changed
    MinutesChanged   VAR BIT
    HoursChanged     VAR BIT
    DaysChanged      VAR BIT
    
    GOSUB ResetTime             ; initialize the Elapsed Timer
    
    Goto OverElapsed            ; skip over the routines
    
    ' -------------- calc timer reload Constants -------------------------------
    ASM
    T1PS = 1                             ; start with 1:1 postscaler
    TimerConst = ((OSC*1000000)/4/100)   ; how many timer ticks will it take
      while TimerConst > 65400           ; if it's more than the timer can count
    T1PS = T1PS * 2                      ;   double the postscaler
    TimerConst = TimerConst / 2          ;   halve the count
      endw
    TimerConst = 65536 - TimerConst + 8  ; final reload value
      
      
    ; -----------------  ADD TimerConst to TMR1H:TMR1L -------------------------
    ADD2_TIMER   macro
        BCF     T1CON,TMR1ON, 0       ;  1 Turn off timer
        MOVLW   LOW(TimerConst)       ;  1
        ADDWF   TMR1L,F, 0            ;  1    
        BTFSC   STATUS,C              ;  1/2
        INCF    TMR1H,F, 0            ;  1
        MOVLW   HIGH(TimerConst)      ;  1
        ADDWF   TMR1H,F, 0            ;  1
        endm
    
    ; -----------------  ADD TimerConst to TMR1H:TMR1L and restart TIMER1 ------
    RELOAD_TIMER  macro
        ADD2_TIMER
        BSF     T1CON,TMR1ON, 0       ;  1   Turn TIMER1 back on  (8 cycles)
        endm
    
    ; -----------------  Load TimerConst into TMR1H:TMR1L ----------------------
    LOAD_TIMER  macro
        MOVE?CT  0, T1CON,TMR1ON
        MOVE?CB  0, TMR1L
        MOVE?CB  0, TMR1H
        ADD2_TIMER
        endm
    ENDASM
    
    ' ------[ This is the Interrupt Handler ]-----------------------------------
    T1PS  CON EXT
    ClockCount:
    @ RELOAD_TIMER                   ; Reload TIMER1
    Ticks = Ticks  + 1                      ; each tick is 2.5ms 
    '       IF LATD.3 = 0 THEN                  ' used to debug to confirm 2.5ms
    '          LATD.3 = 1
    '       ELSE 
    '          LATD.3 = 0
    '       ENDIF   
      if ticks // T1PS = 0  THEN      ' if modulas of tips (4) = 0 
    '       IF LATD.3 = 0 THEN                  ' used to debug to confirm 10ms
    '          LATD.3 = 1
    '       ELSE 
    '          LATD.3 = 0
    '       ENDIF   
              OneHundreth = OneHundreth + 1   ; each 1/100th is 10ms
              OneHundrethChanged = 1
              IF OneHundreth  = 100 THEN
                  OneHundreth = 0
    '    Ticks = Ticks + 1
    '    IF Ticks = 100 THEN
    '       Ticks = 0
    '       T1Post = T1Post + 1
    '       IF T1Post = T1PS THEN
    '           T1Post = 0
               Seconds = Seconds + 1
               SecondsChanged = 1
               IF Seconds = 60 THEN
                  Seconds = 0
                  Minutes = Minutes + 1
                  MinutesChanged = 1
               ENDIF
               IF Minutes = 60 THEN
                  Minutes = 0
                  Hours = Hours + 1
                  HoursChanged = 1
               ENDIF
               IF Hours = 24 THEN
                  Days = Days + 1
                  DaysChanged = 1
                  Hours = 0
               ENDIF
           ENDIF
        ENDIF
    @ INT_RETURN                     ; Restore context and return from interrupt
    
    '-----====[ END OF TMR1 Interrupt Handler ]====-----------------------------
    
    StartTimer:
        T1CON = 1                    ; 1:1, FOSC4, TMR1ON
    RETURN
    
    ; --------------------------------------------------------------------------
    StopTimer:
        T1CON.0 = 0                  ; Turn OFF Timer1
    RETURN
    
    ; --------------------------------------------------------------------------
    BitSave  VAR  BIT
    
    ResetTime:
        BitSave = T1CON.0            ; Save TMR1ON bit
    @   LOAD_TIMER                   ; Load TimerConst
        T1CON.0 = BitSave            ; Restore TMR1ON bit
    ;    T1Post = 0                   ; clear the postscaler
        Ticks = 0
        OneHundreth = 0
        Seconds = 0
        Minutes = 0
        Hours = 0
        Days = 0
        OneHundrethChanged = 1
        SecondsChanged = 1           ; indicate everything has changed
        MinutesChanged = 1           ; so that 00:00:00 is processed
        HoursChanged = 1
        DaysChanged = 1
    RETURN
    
    
    OverElapsed:
    ENABLE DEBUG
    New field OneHundreth (10ms) replaces Tick (2.5ms at 64MHz).

    Name:  Saleae 64MHz new.PNG
Views: 116
Size:  22.4 KB

    (Remove .TXT suffix)
    Elapsed_INT-18_64MHz.bas.txt

    Robert
    Not as dumb as yesterday, but stupider than tomorrow!

  34. #34
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    you may like to re-examine that I just tried it on a pic1845k20 @64 MHz and the int is @2.5mS as expected , sheldons mod just adds 100th capability doesn't it ?

    the seconds inc on every 400th interrupt the ticks are not meant to be 10mS
    Last edited by richard; - 23rd December 2014 at 05:57. Reason: better explanition

  35. #35
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    From http://web.archive.org/web/201206151...8/elapsed.html

    The time is kept in the variables:
    --------------------------------------------------------------------------------

    Ticks var byte ' 1/100th of a second
    Seconds var byte ' 0-59
    Minutes var byte ' 0-59
    Hours var byte ' 0-23
    Days var word ' 0-65535
    But a tick is not 2.5ms.

    Robert

  36. #36
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,254

    Default Re: Elapsed timer not working as expected at 64MHz

    Quote Originally Posted by richard View Post
    you may like to re-examine that I just tried it on a pic1845k20 @64 MHz and the int is 2.5mS as expected , sheldons mod just adds 100th doesn't it

    the ticks only inc on every 4th interrupt

    What happens when you start/stop the timer after 5 ticks using the original include?

    I get this using the new include:
    Name:  Saleae 64MHz 5 ticks.PNG
Views: 114
Size:  22.6 KB

    Code:
    MainProgram:
    
        if T1CON.0 = 0 then
            PortD.3 = 1
            GOSUB StartTimer
        endif
    
        if OneHundreth = 5 then
            PortD.3 = 0
            GOSUB StopTimer                    ' Stop the Elapsed Timer
            GOSUB ResetTime                     ' Reset Time to  0d-00:00:00.00
        endif
    
        goto MainProgram
    Robert

  37. #37
    Join Date
    May 2013
    Location
    australia
    Posts
    1,678

    Default Re: Elapsed timer not working as expected at 64MHz

    its a clock not a stopwatch , if you really need to measure wee small times like that there are better ways.
    to get the fractional part of the seconds multiply t1post with ticks and / 4

  38. #38
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    765

    Default Re: Elapsed timer not working as expected at 64MHz

    ticks should be 2.5ms , 1/100 is 4 x tick = 10ms , 1 sec should be 100 x 1/100th or 400 tick = 1sec

  39. #39
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    765

    Default Re: Elapsed timer not working as expected at 64MHz

    i did version of DTs elapsed timer that shown at 1/1000 , assuming it does nothing else in life and you got a good xtl , it work ok up to 12 hours , when i tested it

    also DT had a thing about showing code doing a countdown timer , so i never posted it as per his request

  40. #40
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    765

    Default Re: Elapsed timer not working as expected at 64MHz

    Code:
    EL_Ticks            VAR BYTE      ; Ticks Up Counter  -timer Overflows
    EL_100th            VAR BYTE      ; value for 1/100s
    EL_Seconds          VAR BYTE      ; value for seconds 
    EL_Minutes          VAR byte
    EL_Hours            VAR BYTE
    EL_Days             VAR BYTE

Similar Threads

  1. PORTB.3 Input not working as expected.
    By BobEdge in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 5th March 2013, 09:58
  2. Elapsed Timer Demo
    By Darrel Taylor in forum Code Examples
    Replies: 111
    Last Post: - 29th October 2012, 17:39
  3. SPWM and Elapsed Timer
    By CocaColaKid in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 8th May 2008, 03:16
  4. DT Elapsed Timer
    By rwskinner in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 9th March 2008, 23:17
  5. I2CRead & I2CWrite not working as expected
    By Melanie in forum FAQ - Frequently Asked Questions
    Replies: 4
    Last Post: - 14th April 2007, 17:37

Members who have read this thread : 19

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