News:

;) This forum is the property of Proton software developers

Main Menu

Interrupts

Started by Fanie, Sep 21, 2025, 09:59 AM

Previous topic - Next topic

trastikata

Did you change this as I mentioned in my comments:

"T3CON.7 = 1      ' Enables register read/write of Timer3 in one 16-bit operation"
This should be "T3CON.7 = 0"

Fanie

Quote from: trastikata on Sep 24, 2025, 07:13 PMDid you change this as I mentioned in my comments:

"T3CON.7 = 1      ' Enables register read/write of Timer3 in one 16-bit operation"
This should be "T3CON.7 = 0"
That is working for timer3, tested thank you !

trastikata

Timer0 you pre-load as High and Low byte i.e.

say you want to load wTemp = 0x1234 in Timer0 then in your code write

TMR0L = wTemp.Byte0 : TMR0H = wTemp.Byte1

or

TMR0L = 0x34 : TMR0H = 0x12

Pepe

Device = 18F14K22           '18F14K50    ' 24FJ16MC102     '32CM5164JH00032T
Declare Xtal = 64
Declare Create_Coff On
Declare Watchdog off
Config_Start
   FOSC = IRC ; Internal RC oscillator
   'FOSC = HS      ; HS oscillator                     Neither of these makes a difference...
   PLLEN = On       ; Oscillator multiplied by 4
   PCLKEN = On     ; Primary clock is under software control     
   FCMEN = OFF      ; Fail-Safe Clock Monitor disabled         
   IESO = On        ; Oscillator Switchover mode enabled
   PWRTEN = On      ; PWRT enabled
   BOREN = Off      ; Brown-out Reset enabled and controlled by software (SBOREN is enabled)
   BORV = 30        ; VBOR set to 2.2 V nominal
   WDTEN = OFF      ; WDT is controlled by SWDTEN bit of the WDTCON register
   WDTPS = 64
   MCLRE = OFF       ; RA3 input pin enabled; MCLR disabled
   HFOFST = On      ; The system clock is held off until the HF-INTOSC is stable.
   STVREN = On      ; Stack full/underflow will cause Reset
   LVP = Off ; (Single-Supply icsp ?) Low Voltage programming disabled
   BBSIZ = OFF ; 1kW boot block size
   XINST = Off ; Instruction set extension and Indexed Addressing mode enabled
   Cp0 = On     ; Block 0 code-protected
   CP1 = On         ; Block 1 (002000-003FFFh) code-protected
   CPB = On         ; Boot block (000000-0007FFh) code-protected
   CPD = On         ; Data EEPROM code-protected
   WRT0 = OFF       ; Block 0 (000800-001FFFh) not write-protected
   WRT1 = OFF       ; Block 1 (002000-003FFFh) not write-protected
   WRTB = OFF       ; Boot block (000000-0007FFh) not write-protected
   WRTC = OFF       ; Configuration registers (300000-3000FFh) not write-protected
   WRTD = OFF       ; Data EEPROM not write-protected
   EBTR0 = OFF      ; Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
   EBTR1 = OFF      ; Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
   EBTRB = OFF      ; Boot block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End

    Declare Auto_Heap_Arrays = On          ' Tell the compiler to create arrays above standard variables,
                                           ' so assembler code is more efficient
    Declare Auto_Variable_Bank_Cross = On  ' Tell the compiler to create any multi-byte variables in the same RAM bank.
                                           ' For more efficiency



       
TRISA = %00001010               ' Configure I/O
TRISB = %00000000
TRISC = %00001000

ADCON2.7 = 1
OSCCON = %01110100             '
                        ' %0 101 1100 select internal 4 MHz clock defined by FOSC<2:0> of the CONFIG1
                                ' -111---- = 16MHz   1MHz
                                ' -110---- = 8MHz    500kHz
                                ' -101---- = 4MHz    250kHz
                                ' -100---- = 2MHz
OSCCON2 = %00000111
OSCTUNE = %01000000             '  PLL enabled for 64MHz    Bit 6 = PLL ON   



Dim Cnti As Dword

Dim Vin As Word                ' Voltage input
                '
Dim Valu As Word
Dim UpDn As Bit                   ' Multiply with Factor / Divide with Factor

Dim Cntin As TMR0L.Word         ' Create a 16-bit Word from registers TMR0L/H
Dim Cntin2 As Float
Dim Cntout As TMR3L.Word         ' Create a 16-bit Word from registers TMR3L/H


       
Dim Dis1 As Byte
Dim Dis2 As Byte
Dim Dis3 As Byte
Dim Dis4 As Byte
Dim Dis5 As Byte
Dim Dis6 As Byte
Dim Dis7 As Byte
Dim Dis8 As Byte

Symbol NCA0 = PORTA.0     ' NC output                         o
Symbol Fin = PORTA.1     ' Frequency Input                         o
Symbol NCA2 = PORTA.2     ' NC Output                         o

Symbol NCA4 = PORTA.4     ' NC Output                         o   Alt int Fin
Symbol NCA5 = PORTA.5     ' NC Output                         0   FIn  Interrupt

Symbol SW1 = PORTB.4            ' Sw Input                          1   Switch1
Symbol SW2 = PORTB.5            ' Sw Input                          i   
Symbol DisC = PORTB.6     ' Disp Clock output                 o
Symbol DisS = PORTB.7     ' Disp Strobe output                o
   
Symbol Fout = PORTC.0     ' Freq Output                       o   Fout
Symbol NCC1 = PORTC.1      ' NC Output                         o
Symbol NCC2 = PORTC.2     ' NC Output                         o
Symbol AnIn = PORTC.3     ' pot Analog in                     o   Pot in

Symbol NCC4 = PORTC.4           ' LedY Output                       o
Symbol NCC5 = PORTC.5           ' LedG Output                       o
Symbol NCC6 = PORTC.6     ' Freq Input Analog                 i
Symbol DisD = PORTC.7     ' Disp Data Output                  o

PORTA = 0 : PORTB = 0 : PORTC = 0

 ANSEL = $80

'**********************************************************
'                Setup Interrupts     RCON, INTCON, INTCON2, INTCON3, PIR1, PIR2, PIE1, PIE2, IPR1, IPR2
'**********************************************************
       ' Setup Pin Change Interrupt, TMR0                                                   
       ' INTERRUPT CONTROL REGISTER               TMR0IE
INTCON.7 = 1     ' Global Interrupt Enable bit                                     GIE    IPEN = 0    IPEN = 1
INTCON.6 = 1     ' 1 = Enable all high priority interrupts   IPEN = 1              PEIE   IPEN = 0    IPEN = 1


       ' INTERRUPT CONTROL 3 REGISTER


INTCON3.3 = 1    ' 1 = Enables the INT1 external interrupt                          INT1IE
INTCON3.6 = 1    ' INT1 External Interrupt Priority bit   1 = High priority         INT1IP
INTCON3.0 = 1    ' INT1 external interrupt occurred  cleared by software            INT1IF

INTCON2.5 = 1    ' Interrupt on rising edge INT_1



       ' TIMER0 CONTROL REGISTER
T0CON.7 = 1      ' 1 = Enables Timer0                                               TMR0ON
T0CON.6 = 0      ' 0 = Timer0 is configured as a 16-bit timer/counter               T08BIT
T0CON.5 = 0      ' 1 = Transition on T0CKI pin  0 = Int instruct cycle clock        T0CS
T0CON.4 = 0      ' 0 = Increment on low-to-high transition on T0CKI pin             T0SE
T0CON.3 = 0      ' 0 = TImer0 prescaler is assigned.                                PSA
T0CON.2 = 1      '                                                                  T0PS<2:0>
T0CON.1 = 1      '
T0CON.0 = 1      '
'                  111 = 1:256 prescale value
'                  110 = 1:128 prescale value
'                  101 = 1:64 prescale value
'                  100 = 1:32 prescale value
'                  011 = 1:16 prescale value
'                  010 = 1:8   prescale value
'                  001 = 1:4   prescale value
'                  000 = 1:2   prescale value

       ' TIMER3 CONTROL REGISTER
T3CON.7 = 1      ' 16 bits  Timer3
T3CON.5 = 0      ' prescale                11 = 1:8   10 = 1:4
T3CON.4 = 0      '                         00 = 1:1   01 = 1:2
T3CON.3 = 0      ' Timer3 and Timer1 to CCP1 enable bits                   

T3CON.2 = 0      ' Timer3 external clock Input Synchronization control bit
                 ' TMR3CS = 0 Timer3 uses the internal clock
T3CON.1 = 0      ' Timer3 Clock Source Select bit 0= internal clock (fosc/4)
T3CON.0 = 1      ' 1 = Enables Timer3

PIE2.1 = 1       ' TMR3 overflow Int En bit


 
On_Hardware_Interrupt GoTo INTHandler


'********************************************************
'*              Main Program Starts Here
'********************************************************


         
Do       
       
        Cnti = Valu
        GoSub Display
        DelayMS 100
       
        Vin = ADIn 7
        Vin = 1023 - Vin    ' swap pot direction
       
         If Vin > 512 Then
            Vin = Vin - 512
            UpDn = 1
          Else
            Vin = 512 - Vin
            UpDn = 0   
         EndIf
         
Loop
     
           
'***************************************************************************
'                       INTERRUPT ROUTINES
'***************************************************************************           
INTHandler:

    Context Save        ' Save any variables used in the interrupt
   
          If INTCON3.0 = 1 Then     ' identify the int source
             T0CON.7 = 0             ' stop timer0 count
             
             If Cntin = 0 Then Cntin = 1
             If Vin = 0 Then Vin = 1
             
             If UpDn = 1 Then
                Cntin2 = Cntin * Vin
                Cntin2 = Cntin2 / 100
                         Else
                Cntin2 = Cntin / Vin
                Cntin2 = Cntin2 * 100
         EndIf
             Valu = Cntin2
             
             Cntin = 0
             T0CON.7 = 1         'restart timer0
             INTCON3.0 = 0       ' reset pin int flag   
          EndIf
         
          If PIR2.1 = 1 Then
                            Cntout = Valu
                            Toggle Fout
                            PIR2.1 = 0
          EndIf

    Context Restore       ' Restore any variables and exit the interrupt

'***************************************************************************
'                       SUBROUTINES START HERE
'***************************************************************************
Display:       
        Dis1 = Dig Cnti , 0                  ' Extract values for display
        Dis2 = Dig Cnti , 1
        Dis3 = Dig Cnti , 2
        Dis4 = Dig Cnti , 3
        Dis5 = Dig Cnti , 4                  ' Extract values for display
        Dis6 = Dig Cnti , 5
        Dis7 = Dig Cnti , 6
        Dis8 = Dig Cnti , 7
       
Display1:
        ' Set corresponding bits on displaying Volt
        Dis1 = LookUp Dis1 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis2 = LookUp Dis2 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis3 = LookUp Dis3 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis4 = LookUp Dis4 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis5 = LookUp Dis5 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis6 = LookUp Dis6 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis7 = LookUp Dis7 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis8 = LookUp Dis8 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
       
       
Display2:

         SHOut DisD, DisC, 0,[Dis1, Dis2, Dis3, Dis4, Dis5, Dis6, Dis7, Dis8]
       
         DisS = 1
         DelayMS 20
         DisS = 0
         
         Return
         
End


Fanie

Thank you Trastikata and Pepe.

Still not working.  Nothing seems to work.

Value in the pin interrupt cannot be transferred to the timer3

Context Save        ' Save any variables used in the interrupt
         
          'INT1 external Interrupt
          If INTCON3.0 = 1 Then    ' identify the int source
            Cntin2 = Cntin
            INTCON3.0 = 0    ' restart INT1 pin int   
          EndIf
         
          'TMR3 Overflow Interrupt
         
          If PIR2.1 = 1 Then            ' identify the int source 
            Cntout = Cntin2
            TMR3L = Cntout & $0f
            TMR3H = Cntout & $f0
            Toggle Fout                ' toggle output pin
            PIR2.1 = 0                ' restart TMR3 int
          EndIf
         
    Context Restore      ' Restore any variables and exit the interrupt

in this routine Cntin2 and Cntin shows correct on the display

Cntout = Cntin2 does not happen, Cntout displays random all over.

I have a second board, does the same.

Pepe

Test this code, in Proteus the transfer to timer3 works correctly by varying the analog input.

Device = 18F14K22           '18F14K50    ' 24FJ16MC102     '32CM5164JH00032T
Declare Xtal = 64
Declare Create_Coff On
Declare Watchdog off
Config_Start
   FOSC = IRC ; Internal RC oscillator
   'FOSC = HS      ; HS oscillator                     Neither of these makes a difference...
   PLLEN = On       ; Oscillator multiplied by 4
   PCLKEN = On     ; Primary clock is under software control     
   FCMEN = OFF      ; Fail-Safe Clock Monitor disabled         
   IESO = On        ; Oscillator Switchover mode enabled
   PWRTEN = On      ; PWRT enabled
   BOREN = Off      ; Brown-out Reset enabled and controlled by software (SBOREN is enabled)
   BORV = 30        ; VBOR set to 2.2 V nominal
   WDTEN = OFF      ; WDT is controlled by SWDTEN bit of the WDTCON register
   WDTPS = 64
   MCLRE = OFF       ; RA3 input pin enabled; MCLR disabled
   HFOFST = On      ; The system clock is held off until the HF-INTOSC is stable.
   STVREN = On      ; Stack full/underflow will cause Reset
   LVP = Off ; (Single-Supply icsp ?) Low Voltage programming disabled
   BBSIZ = OFF ; 1kW boot block size
   XINST = Off ; Instruction set extension and Indexed Addressing mode enabled
   Cp0 = On     ; Block 0 code-protected
   CP1 = On         ; Block 1 (002000-003FFFh) code-protected
   CPB = On         ; Boot block (000000-0007FFh) code-protected
   CPD = On         ; Data EEPROM code-protected
   WRT0 = OFF       ; Block 0 (000800-001FFFh) not write-protected
   WRT1 = OFF       ; Block 1 (002000-003FFFh) not write-protected
   WRTB = OFF       ; Boot block (000000-0007FFh) not write-protected
   WRTC = OFF       ; Configuration registers (300000-3000FFh) not write-protected
   WRTD = OFF       ; Data EEPROM not write-protected
   EBTR0 = OFF      ; Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
   EBTR1 = OFF      ; Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
   EBTRB = OFF      ; Boot block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End

    Declare Auto_Heap_Arrays = On          ' Tell the compiler to create arrays above standard variables,
                                           ' so assembler code is more efficient
    Declare Auto_Variable_Bank_Cross = On  ' Tell the compiler to create any multi-byte variables in the same RAM bank.
                                           ' For more efficiency



       
TRISA = %00001010               ' Configure I/O
TRISB = %00000000
TRISC = %00001000

ADCON2.7 = 1
OSCCON = %01110100             '
                        ' %0 101 1100 select internal 4 MHz clock defined by FOSC<2:0> of the CONFIG1
                                ' -111---- = 16MHz   1MHz
                                ' -110---- = 8MHz    500kHz
                                ' -101---- = 4MHz    250kHz
                                ' -100---- = 2MHz
OSCCON2 = %00000111
OSCTUNE = %01000000             '  PLL enabled for 64MHz    Bit 6 = PLL ON   



Dim Cnti As Dword

Dim Vin As Word                ' Voltage input
                '
Dim Valu As Float
Dim UpDn As Bit                   ' Multiply with Factor / Divide with Factor

Dim Cntin As TMR0L.Word         ' Create a 16-bit Word from registers TMR0L/H
Dim Cntin2 As Float
Dim Cntout As TMR3L.Word         ' Create a 16-bit Word from registers TMR3L/H


       
Dim Dis1 As Byte
Dim Dis2 As Byte
Dim Dis3 As Byte
Dim Dis4 As Byte
Dim Dis5 As Byte
Dim Dis6 As Byte
Dim Dis7 As Byte
Dim Dis8 As Byte

Symbol NCA0 = PORTA.0     ' NC output                         o
Symbol Fin = PORTA.1     ' Frequency Input                         o
Symbol NCA2 = PORTA.2     ' NC Output                         o

Symbol NCA4 = PORTA.4     ' NC Output                         o   Alt int Fin
Symbol NCA5 = PORTA.5     ' NC Output                         0   FIn  Interrupt

Symbol SW1 = PORTB.4            ' Sw Input                          1   Switch1
Symbol SW2 = PORTB.5            ' Sw Input                          i   
Symbol DisC = PORTB.6     ' Disp Clock output                 o
Symbol DisS = PORTB.7     ' Disp Strobe output                o
   
Symbol Fout = PORTC.0     ' Freq Output                       o   Fout
Symbol NCC1 = PORTC.1      ' NC Output                         o
Symbol NCC2 = PORTC.2     ' NC Output                         o
Symbol AnIn = PORTC.3     ' pot Analog in                     o   Pot in

Symbol NCC4 = PORTC.4           ' LedY Output                       o
Symbol NCC5 = PORTC.5           ' LedG Output                       o
Symbol NCC6 = PORTC.6     ' Freq Input Analog                 i
Symbol DisD = PORTC.7     ' Disp Data Output                  o

PORTA = 0 : PORTB = 0 : PORTC = 0

 ANSEL = $80

'**********************************************************
'                Setup Interrupts     RCON, INTCON, INTCON2, INTCON3, PIR1, PIR2, PIE1, PIE2, IPR1, IPR2
'**********************************************************
       ' Setup Pin Change Interrupt, TMR0                                                   
       ' INTERRUPT CONTROL REGISTER               TMR0IE
INTCON.7 = 1     ' Global Interrupt Enable bit                                     GIE    IPEN = 0    IPEN = 1
INTCON.6 = 1     ' 1 = Enable all high priority interrupts   IPEN = 1              PEIE   IPEN = 0    IPEN = 1


       ' INTERRUPT CONTROL 3 REGISTER


INTCON3.3 = 0    ' 1 = Enables the INT1 external interrupt                          INT1IE
INTCON3.6 = 1    ' INT1 External Interrupt Priority bit   1 = High priority         INT1IP
INTCON3.0 = 1    ' INT1 external interrupt occurred  cleared by software            INT1IF

INTCON2.5 = 1    ' Interrupt on rising edge INT_1



       ' TIMER0 CONTROL REGISTER
T0CON.7 = 0      ' 1 = Enables Timer0                                               TMR0ON
T0CON.6 = 0      ' 0 = Timer0 is configured as a 16-bit timer/counter               T08BIT
T0CON.5 = 0      ' 1 = Transition on T0CKI pin  0 = Int instruct cycle clock        T0CS
T0CON.4 = 0      ' 0 = Increment on low-to-high transition on T0CKI pin             T0SE
T0CON.3 = 0      ' 0 = TImer0 prescaler is assigned.                                PSA
T0CON.2 = 1      '                                                                  T0PS<2:0>
T0CON.1 = 1      '
T0CON.0 = 1      '
'                  111 = 1:256 prescale value
'                  110 = 1:128 prescale value
'                  101 = 1:64 prescale value
'                  100 = 1:32 prescale value
'                  011 = 1:16 prescale value
'                  010 = 1:8   prescale value
'                  001 = 1:4   prescale value
'                  000 = 1:2   prescale value

       ' TIMER3 CONTROL REGISTER
T3CON.7 = 1      ' 16 bits  Timer3
T3CON.5 = 0      ' prescale                11 = 1:8   10 = 1:4
T3CON.4 = 0      '                         00 = 1:1   01 = 1:2
T3CON.3 = 0      ' Timer3 and Timer1 to CCP1 enable bits                   

T3CON.2 = 0      ' Timer3 external clock Input Synchronization control bit
                 ' TMR3CS = 0 Timer3 uses the internal clock
T3CON.1 = 0      ' Timer3 Clock Source Select bit 0= internal clock (fosc/4)
T3CON.0 = 1      ' 1 = Enables Timer3

PIE2.1 = 1       ' TMR3 overflow Int En bit


 
On_Hardware_Interrupt GoTo INTHandler


'********************************************************
'*              Main Program Starts Here
'********************************************************


         
Do       
        Vin = ADIn 7
        Valu = Vin *64.06
        Cnti = Valu + 1
        GoSub Display
        DelayMS 100
Loop
     
           
'***************************************************************************
'                       INTERRUPT ROUTINES
'***************************************************************************           
INTHandler:

Context Save        ' Save any variables used in the interrupt
         
          If PIR2.1 = 1 Then
                            Cntout = Valu
                            Toggle Fout
                            PIR2.1 = 0
          EndIf

Context Restore       ' Restore any variables and exit the interrupt

'***************************************************************************
'                       SUBROUTINES START HERE
'***************************************************************************
Display:       
        Dis1 = Dig Cnti , 0                  ' Extract values for display
        Dis2 = Dig Cnti , 1
        Dis3 = Dig Cnti , 2
        Dis4 = Dig Cnti , 3
        Dis5 = Dig Cnti , 4                  ' Extract values for display
        Dis6 = Dig Cnti , 5
        Dis7 = Dig Cnti , 6
        Dis8 = Dig Cnti , 7
       
Display1:
        ' Set corresponding bits on displaying Volt
        Dis1 = LookUp Dis1 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis2 = LookUp Dis2 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis3 = LookUp Dis3 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis4 = LookUp Dis4 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis5 = LookUp Dis5 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis6 = LookUp Dis6 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis7 = LookUp Dis7 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis8 = LookUp Dis8 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
       
       
Display2:

         SHOut DisD, DisC, 0,[Dis1, Dis2, Dis3, Dis4, Dis5, Dis6, Dis7, Dis8]
       
         DisS = 1
         DelayMS 20
         DisS = 0
         
         Return
         
End



Fanie

Thank you Pepe !  Sorry it still doesn't work.
I will try something else.  Cannot fiddle with something this unreliable and hope it will work.

Fanie

I have this setup -

       ' INTERRUPT CONTROL REGISTER               TMR0IE
INTCON.7 = 1     ' Global Interrupt Enable bit                                     GIE    IPEN = 0    IPEN = 1
INTCON.6 = 0     ' 1 = Enable all high priority interrupts   IPEN = 1              PEIE   IPEN = 0    IPEN = 1

        ' Int1 control Registers
INTCON3.3 = 1    ' 1 = Enables the INT1 external interrupt                          INT1IE
INTCON3.6 = 1    ' INT1 External Interrupt Priority bit   1 = High priority         INT1IP
INTCON3.0 = 0    ' INT1 external interrupt occurred  cleared by software            INT1IF
INTCON2.5 = 1    ' Interrupt on rising edge    INT1    *                            INTEDG1


     
        ' TMR3 CONTROL REGISTERs
T3CON.7 = 1      ' Enables register read/write of Timer3 in one 16-bit operation    RD16                   ***
T3CON.5 = 0      ' Prescale             11 = 1:8,  10 = 1:4                         T3CKPS1
T3CON.4 = 0      '                      00 = 1:1,  01 = 1:2                         T3CKPS0
T3CON.3 = 1      ' Timer3 and Timer1 to CCP1 Enable bits                            T3CCP1
                 ' 1= Timer3 is the clock source  0 = Timer1 is the clock source
T3CON.2 = 1      ' Timer3 External Clock Input Synchronization Control bit          T3SYNC
                 ' TMR3CS = 0 = Timer3 uses the internal clock
T3CON.1 = 0      ' Timer3 Clock Source Select bit   0 = Internal clock (FOSC/4)     TMR3CS
T3CON.0 = 1      ' 1 = Enables Timer3                                               TMR3ON
' TMR3H  Timer0 Register, High Byte
' TMR3L  Timer0 Register, Low Byte  write to TMR3L

         ' PIR2  PERIPHERAL INTERRUPT REQUEST
PIR2.1 = 0      ' TMR3 register overflowed (must be cleared by software)            TMR3IF
                
         ' PIE2  PERIPHERAL INTERRUPT ENABLE
PIE2.1 = 1      ' 1 = TMR3 Overflow Int En bit                                           TMR3IE

         ' IPR2  PERIPHERAL INTERRUPT PRIORITY
IPR2.1 = 1      ' TMR3 Overflow Interrupt Priority 1 = High                          TMR3IP

And this is the handler code

INTHandler:
    
    Context Save        ' Save any variables used in the interrupt
         
          'INT1 external Interrupt
          If INTCON3.0 = 1 Then     ' identify the int source
             'toggle INTCON2.5       ' trigger falling and rising edge
             Cntout = Cntin
             INTCON3.0 = 0    ' restart INT1 pin int   
          EndIf
 
         
          'TMR3 Overflow Interrupt
          If PIR2.1 = 1 Then            ' identify the int source 
             TMR3L = Cntout & $0f
             TMR3H = Cntout & $f0
             Toggle Fout                ' toggle output pin
             PIR2.1 = 0                 ' restart TMR3 int
          EndIf
         
    Context Restore       ' Restore any variables and exit the interrupt
    Retfie


What I'm getting is that Timer3 toggle the output at the same rate as the input is interrupted,

 and does not time at all !

If I uncomment toggle INTCON2.5       ' trigger falling and rising edge
Then the interrupt on pin is up and down and I get double the output pulses from Timer3.

I tried all the different settings, and even tried with a low and high priority two different routines.

Maybe Les can help out here.


top204

#48
What is the intended purpose of:

TMR3L = Cntout & $0f
TMR3H = Cntout & $f0

That will load TMR3L and TMR3H with the lowest and highest nibbles only, and cause the wrong timings on the next interrupt cycle.

You need to use something like:

TMR3L = Cntout & $FF
TMR3H = ( Cntout >> 8 ) & $FF

Or better, and smaller code:

TMR3L = Cntout.Byte0
TMR3H = Cntout.Byte1

One thing I know for absolute certainty, is that it is not a problem with the compiler, or its code generation, and you need to simplify a test program and get things working as they should. See my earlier post with a full code template of an INT0 and Timer0 interrupt on a PIC18F14K22 device, and I tested it on a real device and it worked perfectly, with the correct interrupt timings as well, based upon the preprocessor calculator for it.

I would 'personally' use Timer0 or Timer1, and leave Timer2 and Timer3 alone, so they can be used with peripherals if required in later iterations of the code.

Pepe

In addition, it is necessary to set Cntin to zero below Cntout = Cntin because otherwise Timer0 would not be synchronized with the interrupt pulses

Fanie

thank you.
I tried timer0 but it didn't work.  I since omitted it.  Will try to get timer1 going.

trastikata

Quote from: Fanie on Sep 25, 2025, 03:36 PMthank you.
I tried timer0 but it didn't work.  I since omitted it.  Will try to get timer1 going.

Try this code for Timer3.

'TMR3 Overflow Interrupt
        If PIR2.1 = 1 Then                      'identify the int source as Timer3 IF
            T0CON.7 = 0                         'Timer0 Off
            TMR3L = Cntout.Byte0
            TMR3H = Cntout.Byte1
            Toggle Fout                         'toggle output pin
            PIR2.1 = 0                          'Clear Timer3 If
            T0CON.7 = 1                         'Timer0 On
        EndIf

Fanie

Oh dear.  Timer1 does exactly what timer3 did  :'(

I will fiddle with it some more and let you know.

Fanie

Quote from: trastikata on Sep 25, 2025, 04:33 PMTry this code for Timer3.

That was the first I tried, but !

The problem is that the value is not loaded into TMR3L, TMR3H, TMR1L or TMR1H.

The timer1 also now only output (toggle Fout) when INT1 (RA1) is interrupted.

trastikata

Can you share the full code. This is very strange, timers always were easy to get working, something's odd here.

Fanie

If I display Cntout and TMR1L and TMR1H values, then they are not the same
The Cntout value is correct, but TMR1L and TMR1H values varies randomly.
Have now tried all the possibilities with Timer1 timer on / off internal external hi low priority.

Just so you know.

Only time it works faulty is it seems to be triggered by the input and toggle output according.
No timing takes place

                'TMR1 Overflow Interrupt
          If PIR1.0 = 1 Then            ' identify the int source
             'T1CON.0 = 0               ' Timer1 off
             'Cntout = 1780
             TMR1L = Cntout.Byte0
             TMR1L = Cntout.Byte1
             Toggle Fout                ' toggle output pin
             PIR1.0 = 0                 ' restart TMR1 int
             'T1CON.0 = 1                ' Timer1 on
          EndIf

This is the full code, which I have chopped and changed to get a result... any result.

'****************************************************************
'*  Name    : FUP.BAS                                           *
'*  Author  : Fanie                                             *
'*  Notice  : Copyright (c) 2009 FAZE Electronics               *
'*          : All Rights Reserved                               *
'*  Date    : 15/02/2025                                        *
'*  Version : 1.0                                               *
'*  Notes   : Increaqse or decrease frequency input vs output   *
'*          :                                                   *
'*          :                                                   *
'****************************************************************
' Notes:
'Higest frequency in adjust scale value fastest

Device = 18F14K22           '18F14K50    ' 24FJ16MC102     '32CM5164JH00032T
Declare Xtal = 64

Config_Start
   FOSC = IRC ; Internal RC oscillator
   'FOSC = HS      ; HS oscillator                     Neither of these makes a difference...
   PLLEN = On       ; Oscillator multiplied by 4
   PCLKEN = On     ; Primary clock is under software control     
   FCMEN = OFF      ; Fail-Safe Clock Monitor disabled         
   IESO = On        ; Oscillator Switchover mode enabled
   PWRTEN = On      ; PWRT enabled
   BOREN = Off      ; Brown-out Reset enabled and controlled by software (SBOREN is enabled)
   BORV = 30        ; VBOR set to 2.2 V nominal
   WDTEN = OFF      ; WDT is controlled by SWDTEN bit of the WDTCON register
   WDTPS = 64
   MCLRE = On       ; RA3 input pin enabled; MCLR disabled
   HFOFST = On      ; The system clock is held off until the HF-INTOSC is stable.
   STVREN = On      ; Stack full/underflow will cause Reset
   LVP = Off ; (Single-Supply icsp ?) Low Voltage programming disabled
   BBSIZ = OFF ; 1kW boot block size
   XINST = Off ; Instruction set extension and Indexed Addressing mode enabled
   Cp0 = On     ; Block 0 code-protected
   CP1 = On         ; Block 1 (002000-003FFFh) code-protected
   CPB = On         ; Boot block (000000-0007FFh) code-protected
   CPD = On         ; Data EEPROM code-protected
   WRT0 = OFF       ; Block 0 (000800-001FFFh) not write-protected
   WRT1 = OFF       ; Block 1 (002000-003FFFh) not write-protected
   WRTB = OFF       ; Boot block (000000-0007FFh) not write-protected
   WRTC = OFF       ; Configuration registers (300000-3000FFh) not write-protected
   WRTD = OFF       ; Data EEPROM not write-protected
   EBTR0 = OFF      ; Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
   EBTR1 = OFF      ; Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
   EBTRB = OFF      ; Boot block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End

Declare Auto_Heap_Arrays = On          ' Tell the compiler to create arrays above standard variables,
                                           ' so assembler code is more efficient
Declare Auto_Variable_Bank_Cross = On  ' Tell the compiler to create any multi-byte variables in the same RAM bank.
                                           ' For more efficiency



       
TRISA = %00001010               ' Configure I/O
TRISB = %00000000
TRISC = %00001000

ADCON0 = %00011101              ' Set analogue inputs on AN11       01 enable ADC 00 disable ADC
ADCON1 = %00000000              ' AD control reg
ADCON2 = %10111000
OSCCON = %01110100             '
                        ' %0 101 1100 select internal 4 MHz clock defined by FOSC<2:0> of the CONFIG1
                                ' -111---- = 16MHz   1MHz
                                ' -110---- = 8MHz    500kHz
                                ' -101---- = 4MHz    250kHz
                                ' -100---- = 2MHz
OSCCON2 = %00000111
OSCTUNE = %01000000             '  PLL enabled for 64MHz    Bit 6 = PLL ON   



Dim FacTor As Word
Dim Vin As Word                ' pot input
Dim Valu As Word
Dim UpDn As Bit                   ' Multiply with Factor / Divide with Factor
Dim FLagin As Bit

Dim Cntin As Word         ' Create a 16-bit Word from registers TMR0L/H
'dim Cntin as  tmr0h x 256 + tmr0l
Dim Cntin2 As Dword
'Dim Cntout As TMR3L.Word         ' Create a 16-bit Word for registers TMR3L/H
Dim Cntout As Word

'aWord = hibyte x 256 + lobyte
Dim TesT As Byte
Dim Abc As Byte
Dim Def As Byte
       
Dim Dis1 As Byte
Dim Dis2 As Byte
Dim Dis3 As Byte
Dim Dis4 As Byte
Dim Dis5 As Byte
Dim Dis6 As Byte
Dim Dis7 As Byte
Dim Dis8 As Byte

Symbol NCA0 = PORTA.0     ' NC output                         o
Symbol Fin = PORTA.1     ' Frequency Input                         o
Symbol NCA2 = PORTA.2     ' NC Output                         o

Symbol NCA4 = PORTA.4     ' NC Output                         o   Alt int Fin
Symbol NCA5 = PORTA.5     ' NC Output                         0   FIn  Interrupt

Symbol SW1 = PORTB.4            ' Sw Input                          1   Switch1
Symbol SW2 = PORTB.5            ' Sw Input                          i   
Symbol DisC = PORTB.6     ' Disp Clock output                 o
Symbol DisS = PORTB.7     ' Disp Strobe output                o
   
Symbol Fout = PORTC.0     ' Freq Output                       o   Fout
Symbol NCC1 = PORTC.1      ' NC Output                         o
Symbol NCC2 = PORTC.2     ' NC Output                         o
Symbol AnIn = PORTC.3     ' pot Analog in                     o   Pot in

Symbol NCC4 = PORTC.4           ' LedY Output                       o
Symbol NCC5 = PORTC.5           ' LedG Output                       o
Symbol NCC6 = PORTC.6     ' Freq Input Analog                 i
Symbol DisD = PORTC.7     ' Disp Data Output                  o

PORTA = 0 : PORTB = 0 : PORTC = 0



'**********************************************************
'                Setup Interrupts     RCON, INTCON, INTCON2, INTCON3, PIR1, PIR2, PIE1, PIE2, IPR1, IPR2
'**********************************************************
                                                 
       ' INTERRUPT CONTROL REGISTER               TMR0IE
INTCON.7 = 1     ' Global Interrupt Enable bit                                     GIE    IPEN = 0    IPEN = 1
INTCON.6 = 0     ' 1 = Enable all high priority interrupts   IPEN = 1              PEIE   IPEN = 0    IPEN = 1

        ' Int1 control Registers
INTCON3.3 = 1    ' 1 = Enables the INT1 external interrupt                          INT1IE
INTCON3.6 = 1    ' INT1 External Interrupt Priority bit   1 = High priority         INT1IP
INTCON3.0 = 0    ' INT1 external interrupt occurred  cleared by software            INT1IF
INTCON2.5 = 1    ' Interrupt on rising edge    INT1    *                            INTEDG1


     
        ' T1CON    TIMER1 CONTROL REGISTERs
T1CON.7 = 1      ' Enables register read/write of Timer1 in one 16-bit operation    RD16                   ***
T1CON.6 = 0      ' clock is derived from Timer1 osc                                 T1RUN
T1CON.5 = 0      ' Prescale             11 = 1:8,  10 = 1:4                         T1CKPS1
T1CON.4 = 0      '                      00 = 1:1,  01 = 1:2                         T1CKPS0
T1CON.3 = 0      ' 1 = Timer1 oscillator is enabled                                 T1OSCEN
T1CON.2 = 0      ' Timer1 External Clock Input Synchronization Control bit          T1SYNC
                 ' TMR1CS = 0 = Timer1 uses the internal clock
T1CON.1 = 0      ' 0 = Internal clock (FOSC/4) 1 = Ext clk or from Timer1 osc       TMR1CS
T1CON.0 = 1      ' 1 = Enable Timer1                                               TMR1ON
' TMR1H  Timer1 Register, High Byte
' TMR1L  Timer1 Register, Low Byte  write to TMR3L

         ' PIR1 PERIPHERAL INTERRUPT REQUEST
PIR1.0 = 1      ' TMR1 register overflowed (must be cleared by software)            TMR1IF
                 
         ' PIE1  PERIPHERAL INTERRUPT ENABLE
PIE1.0 = 1      ' 1 = TMR1 Overflow Int En bit                                      TMR1IE

         ' IPR2  PERIPHERAL INTERRUPT PRIORITY
IPR2.0 = 1      ' TMR1 Overflow Interrupt Priority 1 = High                         TMR1IP

On_Hardware_Interrupt INTHandler

'********************************************************
'*              Main Program Starts Here
'********************************************************

Start: 
        Vin = ADIn 7                                                ' read A/D in int routine ?
        Vin = 1023 - Vin          ' swap pot direction
        If Vin = 0 Then Vin = 1
        Cntin = 100
        Cntin = Cntin * Vin
        Cntout = Cntin
       
Start1:
         GoSub Display
         GoTo Start     
           
'***************************************************************************
'                       INTERRUPT ROUTINES
'***************************************************************************           
INTHandler:
     
    Context Save        ' Save any variables used in the interrupt
         
                'INT1 external Interrupt
          If INTCON3.0 = 1 Then     ' identify the int source
             'toggle INTCON2.5       ' trigger falling and rising edge
             Cntout = Cntin
             INTCON3.0 = 0    ' restart INT1 pin int   
          EndIf
         
                'TMR1 Overflow Interrupt
          If PIR1.0 = 1 Then            ' identify the int source
             'T1CON.0 = 0               ' Timer1 off
             'Cntout = 1780
             TMR1L = Cntout.Byte0
             TMR1H = Cntout.Byte1
             Toggle Fout                ' toggle output pin
             PIR1.0 = 0                 ' restart TMR1 int
             'T1CON.0 = 1                ' Timer1 on
          EndIf
         
         

         
    Context Restore       ' Restore any variables and exit the interrupt
    Retfie

'***************************************************************************
'                       SUBROUTINES START HERE
'***************************************************************************
Display:       
        Dis1 = Dig TMR1L , 0                  ' Extract values for display
        Dis2 = Dig TMR1L , 1
        Dis3 = Dig TMR1H , 0
        Dis4 = Dig TMR1H , 1
        Dis5 = Dig Cntout , 0                 
        Dis6 = Dig Cntout , 1
        Dis7 = Dig Cntout , 2
        Dis8 = Dig Cntout , 3
       
Display1:
        ' Set corresponding bits on displaying Volt
        Dis1 = LookUp Dis1 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis2 = LookUp Dis2 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis3 = LookUp Dis3 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis4 = LookUp Dis4 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis5 = LookUp Dis5 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis6 = LookUp Dis6 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis7 = LookUp Dis7 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
        Dis8 = LookUp Dis8 , [126, 34, 188, 186, 226, 218, 222, 50, 254, 250, 152]
               
   'Blank leading zero   
'Blank:
'       If Dis4 <> 126 Then GoTo Display2
'       Dis4 = 0
'       If Dis3 <> 126 Then GoTo Display2
'       Dis3 = 0
'       If Dis2 <> 126 Then GoTo Display2
'       Dis2 = 0
       
       
       
Display2:

         SHOut DisD, DisC, 0,[Dis1, Dis2, Dis3, Dis4, Dis5, Dis6, Dis7, Dis8]
       
         DisS = 1
         DelayMS 20
         DisS = 0
         DelayMS 300
         
         Return
         
         




            End




tumbleweed

If you enable the 16-bit mode for a timer, you MUST access the timer registers in a certain order... write TMRxH then TMRxL (as bytes to make sure the order is correct), and to read it's the opposite... TMRxL then TMRxH

There are internal latch registers the perform the actual 16-bit transfers when done this way.

Fanie

I tried and the result is the same.  I suspect the internal clock is faulty or somehow have the two interrupts clash or one overrides the other.

Fanie

The up side is the wife made a banana bread,
so I'm having some with tea while feeling sorry for myself ;D

Pepe

this work in proteus