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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 sectionsubprocedureInitTimer1()T1CON=0x11TMR1IF_bit=0TMR1H=0x3CTMR1L=0xB0TMR1IE_bit=1INTCON=0xC0endsubsubprocedureInterrupt()if(TMR1IF_bit)thenTMR1IF_bit=0TMR1H=0x3CTMR1L=0xB0'Enter your code hereendifendsub
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 Timer1InitTimer1(Osc,PS1_2)‘2:1prescaleSetTimer(1,15535)' Preload Count for 20ms @ 20MhzStartTimer1OnInterruptTimer1OverflowCallTimerIntSubdonoploopSubTimerIntSubSetTimer(1,15535)' reset count for 20ms'do stuffendsub
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
“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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
Last edit: William Roth 2016-07-07
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)
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...
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
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
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
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
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