News:

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

Main Menu

Interrupts

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

Previous topic - Next topic

trastikata

By default Timer0 is set as 8-bit timer, dis you change it when you set T0CON register? Also the PSA bit must be cleared to assign prescaller.

Fanie

#21
The pic died, it is dead after I tried to enable the interrupt in the main code after polling the interrupt pin in the software... I left the interrupt disabled in the interrupt routine, then later enables it again in the main loop and then the pic dies.

Not even the flashing led works
Start:
        toggle fout
        delayms 1000
        GoTo Start

The programmer keeps on disconnecting but weird, re-connects and indicate it has programmed the pic.

Remained dead.

I have then commented all the interrupt related code.

Only the little routine above can run.

It seems to me there is a problem with the interrupts.

Btw, I wrote a simple piece of code counting freely while polling the frequency in and displayed it.  The counts range from 4000 at high frequency to 11000 at low frequency, stable too.  Could not get it done with the timer 0.

I'm going to have to think carefully if I'm going to proceed with this project and this pic.

Just as an afterthought-
The ESP32-S3 has a pulse counter built-in. P1393 of the data sheet/ reference manual.
Pulse Count Controller (PCNT)
The pulse count controller (PCNT) is designed to count input pulses. It can increment or decrement a pulse counter value by keeping track of rising (positive) or falling (negative) edges of the input pulse signal. The PCNT  has four independent pulse counters called units, which have their groups of registers...

Quite interesting how they do it ! if you care to look at it.

trastikata

Can you share your full code, I think something might be missing there.

Fanie

#23

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 Cntin As Dword               ' Count cycles in
Dim Cnti As Dword
Dim Cnto As Dword               ' Count cycles out
Dim FacTor As Float
Dim Vin As Dword                ' Voltage input
Dim Tin As Float                '
Dim Valu As Word
Dim UpDn As Bit                   ' Multiply with Factor / Divide with Factor
Dim FLagin As Bit

Dim Cntin As TMR0L.Word         ' Create a 16-bit Word from registers TMR0L/H
Dim Cntin2 As Dword
Dim Cntout As TMR1L.Word         ' Create a 16-bit Word from registers TMR1L/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



'**********************************************************
'                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
INTCON.5 = 0     ' Disables the TMR0 overflow interrupt                            TMR0IE
INTCON.4 = 0     ' INT0 External Interrupt Enable bit                              INT0IE
INTCON.3 = 0     ' 1 Enables the RA and RB port change interrupt                   RABIE
INTCON.2 = 0     ' TMR0 Overflow Interrupt Flag bit   cleared by software          TMR0IF
INTCON.1 = 0     ' INT0 External Interrupt Flag bit   cleared by software          INT0IF
INTCON.0 = 0     ' RA and RB Port Change Interrupt flag bit  cleared by software   RABIF
 
        ' INTERRUPT CONTROL 2 REGISTER
INTCON2.7 = 1   ' PORTA and PORTB pull-ups are disabled                            RABPU
INTCON2.6 = 1   ' Interrupt on rising edge    INT0                                 INTEDG0
INTCON2.5 = 1   ' Interrupt on rising edge    INT1    *                            INTEDG1
INTCON2.4 = 1   ' Interrupt on rising edge    INT2                                 INTEDG2
INTCON2.3 = 0   ' Unimplemented
INTCON2.2 = 0   ' TMR0  1 = High priority                                          TMR0IP
INTCON2.1 = 0   ' Unimplemented
INTCON2.0 = 0   ' RA and RB Port Change Int Priority bit  1 = High priority        RABIP
 
       ' INTERRUPT CONTROL 3 REGISTER
INTCON3.7 = 1    ' INT2 External Interrupt Priority bit   1 = High priority         INT2IP
INTCON3.6 = 1    ' INT1 External Interrupt Priority bit   1 = High priority         INT1IP
INTCON3.5 = 0    ' Unimplemented
INTCON3.4 = 0    ' 1 = Enables the INT2 external interrupt                          INT2IE
INTCON3.3 = 1    ' 1 = Enables the INT1 external interrupt                          INT1IE
INTCON3.2 = 0    ' Unimplemented
INTCON3.1 = 1    ' INT2 external interrupt occurred  cleared by software            INT2IF
INTCON3.0 = 1    ' INT1 external interrupt occurred  cleared by software            INT1IF

       ' 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 = 1      ' 1 = 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



         '   PERIPHERAL INTERRUPT REQUEST (FLAG) REGISTER 1
'PIR1.0 = 0       ' TMR1 register did not overflow   cleared by software

         '  PERIPHERAL INTERRUPT REQUEST (FLAG) REGISTER 2
'PIR2.1 = 0       ' TMR3 register overflowed  cleared by software   

         '  PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 1
'PIE1.1 = 0       ' Enables the TMR1 overflow interrupt

         ' PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 2
'PIE2.1 = 0       ' TMR3 1 = Overflow Interrupt Enable bit         

         ' PERIPHERAL INTERRUPT PRIORITY REGISTER 1
'IPR1.0 = 1      ' TMR1 Overflow Interrupt Priority bit 1 = High priority
 
         ' PERIPHERAL INTERRUPT PRIORITY REGISTER 2
IPR2.1 = 1      ' TMR3 Overflow Interrupt Priority bit 1 = High priority     
 
         ' RESET CONTROL REGISTER
RCON.7 = 0      ' 1 = Enable priority levels on interrupts     IPEN
 
         ' INTERRUPT-ON-CHANGE PORTA REGISTER
IOCA.0 = 0
IOCA.1 = 0
IOCA.2 = 0
IOCA.3 = 0
IOCA.4 = 0 
IOCA.5 = 0     ' 1 = Interrupt-on-change enabled for PortA5 only 

       ' INTERRUPT-ON-CHANGE PORTB REGISTER
IOCB.4 = 0   
IOCB.5 = 0
IOCB.6 = 0
IOCB.7 = 0                   
 
 
On_Hardware_Interrupt GoTo INTHandler


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

Start: 
'        toggle fout
'        delayms 1000
'        GoTo Start       
         
         INTCON3.0 = 1                 'Stop interrupt
         If Fin = 0 Then GoTo Start
Start1:
         If Fin = 1 Then Inc Cnti : GoTo Start1  ' set by interrupt RA.2
                                       ' fast increment
Start2:           
         If Fin = 0 Then Inc Cnti : GoTo Start2
         
Start3:         
        GoSub Display
        INTCON3.0 = 0                 'Start interrupt
        ' Cnti = 0
        If Fin = 1 Then GoTo Start
        GoTo Start3    ' wait till input goes high again



              ' Counter0 input Pulses
       

        Vin = ADIn 7
        Vin = 1023 - Vin    ' swap pot direction


         If Vin > 512 Then
            Vin = Vin - 512 
            FacTor = Vin / 100  ' make range of 0.00 to 5.00
            FacTor = FacTor + 1 
            Valu = FacTor * 100
            UpDn = 1
            GoTo Start1       
          Else
                 
            Vin = 512 - Vin 
            FacTor = Vin / 100  ' make range of 0.00 to 5.00
            FacTor = FacTor + 1
            Valu = FacTor * 100
            UpDn = 0
            GoTo Start1     
         EndIf

     
           
'***************************************************************************
'                       INTERRUPT ROUTINES
'***************************************************************************           
INTHandler:

    Context Save        ' Save any variables used in the interrupt
   
          If INTCON3.0 = 1 Then     ' identify the int source
             Cnti= 0
            ' INTCON3.0 = 0    ' reset pin int flag   
          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]
               
   '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


Fanie

Am I thinking right here ?

If I set the timer0 up correctly, then
At 64MHz / 256 prescaler = 250 000 clock cycles counted per second.
Hence, if the interrupt duration is 0,1 second, the result should be 25 000 counts ?


The 18F14k22 data sheet on P17 indicates -
 When OSC2 is configured as CLKOUT, the frequency at the pin is the
 frequency of the Internal Oscillator divided by 4
Will this be the same frequency fed to timer0 in counter mode ?

Pepe

demo proteus

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

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 Cntin As Dword               ' Count cycles in
Dim Cnti As Dword
Dim Cnto As Dword               ' Count cycles out
Dim FacTor As Float
Dim Vin As Dword                ' Voltage input
Dim Tin As Float                '
Dim Valu As Word
Dim UpDn As Bit                   ' Multiply with Factor / Divide with Factor
Dim FLagin As Bit

Dim Cntin As TMR0L.Word         ' Create a 16-bit Word from registers TMR0L/H
Dim Cntin2 As Dword
Dim Cntout As TMR1L.Word         ' Create a 16-bit Word from registers TMR1L/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



'**********************************************************
'                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
INTCON.5 = 0     ' Disables the TMR0 overflow interrupt                            TMR0IE
INTCON.4 = 0     ' INT0 External Interrupt Enable bit                              INT0IE
INTCON.3 = 0     ' 1 Enables the RA and RB port change interrupt                   RABIE
INTCON.2 = 0     ' TMR0 Overflow Interrupt Flag bit   cleared by software          TMR0IF
INTCON.1 = 0     ' INT0 External Interrupt Flag bit   cleared by software          INT0IF
INTCON.0 = 0     ' RA and RB Port Change Interrupt flag bit  cleared by software   RABIF
 
        ' INTERRUPT CONTROL 2 REGISTER
INTCON2.7 = 1   ' PORTA and PORTB pull-ups are disabled                            RABPU
INTCON2.6 = 1   ' Interrupt on rising edge    INT0                                 INTEDG0
INTCON2.5 = 1   ' Interrupt on rising edge    INT1    *                            INTEDG1
INTCON2.4 = 1   ' Interrupt on rising edge    INT2                                 INTEDG2
INTCON2.3 = 0   ' Unimplemented
INTCON2.2 = 0   ' TMR0  1 = High priority                                          TMR0IP
INTCON2.1 = 0   ' Unimplemented
INTCON2.0 = 0   ' RA and RB Port Change Int Priority bit  1 = High priority        RABIP
 
       ' INTERRUPT CONTROL 3 REGISTER
INTCON3.7 = 1    ' INT2 External Interrupt Priority bit   1 = High priority         INT2IP
INTCON3.6 = 1    ' INT1 External Interrupt Priority bit   1 = High priority         INT1IP
INTCON3.5 = 0    ' Unimplemented
INTCON3.4 = 0    ' 1 = Enables the INT2 external interrupt                          INT2IE
INTCON3.3 = 1    ' 1 = Enables the INT1 external interrupt                          INT1IE
INTCON3.2 = 0    ' Unimplemented
INTCON3.1 = 1    ' INT2 external interrupt occurred  cleared by software            INT2IF
INTCON3.0 = 1    ' INT1 external interrupt occurred  cleared by software            INT1IF

       ' 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 = 1      ' 1 = 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



         '   PERIPHERAL INTERRUPT REQUEST (FLAG) REGISTER 1
'PIR1.0 = 0       ' TMR1 register did not overflow   cleared by software

         '  PERIPHERAL INTERRUPT REQUEST (FLAG) REGISTER 2
'PIR2.1 = 0       ' TMR3 register overflowed  cleared by software   

         '  PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 1
'PIE1.1 = 0       ' Enables the TMR1 overflow interrupt

         ' PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 2
'PIE2.1 = 0       ' TMR3 1 = Overflow Interrupt Enable bit         

         ' PERIPHERAL INTERRUPT PRIORITY REGISTER 1
'IPR1.0 = 1      ' TMR1 Overflow Interrupt Priority bit 1 = High priority
 
         ' PERIPHERAL INTERRUPT PRIORITY REGISTER 2
IPR2.1 = 1      ' TMR3 Overflow Interrupt Priority bit 1 = High priority     
 
         ' RESET CONTROL REGISTER
RCON.7 = 0      ' 1 = Enable priority levels on interrupts     IPEN
 
         ' INTERRUPT-ON-CHANGE PORTA REGISTER
IOCA.0 = 0
IOCA.1 = 0
IOCA.2 = 0
IOCA.3 = 0
IOCA.4 = 0
IOCA.5 = 0     ' 1 = Interrupt-on-change enabled for PortA5 only

       ' INTERRUPT-ON-CHANGE PORTB REGISTER
IOCB.4 = 0   
IOCB.5 = 0
IOCB.6 = 0
IOCB.7 = 0                   
 
 
On_Hardware_Interrupt GoTo INTHandler


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

Start:
'        toggle fout
'        delayms 1000
'        GoTo Start       
         
         INTCON3.3 = 0                 'Stop interrupt
         If Fin = 0 Then GoTo Start
Start1:
         If Fin = 1 Then Inc Cnti : GoTo Start1  ' set by interrupt RA.2
                                       ' fast increment
Start2:           
         If Fin = 0 Then Inc Cnti : GoTo Start2
         
Do       
       
        GoSub Display
       ' Cnti = 0
        INTCON3.3 = 1                 'Start interrupt
         
        If Fin = 1 Then GoTo Start
Loop    ' wait till input goes high again



              ' Counter0 input Pulses
       

        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
         FacTor = Vin / 100  ' make range of 0.00 to 5.00
         FacTor = FacTor + 1
         Valu = FacTor * 100
  GoTo Start1
     
           
'***************************************************************************
'                       INTERRUPT ROUTINES
'***************************************************************************           
INTHandler:

    Context Save        ' Save any variables used in the interrupt
   
          If INTCON3.0 = 1 Then     ' identify the int source
             Cnti= 0
             INTCON3.0 = 0    ' reset pin int flag   
          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]
               
   '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
         
         Return
         
         End


charliecoutas

Does the PIC still seem dead Fanie? You set INTCON.7 to 1 so interrupts are enabled, but you never reset the INT0 interrupt flag. So it will just keep racing round the interrupt routine. Unless I've missed something....

Charlie

Fanie

This is the interrupt setup I have now.

Dim Cntin As TMR0L.Word         ' Create a 16-bit Word from registers TMR0L/H  for count in time
Dim Cntin2 As Dword
Dim Cntout As TMR3L.Word         ' Create a 16-bit Word from registers TMR3L/H for count out time


'**********************************************************
'                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

        ' 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 = 1    ' INT1 external interrupt occurred  cleared by software            INT1IF
INTCON2.5 = 1    ' Interrupt on rising edge    INT1    *                            INTEDG1

        ' TMR0 Interrupt  control Registers
T0CON.7 = 1      ' En Timer0   1 = On                                               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      '              111 = 1:256, 110 = 1:128, 101 = 1:64                T0PS2                      
T0CON.1 = 1      ' Prescaler    100 = 1:32, 011 = 1:16                              T0PS1
T0CON.0 = 1      '              010 = 1:8, 001 = 1:4, 000 = 1:2                     T0PS0
INTCON2.2 = 1    ' TMR0  1 = High priority                                         TMR0IP     
INTCON.5 = 0     ' Disables the TMR0 overflow interrupt                            TMR0IE       
INTCON.2 = 1     ' TMR0 Overflow Interrupt Flag bit   cleared by software          TMR0IF 
' TMR0H Timer0 Register, High Byte
' TMR0L Timer0 Register, Low Byte   write To TMR0L
     
        ' 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 = 0      ' 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      ' TMR3 Overflow Int En bit                                           TMR3IE

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

On_Hardware_Interrupt GoTo INTHandler


This is the interrupt routine

INTHandler:

    Context Save        ' Save any variables used in the interrupt
         
          'INT1 external Interrupt
          If INTCON3.0 = 1 Then     ' identify the int source
             T0CON.7 = 0      ' Stop Timer0 count
            ' toggle INTCON2.5             ' Count for rising and falling edge
             If Cntin = 0 Then Cntin = 1   ' Count in from CNTR0 cannot be x 0
             If Vin = 0 Then Vin = 1       ' More or less cannot be x 0
            
             If UpDn = 1 Then              ' set in main prog
                Cntin2 = Cntin * Vin       ' Cntin2 = Dword for large values
                Cntin2 = Cntin2 / 100
                Valu = Cntin2              ' Valu holds new count for TMR3 to overflowed
             Else
                Cntin2 = Cntin / Vin
                Cntin2 = Cntin2 * 100
                Valu = Cntin2              ' Valu holds new count for TMR3 when overflowed
             EndIf
            
             Cntin = 0        ' Zero Timer0 count
             T0CON.7 = 1      ' Re-Start Timer0 count
             INTCON3.0 = 0    ' restart INT1 pin int   
          EndIf
         
          'TMR3 Overflow Interrupt
         
          If PIR2.1 = 1 Then            ' identify the int source 
         
             Cntout = Valu              ' load new count out value
             'cntout = 65536 - Cntout    ' Interrupt on Cntout value
             Toggle Fout                ' toggle output pin
             PIR2.1 = 0                 ' restart TMR3 int
          EndIf
         
    Context Restore       ' Restore any variables and exit the interrupt

Fanie

#28
What it is supposed to do -

Every time the input pin interrupts, it stop and starts counter 0 to count up from internal clock

The counter 0 count can then be made more or less

This value is put into timer3 and every time it interrupt on overflow, it toggle the output pin.

Not getting anything to work, values are all over.
Even the A/D value from the main loop is all over, possibly from the interrupts.

Fanie

I'm supposed to get a more or less stable count value in timer0 because the input pin interrupt time remains the same if I don't change it.

The output time3 is then also suppose to change in relation with timer0

Output is 122Hz and I can do what I want it doesn't change.
Even if I put a fixed value in Cntout (Cntout As TMR3L.Word) it is stuck at 122Hz

Fanie

Does this work ?

Dim Cntin As TMR0L.Word         ' Create a 16-bit Word from registers TMR0L/H  for count in time

Dim Cntout As TMR3L.Word         ' Create a 16-bit Word from registers TMR3L/H for count out time

I get the impression that it does not write or read the 16 bit values from the timers  :-\

Fanie

If I use

TMR3L = 500 : TMR3H = 200

and change either value then the output time change

Dim Cntout As TMR3L.Word  - Cntout does nothing if I change it's value


Also, if i use two bytes for transferring
Abc = TMR0L   Def = TMR0H

to timer 3

TMR3L = Abc  TMR3H = Def

then the timer3 time the output in relation with timer0 count value.

trastikata

#32
Hello Fanie,

I've taken a look at your code, here's my input on your code. Also read the comments I did in the Interrupt routine, it is important:

                (*
                The relationship between the input counter and the output counter
                does not make sense. If your Timer0 is measuring 1Hz then the Cntin
                will be 62500, assuming maximum voltage 512 ADC readings, thus:

                Cntin2 = Cntin * Vin / 100  ==> 62500*512/100 = 320000

                However since you load Cntin2 to Value and then this to Timer3,
                this value does not make sense as 16b Timer counter preload.

                Also keep in mind to have Timer3 overflow for example after 1s,
                which is 62500 Timer3 counts with prescaller 256 = 1s, you need
                to preload Timer3 with 65535-62500=3035 ==> this is the value to
                load in Timer3 to have it overflow after 1 second.
                *)

"INTCON3.3 = 0    ' 1 = Enables the INT1 external interrupt "
Enable the Interrupt only at the last moment when you get to the part of the code that requires it.

"INTCON.6 = 1    ' 1 = Enable all high priority interrupts  IPEN = 1"
You don't have interrupt priorities enabled, thus "INTCON.6 = 1" enables peripheral interrupts.

"INTCON3.6 = 1    ' INT1 External Interrupt Priority bit  1 = High priority        INT1IP"
No need of this, because interrupt priorities is not enabled as mentioned earlier.

"INTCON3.0 = 1    ' INT1 external interrupt occurred  cleared by software"
Why do you set the flag, is this intentional, clearing the flag in this case means setting it to 0?

"T0CON.7 = 1      ' En Timer0  1 = On"
Enable the timer only at the last moment when you get to the part of the code that requires it, because now the timer is counting while you set-up other registers (and possibly do something else in the main code before you get to the point where the timer has to be operational).

"INTCON2.2 = 1    ' TMR0  1 = High priority"
No need of this, because interrupt priorities is not enabled as mentioned earlier.

"INTCON.5 = 0    ' Disables the TMR0 overflow interrupt"
Be careful with your code - you lower frequency limit is 1 Hz - at 64 MHz, Timer0 will overflow at 1.048576 seconds.

"INTCON.2 = 1    ' TMR0 Overflow Interrupt Flag bit  cleared by software "
Why do you set the flag, is this intentional, clearing the flag in this case means setting it to 0?

' TMR0H Timer0 Register, High Byte
' TMR0L Timer0 Register, Low Byte  write To TMR0L
This should be replaced simply by "Cntin = 1" to reset the timer to 1 since you are using the math based from 1 not from 0

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

"T3CON.0 = 1      ' 1 = Enables Timer3 "
Enable the timer only at the last moment when you get to the part of the code that requires it, because now the timer is counting while you set-up other registers (and possibly do something else in the main code before you get to the point where the timer has to be operational).

' TMR3H  Timer0 Register, High Byte
' TMR3L  Timer0 Register, Low Byte  write to TMR3L
This should be replaced simply by "Cntout  = 1234" to reset the timer3 to value 1234 for example.

"IPR2.1 = 1      ' TMR3 Overflow Interrupt Priority 1 = High"
No need of this, because interrupt priorities is not enabled as mentioned earlier.




Device = 18F14K22
Declare Xtal = 64

Symbol Fout = PORTC.0            ' Freq Output

Dim Vin As Dword                ' Voltage input
Dim UpDn As Bit                 ' Multiply with Factor / Divide with Factor
Dim Valu As Word
Dim Cntin As TMR0L.Word         ' Create a 16-bit Word from registers TMR0L/H  for count in time
Dim Cntin2 As Dword
Dim Cntout As TMR3L.Word        ' Create a 16-bit Word from registers TMR3L/H for count out time
Dim PowerOn As Bit              'Is it guaranteed that the incoming pulse generator is synced with the
                                'power on-cycle of the PIC? To make sure, I'd ignore the first pulse,
                                'reset Timer0 and start synchronized count. This bit serves to ignore
                                'the first incoming pulse. 

'**********************************************************
'                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

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

        ' TMR0 Interrupt  control Registers
T0CON.7 = 0      ' En Timer0   1 = On                                               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      '              111 = 1:256, 110 = 1:128, 101 = 1:64                T0PS2                     
T0CON.1 = 1      ' Prescaler    100 = 1:32, 011 = 1:16                              T0PS1
T0CON.0 = 1      '              010 = 1:8, 001 = 1:4, 000 = 1:2                     T0PS0
INTCON.5 = 0     ' Disables the TMR0 overflow interrupt                            TMR0IE      
INTCON.2 = 0     ' TMR0 Overflow Interrupt Flag bit   cleared by software          TMR0IF
    
        ' TMR3 CONTROL REGISTERs
T3CON.7 = 0      ' Enables register read/write of Timer3                            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 = 0      ' 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 = 0      ' 1 = Enables Timer3                                               TMR3ON

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

On_Hardware_Interrupt GoTo INTHandler
         
Main:
    INTCON3.3 = 1    ' 1 = Enables the INT1 external interrupt
    T0CON.7 = 1      ' En Timer0
    PowerOn = 0
   
    'Do something else
End

INTHandler:
    Context Save        ' Save any variables used in the interrupt
        'INT1 external Interrupt
        If INTCON3.0 = 1 Then           'identify the int source as INT1 IF
            If PowerOn = 0 Then         'This is the first pulse in, which is undetermined
                T0CON.7 = 0             'Timer0 Off
                INTCON.2 = 0            'Clear Timer0 IF if first pulse took more than one overflow to come
                Cntin = 1               'Reset Timer0 to 1 because your math is not 0-based
                PowerOn = 1             'Set Power On first pulse complete
                T3CON.0 = 1             'Enable Timer3 for output frequency
                INTCON3.0 = 0           'Clear INT1 If
                T0CON.7 = 1             'Timer0 On
            Else                        'First pulse in was successful
                T0CON.7 = 0                     'Stop Timer0 count
               
                If Vin = 0 Then Vin = 1         'More or less cannot be x 0
           
                If UpDn = 1 Then                'set in main prog
                    Cntin2 = Cntin * Vin        'Cntin2 = Dword for large values
                    Cntin2 = Cntin2 / 100
                Else
                    Cntin2 = Cntin * 100        'If first "Cntin / Vin" you can lose resolution
                    Cntin2 = Cntin2 / Vin
                EndIf
               
                (*
                The relationship between the input counter and the output counter
                does not make sense. If your Timer0 is measuring 1Hz then the Cntin
                will be 62500, assuming maximum voltage 512 ADC readings, thus:

                Cntin2 = Cntin * Vin / 100  ==> 62500*512/100 = 320000

                However since you load Cntin2 to Value and then this to Timer3,
                this value does not make sense as 16b Timer counter preload.

                Also keep in mind to have Timer3 overflow for example after 1s,
                which is 62500 Timer3 counts with prescaller 256 = 1s, you need
                to preload Timer3 with 65535-62500=3035 ==> this is the value to
                load in Timer3 to have it overflow after 1 second.
                *)
               
                Valu = Cntin2                   'Valu holds new count for TMR3 to overflowed
           
                Cntin = 1                       'Reset Timer0 To 1 because your math is not 0-based
                T0CON.7 = 1                     'Re-Start Timer0 count
                INTCON3.0 = 0                   'Clear INT1 If
            EndIf
        EndIf      
            
        'TMR3 Overflow Interrupt
        If PIR2.1 = 1 Then                      'identify the int source as Timer3 IF
            Cntout = Valu                       'load new count out value
            Toggle Fout                         'toggle output pin
            PIR2.1 = 0                          'Clear Timer3 If
        EndIf
    Context Restore       ' Restore any variables and exit the interrupt

Edit: Added "INTCON3.0 = 0          'Clear INT1 If" in ISR under "PowerOn = 0"

Fanie

Let me explain the relationship between timer0 and timer3

The pic cannot work with low frequencies.

I have an encoder that outputs a low frequency, 5 Hz to less than 1000Hz

This low frequency interrupts INT1 pin (RA.1) on the pic.

When INT1 is interrupted, it copies the timer0 count, zero timer0 and restart the timer0 counter

The copied count value of timer0 can now be manipulated to more or less in value.

This value is then placed in timer3 to count the value out, and only then toggle the output pin.

If the timer 0 value is transferred to timer3 without increasing or decreasing it, the slow input pulse will be equal to the output pulse.  If the timer0 value is increased, or decreased, the output pulse will also become faster or slower because the timer3 timeout count changed.

Fanie

#34
As for the timing -

It seems the internal clock is Fosc / 4 ?

64 000 000 Hz / timer0 prescaler of 256 = 250 000 / sec

At 5Hz the time is 0,2 seconds, hence 250 000 * 0.2 = 50 000 will fit in a word which is 65536 max

If Fosc is divided by 4 then the counter value should be 50 000 / 4 = 12 500.

So either should make it.

trastikata

Fannie,

I understood this,but you missed my point there. Read carefully what I said.

With every tick of the Fosc/4 your Timer0 increases from 0 since the last INT1. Thus if 200ms elapsed from this point i.e. 5 Hz, Timer0 would have a count of 12500. Assuming Vin is 400:

Cntin2 = Cntin * Vin / 100  ==> 12500 * 400 / 100 = 50000
Valu=50000

You load this value to Timer3, this means Timer3 will overflow after 65535-50000=15553 counts with prescaller 1:1 as set in your code. This is the equivalent of toggling the output pin every 972 microseconds.

If your Vin is say 10 then the 5 Hz will be converted to 4 milliseconds output pin toggling.

Is this your intention?


Fanie

If I can just get this to work...

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

Neither of these variables values change the timers counts
If I put values in the hibyte and lowbyte of each, then it changes.

trastikata

Look at my previous comment.

Also the code I posted I made modifications to your Timer and Interrupt set-up and handling. Compare it to yours to see where are the differences.

Fanie

Quote from: trastikata on Sep 24, 2025, 07:00 PMFannie,

I understood this,but you missed my point there. Read carefully what I said.

With every tick of the Fosc/4 your Timer0 increases from 0 since the last INT1. Thus if 200ms elapsed from this point i.e. 5 Hz, Timer0 would have a count of 12500. Assuming Vin is 400:

Cntin2 = Cntin * Vin / 100  ==> 12500 * 400 / 100 = 50000
Valu=50000

You load this value to Timer3, this means Timer3 will overflow after 65535-50000=15553 counts with prescaller 1:1 as set in your code. This is the equivalent of toggling the output pin every 972 microseconds.

If your Vin is say 10 then the 5 Hz will be converted to 4 milliseconds output pin toggling.

Is this your intention?

Vin's value is between 0 and 5 multiply, or 0 to 5 divide, it is set to 0 (or 1) so I can get the program working first.

Fanie

Again, if I can just get this to work...

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

Neither of these variables values change the timers counts
If I put values in the hibyte and lowbyte of each, then it changes.