TIMER3Interrupt
SwordfishUser.TIMER3Interrupt History
Hide minor edits - Show changes to markup
The routine is running on an 18F67J11, providing the register address for CCPR3L and CCPR3H is the same in all other PICs, no modification to the code will be needed to run in other types(provided they have a TIMER3 that is!).
The routine is running on an 18F67J11, providing the register address for CCPR3L and CCPR3H is the same in all other PICs, no modification to the code will be needed(provided they have a TIMER3 that is!).
'THE VALUE FOR "CCPR3_word" IS TAKEN FROM THE FOLLOWING CALCULATION.
'THE VALUE FOR "CCPR3_register_word" IS TAKEN FROM THE FOLLOWING CALCULATION.
'With "CCPR3_register_word = 9999" THE PERIOD IS 10ms(1000Hz)
'WITH "CCPR3_register_word = 9999" THE PERIOD IS 10ms(1000Hz)
'78X129=10062us OR 10.062ms '31kHz, "CCPR3_register_word" IS 77(78-1 For RELOAD)
'78X129=10062us OR 10.062ms:- '31kHz, "CCPR3_register_word" IS 77(78-1 For RELOAD).
'the address in PIC memory for the CCPR3L byte register 'CCPR3H is the Next address 4019
'the address in PIC memory for the CCPR3L byte register, CCPR3H is the Next address 4019
Const CCPR3_register_address=4018 'the address in PIC memory for the CCPR3L byte register, CCPR3H is the next address 4019CCPR3_register_address Dim CCPR3_register_word As Word Absolute CCPR3_register_address'create a word from CCPR3L and CCPR3H byte registers Dim CCPR3_interrupt_flag As PIR3.0 'alias the interrupt flag
'the address in PIC memory for the CCPR3L byte register 'CCPR3H is the Next address 4019 Const CCPR3_register_address=4018
Dim interrupt_clock As Word 'incremented at every interrupt Public Dim secs As Byte 'incremented every second, available to main program and other modules
'create a word from CCPR3L and CCPR3H byte registers Dim CCPR3_register_word As Word Absolute CCPR3_register_address 'alias the interrupt flag Dim CCPR3_interrupt_flag As PIR3.0 'incremented at every interrupt Dim interrupt_clock As Word 'incremented every second, available to main program and other modules Public Dim secs As Byte
Inc(interrupt_clock) 'increments the variable at every interrupt
Inc(interrupt_clock) 'increment at every interrupt
'Global Interrupt Enable(GIE bit7) and Peripheral Interrupt Enable(PEIE bit6) bits of INTCON INTCON = %11000000 'TIMER3 used as source for ECCP3(bits 6and 3), no prescaler(bits5 and 4), TIMER3 is off(bit0) T3CON = %00001000 'enable special event trigger(bits 3 to 0) CCP3CON =%00001011 'set match value for 1ms at 4MHz, -1 "tick" that is taken to reset the timer count value CCPR3_register_word = 999 PIE3.0 = 1 'enable CCP3 interrupt CCPR3_interrupt_flag = 0 'clear CCP3 interrupt flag TMR3H = 0 'clear TIMER3 TMR3H register TMR3L = 0 'clear TIMER3 TMR3L register
INTCON = %11000000 'Global Interrupt Enable(GIE bit7) and Peripheral Interrupt Enable(PEIE bit6) bits of INTCON T3CON = %00001000 'TIMER3 used as source for ECCP3(bits 6and 3), no prescaler(bits5 and 4), TIMER3 is off(bit0) TMR3H = 0 'clear TIMER3 TMR3H register TMR3L = 0 'clear TIMER3 TMR3L register CCP3CON =%00001011 'enable special event trigger(bits 3 to 0) CCPR3_register_word = 999 'set match value for 1ms at 4MHz, -1 "tick" that is taken to reset the timer count value PIE3.0 = 1 'enable CCP3 interrupt CCPR3_interrupt_flag = 0 'clear CCP3 interrupt flag
Enable(TIMER3_Interrupt) 'enable TIMER3 ISR(Interrupt Service Routine)
Enable(TIMER3_Interrupt) 'enable TIMER3 ISR
=code [=
[=
'Include "Easylocate_Dims.bas" 'Include "Easylocate_Const.bas" 'Include "INTOSC_Speed.bas"
Const CCPR3_register_address=4018 'the address in PIC memory for the CCPR3L byte register, CCPR3H is the next address 4019CCPR3_register_address Dim CCPR3_register_word As Word Absolute CCPR3_register_address'create a word from CCPR3L and CCPR3H byte registers Dim CCPR3_interrupt_flag As PIR3.0 'alias the interrupt flag
Dim interrupt_clock As Word 'incremented at every interrupt Public Dim secs As Byte 'incremented every second, available to main program and other modules
Const CCPR3_register_address=4018 'the address in PIC memory for the CCPR3L byte register, CCPR3H is the next address 4019CCPR3_register_address Dim CCPR3_register_word As Word Absolute CCPR3_register_address'create a word from CCPR3L and CCPR3H byte registers Dim CCPR3_interrupt_flag As PIR3.0 'alias the interrupt flag Dim interrupt_clock As Word 'incremented at every interrupt Public Dim secs As Byte 'incremented every second, available to main program and other modules
'******************************************************************************
'******************************************************************************
{ ***************************************************************************** * Name : TIMER3_Interrupt.bas * * Author : Mark Rodgers * * Notice : Copyright (c) 2007 Mark Rodgers * * : All Rights Reserved * * Date : 10/09/2007 * * Version : 1.0 * * Notes : * * : * ***************************************************************************** } '****************************************************************************** '****************************************************************************** Module TIMER3_Interrupt_Service_Routine '****************************************************************************** '****************************************************************************** 'Include "Easylocate_Dims.bas" 'Include "Easylocate_Const.bas" 'Include "INTOSC_Speed.bas" '****************************************************************************** '****************************************************************************** Const CCPR3_register_address=4018 'the address in PIC memory for the CCPR3L byte register, CCPR3H is the next address 4019CCPR3_register_address Dim CCPR3_register_word As Word Absolute CCPR3_register_address'create a word from CCPR3L and CCPR3H byte registers Dim CCPR3_interrupt_flag As PIR3.0 'alias the interrupt flag Dim interrupt_clock As Word 'incremented at every interrupt Public Dim secs As Byte 'incremented every second, available to main program and other modules '****************************************************************************** '****************************************************************************** 'TIMER3 INTERRUPT ROUTINE. 'THE VALUE FOR "CCPR3_word" IS TAKEN FROM THE FOLLOWING CALCULATION. 'THE TIMER STARTS AT THIS VALUE THEN COUNTS DOWN TO 0. 'AT THAT POINT THE INTERRUPT OCCURS AND THE COUNTER IS RELOADED. ' 'CRYSTAL=4MHZ 'INTERNAL CLOCK=1MHZ(PIC divides clock by 4 internally) 'SINGLE MACHINE CYCLE=1second/1,000,000=0.000001(1 microsecond) 'FOR A 1ms INTERRUPT THE RELOAD VALUE IS 1000. 'FOR A 10ms INTERRUPT THE RELOAD VALUE IS 10000. 'THE RELOAD OF THE REGISTER TAKES 1 CLOCK CYCLE, THEREFORE:- 'WITH "CCPR3_register_word = 999" THE PERIOD IS 1ms(1000Hz) 'With "CCPR3_register_word = 9999" THE PERIOD IS 10ms(1000Hz) ' 'WHEN USING DIFFERENT SPEED CLOCKS AND A 1ms INTERRUPT:- '32MHz, "CCPR3_register_word" IS 7999(8000-1 FOR RELOAD) '16MHz, "CCPR3_register_word" IS 3999(4000-1 For RELOAD) '8MHz, "CCPR3_register_word" IS 2999(2000-1 For RELOAD) '4MHz, "CCPR3_register_word" IS 999(1000-1 For RELOAD) '2MHz, "CCPR3_register_word" IS 499(500-1 For RELOAD) '1MHz, "CCPR3_register_word" IS 249(250-1 For RELOAD) ' 'WHEN USING THE INTERNAL 31kHz OSCILATOR 'THE INTERNAL CLOCK PERIOD IS 1/7750:- '=0.000129 OR 129us. '1ms/129=7.75 AND WE CAN ONLY HAVE INTEGERS! 'USING 7 AND RELYING ON THE RELOAD TIME OF 1 WE HAVE 'A TOTAL TIME OF 8X129=1032us. 'THIS IS 1.032ms SO CLOSE ENOUGH FOR MOST USES. '31kHz, "CCPR3_register_word" IS 7(8-1 For RELOAD) ' 'WITH ONLY 7 MACHINE CYCLES TO RUN CODE INSIDE THE INTERRUPT IT WOULD NOT REALLY 'BE PRACTICAL TO OPERATE AT 1ms, 10ms WOULD BE BETTER(AND MORE ACCURATE):- '78X129=10062us OR 10.062ms '31kHz, "CCPR3_register_word" IS 77(78-1 For RELOAD) '############################################################################## interrupt TIMER3_Interrupt() 'USER CODE GOES HERE ONLY!!! '################################## Inc(interrupt_clock) 'increments the variable at every interrupt If interrupt_clock = 1000 Then '1msx1000=1second interrupt_clock = 0 'clear the interrupt counter Inc(secs) 'increment the seconds counter End If '################################## 'THIS FLAG CLEARING MUST BE THE LAST 'LINE OF THE CODE, THE NEXT INTERRUPT 'WILL NOT BE REGISTERED UNTIL CLEARED '################################## CCPR3_interrupt_flag = 0 'clear CCP3 interrupt flag '################################## End interrupt '############################################################################## '****************************************************************************** '****************************************************************************** 'INITIAL SETTINGS FOR THE TIMER3 REGISTERS AND VARIABLES '############################################################################## Sub Initialize() interrupt_clock=0 'clear the interrupt counter secs=0 'clear the seconds counter INTCON = %11000000 'Global Interrupt Enable(GIE bit7) and Peripheral Interrupt Enable(PEIE bit6) bits of INTCON T3CON = %00001000 'TIMER3 used as source for ECCP3(bits 6and 3), no prescaler(bits5 and 4), TIMER3 is off(bit0) TMR3H = 0 'clear TIMER3 TMR3H register TMR3L = 0 'clear TIMER3 TMR3L register CCP3CON =%00001011 'enable special event trigger(bits 3 to 0) CCPR3_register_word = 999 'set match value for 1ms at 4MHz, -1 "tick" that is taken to reset the timer count value PIE3.0 = 1 'enable CCP3 interrupt CCPR3_interrupt_flag = 0 'clear CCP3 interrupt flag T3CON.0 = 1 'switch on TIMER3 Enable(TIMER3_Interrupt) 'enable TIMER3 ISR(Interrupt Service Routine) End Sub '############################################################################## '****************************************************************************** '****************************************************************************** Initialize 'run the initialisation routine '****************************************************************************** '******************************************************************************
End of Post
The code is running on an 18F67J11, providing the register address for CCPR3L and CCPR3H is the same in all other PICs, no modification to the code will be needed to run in other types(provided they have a TIMER3 that is!).
The routine is running on an 18F67J11, providing the register address for CCPR3L and CCPR3H is the same in all other PICs, no modification to the code will be needed to run in other types(provided they have a TIMER3 that is!).
Some inspiration was taken from this informative article by xor:- http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.SoftRTC
The code is running on an 18F67J11, providing the register address for CCPR3L and CCPR3H is the same in all other PICs, no modification to the code will be needed to run in other types(provided they have a TIMER3 that is!)
I am using this code on a project that switches the INTOSC and the PLL on and off to save power when in use on its small cell, but need the interrupt timer to test for events that could occur at any time, this is now achievable even at 31khz using the on board very low power oscilator as the main clock for the PIC and still have a 10ms interrupt period to test for button presses and other user inputs.
The code is running on an 18F67J11, providing the register address for CCPR3L and CCPR3H is the same in all other PICs, no modification to the code will be needed to run in other types(provided they have a TIMER3 that is!).
I am using this code on a project that switches the INTOSC and the PLL on and off to save power when in use on its small cell, but need the interrupt timer to test for events that could occur at any time.
This is now achievable even at 31khz using the on board very low power oscilator as the main clock for the PIC and still have a 10ms interrupt period to test for button presses and other user inputs.
Module Notes
The code is fully commented and is written to allow me to understand exactly what it took to get the interrupt to run on TIMER3.
The code is running on an 18F67J11, providing the register address for CCPR3L and CCPR3H is the same in all other PICs, no modification to the code will be needed to run in other types(provided they have a TIMER3 that is!)
I am using this code on a project that switches the INTOSC and the PLL on and off to save power when in use on its small cell, but need the interrupt timer to test for events that could occur at any time, this is now achievable even at 31khz using the on board very low power oscilator as the main clock for the PIC and still have a 10ms interrupt period to test for button presses and other user inputs.