Menu

Timer Calculations and More

Help
2016-07-07
2016-07-09
  • William Roth

    William Roth - 2016-07-07

    Maybe we can continue the timer discusion here. I forgot what I posted but this is what I remember.

    The help chart for timer 1 prescales somehow got corrupted but is the same as that for timer3
    Valid Prescales for timer 1 are:

    PS1_0.... No Prescale
    PS1_2... Divide OSC by 2
    PS1_4.... Divide OSC by 4
    PS1_8....Divide OSCby 8

    These are the the ONLY valid prescales. Using any other will give unexpected results.

    OSC ( source) is actually FOSC/4. So for example PS./4 is in effect
    (FOSC/4) x 4.

    For a 20 ms overflow interrupt at 20MHz Clock:

    ( 20000000 /4 ) / 8 = 625000 ... So 1 /. 625000 = 1.8 us per timer tick with a prescale of 8

    20 ms = .020 sec ... So .020 sec / .0000018 sec = 11,111 timer ticks

    65535 - 11111 = 54424 . So your preset value will be 54424 and the interupt wil occur 11,111 ticks later

    Test Code: Modifiy for 16F1825 @ 20Mhz

      #chip 16F1829, 16  '// or 16F1825
    
      Dir PortC.3 out
    
      on interrupt timer1overflow Call ISR1
      inittimer1(OSC,PS1_8)
      Starttimer 1, 55535
      '// Starttimer 1, 54424
    
      Do
          'wait for interrupt
      Loop
    
      SUB ISR1
        settimer 1, 55535
        '// settimer 1, 54424
        pulseout portC.3, 1 ms
      end sub
    
     

    Last edit: William Roth 2016-07-07
  • viscomjim

    viscomjim - 2016-07-08

    Hi William, I downloaded the MikroElektronika timer calculator, which by the way, covers quite a few chips. I entered the 20ms interrupt time for Timer1 (16 bit) for the 16f1825. Here is what it spit out... (Mikro Basic)

    'Timer1
    'Prescaler 1:2; TMR1 Preload = 15536; Actual Interrupt Time : 20 ms
    
    'Place/Copy this part in declaration section
    sub procedure InitTimer1()
      T1CON  = 0x11
      TMR1IF_bit     = 0
      TMR1H  = 0x3C
      TMR1L  = 0xB0
      TMR1IE_bit     = 1
      INTCON     = 0xC0
    end sub
    
    sub procedure Interrupt()
      if (TMR1IF_bit) then
        TMR1IF_bit = 0
        TMR1H    = 0x3C
        TMR1L    = 0xB0
        'Enter your code here
      end if
    end sub
    

    So I see that the T1CON register is loaded with 0x11 which means a 1:2 prescaler. and then 15536 for the preload number. So I did the math like you show...

    20Mhz/4 = 5Mhz
    5Mhz/2 = 2.5Mhz = .0000004 sec. or .4uS

    20ms = .02 / .0000004 = 50000

    65535 - 50000 = 15535 (Mikro came up with 15536???)

    So it seems like depending on the prescaler you could essentially do this preload different ways. My GCB code would look like this...

    ' Initialize Timer1
          InitTimer1(Osc, PS1_2 )  2:1 prescale
          SetTimer( 1, 15535 ) ' Preload Count for 20ms @ 20Mhz
          StartTimer 1
    
          On Interrupt Timer1Overflow Call TimerIntSub
    
          do
          nop
          loop
    
    
    Sub TimerIntSub
    SetTimer(1, 15535) ' reset count for 20ms
    'do stuff
    end sub
    

    Can I assume that GCB clears the Timer1 interrupt flag, or is it necessary to check it like they do in their sub? I only ask because it looks like the code generated by Mikro checks and clears that flag.

    I also noticed on some posts that in the ISR some people put INTOFF in the beginning of the sub and then INTON at the end of the sub. Is this necessary?

    Thank for ALL your help. This is making sense finally and is very useful information!!!! Should be a detailed example or explanation in the help manual.

    P.S. In your example above, you state...

    OSC ( source) is actually FOSC/4. So for example PS./4 is in effect
    (FOSC/4) x 4.

    I think it should read (FOSC/4) / 4????

     

    Last edit: viscomjim 2016-07-08
    • Anobium

      Anobium - 2016-07-09

      My favorite calculator. This shows a lot more of the internals - enjoy.

      This is on the internet. This is not my works.

       

      Last edit: Anobium 2016-07-09
  • Chris Roper

    Chris Roper - 2016-07-08

    I am not William but will attempt an answer.

    “65535 - 50000 = 15535 (Mikro came up with 15536???)”

    The difference of 1 in 65535 is going to be negligible, you will get a far greater shift with changes in temperate, however, you can use an oscilloscope and tune that number to accurately compensate for your particular setup.

    “Can I assume that GCB clears the Timer1 interrupt flag, “

    If you use an interrupt specific handler as you have done, - Timer1Overflow - then yes GCBasic will sort out the interrupt flags. If you use a generic interrupt you will have to take care of the flags yourself.

    That said there is no harm in clearing the interrupt flag yourself just to be sure.

    “I also noticed on some posts that in the ISR some people put INTOFF in the beginning of the sub and then INTON at the end of the sub. Is this necessary?”

    IntOff and IntOn are used to bracket timing critical code that you don't want to be interrupted or code that may return an invalid result if interrupted. Again in most cases there is no harm done, but don’t do it if you have a more important / critical interrupt pending. The PIC32 family has an interrupt priority module, in the PIC 16 family it is up to you to determine priority.

    Cheers
    Chris

     

    Last edit: Chris Roper 2016-07-08
  • William Roth

    William Roth - 2016-07-08

    Yes, it should be (FOSC/4) / 4

    Look at your code above. In the timerinit sub you have used a hex value of "0x15535. This will obviously not work. You need Decimal 15535.

    If using hex ( Why would you want to?) it would be 0x3CAF

     
  • viscomjim

    viscomjim - 2016-07-08

    I will edit that post. 15535 decimal is what I want to use... Thanks again for All the help!!!!

     

    Last edit: viscomjim 2016-07-08

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.