News:

Let's find out together what makes a PIC Tick!

Main Menu

PIC18F46Q43 Timer1 Interrupt

Started by Jamie, Nov 03, 2022, 12:20 AM

Previous topic - Next topic

Jamie

Hello forum, I would like to ask for some assistance setting up an interrupt at 20Hz with a 10Mhz Xtal and timer1. The code worked great on the 18F46K22. I've gone over the datasheet for a few days now and tried several things but the interrupt wont work with the 18F46Q43.
Everything else works fine except the variables in the interrupt wont count down.

I would appreciate a fresh set of eyes to see what I've missed. There isn't much in the way of examples for this processor.

Thanks

Jamie


' Interrupt bits
Symbol TIMER1 = TMR1L.Word      ' Create a WORD variable from two hardware registers
Symbol TMR1IF = PIR1.0          ' TIMER1 overflow interrupt flag bit
Symbol TMR1IE = PIE1.0          ' TIMER1 overflow interrupt enable
Symbol GIE = INTCON0.7           ' Global Interrupt enable bit      *********** NEW FOR 18F46Q43
Symbol PEIE = INTCON0.6          ' Peripheral interrupt Enable bit  *********** NEW FOR 18F46Q43

'Symbol GIE = INTCON.7           ' Global Interrupt enable bit
'Symbol PEIE = INTCON.6          ' Peripheral interrupt Enable bit

delayms 500   
Print At 4,1," V10.0 Mar 11  2022 "


GoTo OVER_INTERRUPT         ' Jump over the interrupt subroutine






INTERRUPT_HANDLER:
Context Save                ' Save system variables

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The body of the Interrupt routine goes here ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'PIE1.0 = 0
T1CON.0 = 0                                 ' Disable timer1 while in the interrupt
'TIMER1 = TIMER1 + 3036                      ' Interrupt at 10hz (100ms) with 40mhz OSC at 1:16 
TIMER1 = TIMER1 + 49912                     ' Interrupt at 20hz (50ms) with 10mhz OSC at 1:8
T1CON.0 = 1                                 ' Start Timer1


    If Out1_CNTFlag = 1 Then                ' interrupt counts down 20 per second
        If Out1_Time > 0 Then
            Out1_Time = Out1_Time - 1
        EndIf
    EndIf

    If Out2_CNTFlag = 1 Then
        If Out2_Time > 0 Then
            Out2_Time = Out2_Time - 1
        EndIf
    EndIf
    If Out3_CNTFlag = 1 Then
        If Out3_Time > 0 Then
            Out3_Time = Out3_Time - 1
        EndIf
    EndIf
    If Out4_CNTFlag = 1 Then
        If Out4_Time > 0 Then
            Out4_Time = Out4_Time - 1
        EndIf
    EndIf
    If Out5_CNTFlag = 1 Then
        If Out5_Time > 0 Then
            Out5_Time = Out5_Time - 1
        EndIf
    EndIf
    If Out6_CNTFlag = 1 Then
        If Out6_Time > 0 Then
            Out6_Time = Out6_Time - 1
        EndIf
    EndIf
    If Out7_CNTFlag = 1 Then
        If Out7_Time > 0 Then
            Out7_Time = Out7_Time - 1
        EndIf
    EndIf
    If Out8_CNTFlag = 1 Then
        If Out8_Time > 0 Then
            Out8_Time = Out8_Time - 1
        EndIf
    EndIf


        If GetTempFlag > 0 Then
            GetTempFlag = GetTempFlag - 1      ' This is the CHECK TEMP COUNTER
        EndIf

        If KegFlash > 0 Then
            KegFlash = KegFlash - 1
        EndIf



Clear TMR1IF                ' Clear the Timer1 interrupt flag
'T1CON.0 = 1                 ' restart timer1
Context Restore             ' Restore the registers and exit the interrupt
;High_Int_Sub_End
'Enable
'--------------------------------------------------------------------------------------------------------------------------------------------

' MAIN PROGRAM LOOP STARTS HERE

OVER_INTERRUPT:
INTCON0 = 0                  ' Disable Interrupts
TIMER1 = 49912              ' Interrupt at 20hz (50ms) with 10mhz OSC at 1:8
T1CON = %00110001           ' Turn on Timer1, prescaler = 1:8

'pie3 = %00010000            '' ENABLE TIMER1 INTERRUPT.             PG 142 PIE3      NEW 1
T1CLK = %00000001           ' NEW T1CLK PG 395 FOSC/4 CLOCK SOURCE
TMR1IE = 1                  ' Enable the TIMER1 overflow interrupt
INTCON0 = %11000000          ' Enable global interrupts and peripheral interrupts same as PEIE = 1, GIE = 1



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''       
Cls
Begin:

Down here is where it prints out the variables from within the interrupt.
 

Stephen Moss

I am not sure how the compiler reads a word resister when you define it as Symbol TIMER1 = TMR1L.Word. But in the T1CON register is a bit to select whether its read/write operations are preformed as 8bits or 16bits. Consequently, if you have not already done so you might want to try setting it yourself to both options  and see if that has any effect in case it is in the wrong mode for way the compiler is dealing with it.

You are using Symbol to define TIMER1, generally Symbol is for Constants so you might want to try it as DIM TIMER1 as TMR1L.Word instead.

Finally, and maybe most importantly I cannot see how you are executing the ISR as there is no ON_HARDWARE_INTERRUPT GoTo or ON_LOW_INTERRUPT Goto command, so are you sure the interrupt handle is being called? One way to test would be the get it to turn an LED on for a second at the start of the ISR, then at least you would know whether or not the ISR is being called upon.   

top204

When assistance is required for a program, it is important to place a compilable program in the post, otherwise, educated guesses have to be made, and incorrect advice can be given, which is often worse than no advice at all. :-)

Thanks to the Positron8 compiler, the Q43 devices operate the same as other 18F types, but their SFR names may change and the bits within them will change, so it is important to check in the datasheet what SFRs and bits are required for a particular peripheral on a particular device. The PIC18F46Q43 device should be the same as the PIC18F27Q43 device I used for the demonatration program listing below, but with microchip, you can never guarantee that, so it "may" need some changes in the Timer0_Init procedure. :-)

The program listing below shows a simple Timer0 overflow interrupt demonstration. It has the interrupt set for 50ms (I hope because I do not have my frequency counter available). It also shows a more clear layout of a program listing, so it is easy to follow and change when required:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' A simple demonstration of a Timer0 overflow interrupt, operating on a PIC18F27Q43 device.
' The interrupt is set for a 50ms interval, which is 20Hz.
'
' It will flash an LED when the interrupt occurs and transmit an incrementing value to a serial terminal.
'
' Written for the Positron8 BASIC compiler by Les Johnson.
'
    Device = 18F27Q43                               ' Tell the compiler what device to compile for
    Declare Xtal = 64                               ' Tell the compiler what frequency the device is operating at (in MHz)
    On_Hardware_Interrupt Goto ISR_Handler          ' Tell the compiler that interrupts are being used and point to its handler routine
'
' Setup USART1
'
    Declare Hserial_Baud = 9600
    Declare HRSOut1_Pin = PORTC.6
    Declare HRSIn1_Pin = PORTC.7
'
' Create some constants and alias'
'
    Symbol LED_Pin = PORTB.0                        ' The LED is attached to this pin
    Symbol Timer0_cValue = $F3CB                    ' Set for Timer0 interval at 50ms with a 256 prescaler and the device operating at 64MHz
'
' Create a variable for the demonstration
'
    Dim wCounter As Word                            ' Increments every interrupt

'----------------------------------------------------
' Create some preprocessor meta-macros to make the program easier to follow and change
'----------------------------------------------------
$define Int_Global_Enable() INTCON0bits_GIE = 1     ' Enable global interrupts
$define Int_Global_Disable() INTCON0bits_GIE = 0    ' Disable global interrupts

$define Timer0_Enable() T0CON0bits_T0EN = 1         ' Enable Timer0
$define Timer0_Disable() T0CON0bits_T0EN = 0        ' Disable Timer0

'----------------------------------------------------
' Write a 16-bit value to the Timer0 SFRs
' Input     : pValue holds the value to write to TMR0L\H
' Output    : None
' Notes     : None
'
$define Timer0_Write16(pValue) '
    TMR0H = pValue.Byte1       '
    TMR0L = pValue.Byte0

'--------------------------------------------------------------------------------------------
' The main program starts here
' Initialise a Timer0 overflow interrupt.
' Every 20ms, the interrupt will flash an LED on PORTB.0
' And transmit the value of an incrementing counter variable to a serial terminal
'
Main:
    Int_Osc64MHz()                                  ' Set the device to use its internal 64MHz oscillator

    HRsoutLn "Started"                              ' Transmit to a serial terminal to make sure the program is initialised at 64MHz

    wCounter = 0                                    ' Reset the wCounter variable
    PinLow LED_Pin                                  ' Make the LED pin and output low to extinguish it
    Timer0_Init()                                   ' Initialise Timer0 for the interrupt required
    Int_Global_Enable()                             ' Enable global interrupts

    Do : Loop                                       ' Stop here because the interrupt will do its thing in the background

'--------------------------------------------------------------------------------------------
' Initialise Timer0
' Input     : None
' Output    : None
' Notes     : Timer0 is set up for a 50ms duration (20 Hz)
'
Proc Timer0_Init()
    Dim wTimer0 As TMR0L.Word                       ' Create a 16-bit SFR from TMR0L\H

    T0CON1 = 0b01011000                             ' Clock is FOSC/4, Prescaler is 1:256, Not Synchronised
    wTimer0 = Timer0_cValue                         ' Set Timer0 value
    PIR3bits_TMR0IF = 0                             ' Clear the interrupt flag before enabling the interrupt
    PIE3bits_TMR0IE = 1                             ' Enable a Timer0 interrupt
    T0CON0 = 0b10010000                             ' Postscaler is 1:1, Timer0 enabled, 16-bit operation
EndProc

'--------------------------------------------------------------------------------------------
' Read the 16-bit Timer0
' Input     : None
' Output    : Returns the 16-bit value held in TMR0L\H
' Notes     : None
'
Proc Timer0_Read16(), Word
    Result.Byte0 = TMR0L
    Result.Byte1 = TMR0H
EndProc

'--------------------------------------------------------------------------------------------
' Setup the internal oscillator for 64MHz
' Input     : None
' Output    : None
' Notes     : None
'
Proc Int_Osc64MHz()
    OSCCON1 = ob00000000
    OSCFRQ = 0b00001000                             ' Setup for 64MHz
    OSCENbits_HFOEN = 1                             ' HFINTOSC is enabled and operating as set by OSCFRQ
    DelayMs 100
EndProc

'--------------------------------------------------------------------------------------------
' Interrupt handler routine
' Input     : None
' Output    : None
' Notes     : A Timer0 overflow interrupt is tested for,
'             and this flashes an LED and transmits an incrementing value to a serial terminal
'
ISR_Handler:
    Context Save                                    ' Save any SFRs and compiler system variables used within the interrupt handler

    If PIR3bits_TMR0IF = 1 Then                     ' Was it a Timer0 overflow that triggered the interrupt?
        PIR3bits_TMR0IF = 0                         ' Yes. So clear its flag
        Timer0_Write16(Timer0_cValue)               ' Reload Timer0 for the same timing of the next interrupt
        Toggle LED_Pin                              ' Flash the LED
        HRsoutLn "From Interrupt: ", Dec wCounter   ' Transmit the value of wCounter to a serial terminal
        Inc wCounter                                ' Increment the wCounter variable
    EndIf

    Context Restore                                 ' Restore any SFRs and compiler system variables and exit the interrupt

'--------------------------------------------------------------------------------------------
' Set the config fuses to use the internal oscillator at 64MHz on a PICxxQ43 device
'
Config_Start
    FEXTOSC = Off                 ' Oscillator not enabled
    RSTOSC = HFINTOSC_64MHZ       ' HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1
    CLKOUTEN = Off                ' CLKOUT function is disabled
    PR1WAY = Off                  ' PRLOCKED bit can be set and cleared repeatedly
    CSWEN = On                    ' Writing to NOSC and NDIV is allowed
    FCMEN = On                    ' Fail-Safe Clock Monitor enabled
    MCLRE = INTMCLR               ' MCLR pin enabled
    PWRTS = PWRT_64               ' PWRT set at 64ms
    MVECEN = Off                  ' Interrupt contoller does not use vector table to prioritze interrupts
    IVT1WAY = Off                 ' IVTLOCKED bit can be cleared and set repeatedly
    LPBOREN = On                  ' Low-Power BOR enabled
    BOREN = SBORDIS               ' Brown-out Reset enabled. SBOREN bit is ignored
    BORV = VBOR_2P85              ' Brown-out Reset Voltage (VBOR) set to 2.8V
    ZCD = Off                     ' ZCD module is disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
    PPS1WAY = Off                 ' PPSLOCKED bit can be set and cleared repeatedly (subject to the unlock sequence)
    STVREN = On                   ' Stack full/underflow will cause Reset
    LVP = Off                     ' HV on MCLR/VPP must be used for programming
    XINST = Off                   ' Extended Instruction Set and Indexed Addressing Mode disabled
    WDTCPS = WDTCPS_31            ' Divider ratio 1:65536. software control of WDTPS
    WDTE = Off                    ' WDT Disabled. SWDTEN is ignored
    WDTCWS = WDTCWS_7             ' Window always open (100%). Software control. Keyed access not required
    WDTCCS = SC                   ' Software Control
    BBSIZE = BBSIZE_512           ' Boot Block size is 512 words
    BBEN = Off                    ' Boot block disabled
    SAFEN = Off                   ' SAF disabled
    DEBUG = Off                   ' Background Debugger disabled
    WRTB = Off                    ' Boot Block not Write protected
    WRTC = Off                    ' Configuration registers not Write protected
    WRTD = Off                    ' Data EEPROM not Write protected
    WRTSAF = Off                  ' SAF not Write Protected
    WRTAPP = Off                  ' Application Block not write protected
    CP = Off                      ' PFM and Data EEPROM code protection disabled
Config_End

Below is a screenshot of the above program operating on an Amicus18 board that contains a PIC18F27Q43 device, instead of its PIC18F25K20 device:
Timer0_Interrupt.jpg

Jamie

Stephen, Thank you for the reply. I do have

On_Hardware_Interrupt GoTo INTERRUPT_HANDLER

in the code.


Top204, Thank you for the program listing I'll pour over it until I get it going on Timer1


Is there any way to Buy coffee or to donate to the forum? Its very helpfull and very much appreciated to receive help when stuck!
I'm no star programmer but working on it and would be nice to give back somehow.

Thanks for everyone's help

Jamie

top204

For a Timer1 interrupt rate of 50ms (20 Hz), I could not get it to operate slow enough when using 64MHz because it only has a prescaler up to 1:8, but 32MHz works nicely with Timer1 generating an interrupt every 50ms.

The code listing below is a modification of the previous Timer0 interrupt, but the SFRs are changed for Timer1 operation:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' A simple demonstration of a Timer1 overflow interrupt, operating on a PIC18F27Q43 device.
' The interrupt is set for a 50ms interval, which is 20Hz.
'
' It will flash an LED when the interrupt occurs and transmit an incrementing value to a serial terminal.
'
' Written for the Positron8 BASIC compiler by Les Johnson.
'
    Device = 18F27Q43                               ' Tell the compiler what device to compile for
    Declare Xtal = 32                               ' Tell the compiler what frequency the device is operating at (in MHz)
    On_Hardware_Interrupt Goto ISR_Handler          ' Tell the compiler that interrupts are being used and point to its handler routine
'
' Setup USART1
'
    Declare Hserial_Baud = 9600
    Declare HRSOut1_Pin = PORTC.6
    Declare HRSIn1_Pin = PORTC.7
'
' Create some constants and alias'
'
    Symbol LED_Pin = PORTB.0                        ' The LED is attached to this pin
    Symbol Timer1_cValue = $3CB0                    ' Set for Timer1 interval at 50ms with an 8 prescaler and the device operating at 32MHz
'
' Create a variable for the demonstration
'
    Dim wCounter As Word                            ' Increments every interrupt

'----------------------------------------------------
' Create some preprocessor meta-macros to make the program easier to follow and change
'----------------------------------------------------
$define Int_Global_Enable() INTCON0bits_GIE = 1     ' Enable global interrupts
$define Int_Global_Disable() INTCON0bits_GIE = 0    ' Disable global interrupts

$define Timer1_Enable() T1CONbits_TMR1ON = 1        ' Enable Timer1
$define Timer1_Disable() T1CONbits_TMR1ON = 0       ' Disable Timer1

'----------------------------------------------------
' Write a 16-bit value to the Timer1 SFRs
' Input     : pValue holds the value to write to TMR1L\H
' Output    : None
' Notes     : None
'
$define Timer1_Write16(pValue) '
    TMR1H = pValue.Byte1       '
    TMR1L = pValue.Byte0

'--------------------------------------------------------------------------------------------
' The main program starts here
' Initialise a Timer1 overflow interrupt.
' Every 20ms, the interrupt will flash an LED on PORTB.0
' And transmit the value of an incrementing counter variable to a serial terminal
'
Main:
    Int_Osc32MHz()                                  ' Set the device to use its internal 32MHz oscillator

    HRsoutLn "Started"                              ' Transmit to a serial terminal to make sure the program is initialising

    wCounter = 0                                    ' Reset the wCounter variable
    PinLow LED_Pin                                  ' Make the LED pin and output low to extinguish it
    Timer1_Init()                                   ' Initialise Timer1 for the interrupt required
    Int_Global_Enable()                             ' Enable global interrupts

    Do : Loop                                       ' Stop here because the interrupt will do its thing in the background

'--------------------------------------------------------------------------------------------
' Initialise Timer1
' Input     : None
' Output    : None
' Notes     : Timer1 is set up for a 50ms duration (20 Hz)
'
Proc Timer1_Init()
    Dim wTimer1 As TMR1L.Word                       ' Create a 16-bit SFR from TMR1L\H

    T1CLK = 0b00000001                              ' Set for FOSC/4
    Timer1_Write16(Timer1_cValue)                   ' Write the value to TMR1L\H
    PIR3bits_TMR1IF = 0                             ' Clear the interrupt flag before enabling a Timer1 interrupt
    PIE3bits_TMR1IE = 1                             ' Enable a Timer1 interrupt
    T1CON = 0b00110111                              ' Timer1 prescaler is 1:8, Timer1 enabled, 16-bit read, not synchronized
EndProc

'--------------------------------------------------------------------------------------------
' Read the 16-bit Timer1
' Input     : None
' Output    : Returns the 16-bit value held in TMR1L\H
' Notes     : None
'
Proc Timer1_Read16(), Word
    Result.Byte0 = TMR1L
    Result.Byte1 = TMR1H
EndProc

'--------------------------------------------------------------------------------------------
' Setup the internal oscillator for 32MHz
' Input     : None
' Output    : None
' Notes     : None
'
Proc Int_Osc32MHz()
    OSCCON1 = 0b01100000
    OSCCON3 = 0b00000000
    OSCFRQ  = 0b00000110                            ' Setup for 32MHz
    OSCEN   = 0b00000000
    OSCTUNE = 0b00000000
    DelayMs 100
EndProc

'--------------------------------------------------------------------------------------------
' Interrupt handler routine
' Input     : None
' Output    : None
' Notes     : A Timer1 overflow interrupt is tested for,
'             and this flashes an LED and transmits an incrementing value to a serial terminal
'
ISR_Handler:
    Context Save                                    ' Save any SFRs and compiler system variables used within the interrupt handler

    If PIR3bits_TMR1IF = 1 Then                     ' Was it a Timer1 overflow that triggered the interrupt?
        PIR3bits_TMR1IF = 0                         ' Yes. So clear its flag
        Timer1_Write16(Timer1_cValue)               ' Reload Timer1 for the same timing of the next interrupt
        Toggle LED_Pin                              ' Flash the LED
        HRsoutLn "From Interrupt: ", Dec wCounter   ' Transmit the value of wCounter to a serial terminal
        Inc wCounter                                ' Increment the wCounter variable
    EndIf

    Context Restore                                 ' Restore any SFRs and compiler system variables and exit the interrupt

'--------------------------------------------------------------------------------------------
' Set the config fuses to use the internal oscillator on a PICxxQ43 device
'
Config_Start
    FEXTOSC = Off                 ' Oscillator not enabled
    RSTOSC = HFINTOSC_64MHZ       ' HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1
    CLKOUTEN = Off                ' CLKOUT function is disabled
    PR1WAY = Off                  ' PRLOCKED bit can be set and cleared repeatedly
    CSWEN = On                    ' Writing to NOSC and NDIV is allowed
    FCMEN = On                    ' Fail-Safe Clock Monitor enabled
    MCLRE = INTMCLR               ' MCLR pin enabled
    PWRTS = PWRT_64               ' PWRT set at 64ms
    MVECEN = Off                  ' Interrupt contoller does not use vector table to prioritze interrupts
    IVT1WAY = Off                 ' IVTLOCKED bit can be cleared and set repeatedly
    LPBOREN = On                  ' Low-Power BOR enabled
    BOREN = SBORDIS               ' Brown-out Reset enabled. SBOREN bit is ignored
    BORV = VBOR_2P85              ' Brown-out Reset Voltage (VBOR) set to 2.8V
    ZCD = Off                     ' ZCD module is disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
    PPS1WAY = Off                 ' PPSLOCKED bit can be set and cleared repeatedly (subject to the unlock sequence)
    STVREN = On                   ' Stack full/underflow will cause Reset
    LVP = Off                     ' HV on MCLR/VPP must be used for programming
    XINST = Off                   ' Extended Instruction Set and Indexed Addressing Mode disabled
    WDTCPS = WDTCPS_31            ' Divider ratio 1:65536. software control of WDTPS
    WDTE = Off                    ' WDT Disabled. SWDTEN is ignored
    WDTCWS = WDTCWS_7             ' Window always open (100%). Software control. Keyed access not required
    WDTCCS = SC                   ' Software Control
    BBSIZE = BBSIZE_512           ' Boot Block size is 512 words
    BBEN = Off                    ' Boot block disabled
    SAFEN = Off                   ' SAF disabled
    Debug = Off                   ' Background Debugger disabled
    WRTB = Off                    ' Boot Block not Write protected
    WRTC = Off                    ' Configuration registers not Write protected
    WRTD = Off                    ' Data EEPROM not Write protected
    WRTSAF = Off                  ' SAF not Write Protected
    WRTAPP = Off                  ' Application Block not write protected
    Cp = Off                      ' PFM and Data EEPROM code protection disabled
Config_End

In order to get it to run at 50ms while using a 64MHz oscillator, you could always make the interrupt run at 25ms, and set a simple counter inside it, to half the rate to 50ms.

Jamie

Thank you again Top204,
I've managed to get both of the examples running and have learned a ton from them!

Greatly appreciated

Jamie

top204

#6
You are welcome.

I did a bit more reading of the PIC18F27Q43 datasheet, and found that Timer1 can also use the internal oscillator for its timing, so setting it to work with its internal 500KHz oscillator "should" allow an interrupt every 50ms while using its 64MHz internal oscillator to run the device at 16 MIPS (Million Instructions Per Second). i.e. Full Speed.

Change the line in the "Timer1_Init" procedure, to:

T1CLK = 0b00000101                              ' Set for medium frequency internal oscillator of 500KHz

And change the constant value held in Timer1_cValue, to:

Symbol Timer1_cValue = $F3CB            ' Set for Timer1 interval at 50ms with an 8 prescaler/500Hz internal oscillator and the device operating at 64MHz

Use the previous "Int_Osc64MHz()" procedure to make the device run at 64MHz, and it should now have a Timer1 overflow interrupt duration of 50ms while the device is still running at full speed. Make sure you change the Declare Xtal to operate at 64 MHz, instead of 32. i.e. Declare Xtal = 64