News:

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

Main Menu

Interrupt in PIC18F24Q71 problem

Started by John Drew, Jun 27, 2025, 08:44 AM

Previous topic - Next topic

John Drew

G'day all,
I have a program working well when polling. In an effort to speed things up I thought I'd use an interrupt to improve throughput from the encoders but I've become stuck.
The 18F24Q71 sends information to another board some distance away. The board is polled from the main board by sending a high on portb.5 which initiates a data stream back to the main board. The program below is a simplified version to test the interrupt. No data is sent.

Disregard the extra TRIS as the board I'm testing on is the final populated board but with this test code. I use the LEDs to keep track of what is happening. I expect the DtaReqLED to flash with incoming requests while the DtaInLedA flashes continually except when missing a flash because the interrupt routine is accessed.The main board poll stays low until it has received all the data normally but with this code the poll is slow because the absence of received data results in a timeout.

That's the theory but numerous tests tell me I haven't got the Interrupt set up properly.
I'd appreciate any help to check my setup of the interrupt on change registers.
John

'****************************************************************
'*  Name    : Testinterrupt.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2025 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 26/06/2025                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
    Device = 18F24Q71                       'Tell the compiler what device to compile for
    Declare Xtal = 64                       'Tell the compiler what frequency the device is operating at (in MHz)
    Declare Auto_Heap_Arrays   = On         'Make all arrays "Heap" types, so they always get placed after standard variables
    Declare Auto_Heap_Strings  = On         'Make all Strings "Heap" types, so they always get placed after standard variables
    Declare Auto_Variable_Bank_Cross = On   'Make sure all multi-byte variables remain within a single RAM bank
    Declare Hserial1_Baud = 9600            'Set USART1 Baud rate         115200
    Declare HRSOut1_Pin   = PORTC.6         'Set the TX pin for USART1 pin 17
   
    Symbol DtaReqLED=PORTC.7        'LED request from shack               pin 18
    Symbol DtaInLEDa=PORTC.5        'LED Data in from AZ encoder          pin 16
    Symbol DtaInLEDe=PORTB.4        'LED Data in from EL encoder          pin 25
    Symbol Handshake=PORTB.5        'Handshake from shack low=send data   pin 26
   
' setup registers for Interrupt on change
    Symbol GIE = INTCON0.7          'global interrupts               
    Symbol Intrpt = PIR0.7          'enable Int on change
    Symbol SetDirection = IOCBP.5   'IOC on upward change register   
    Symbol PriorityH = IPR0.7       'interrupt on change priority     
    Symbol PeriphOK = PIE0.7        'Peripheral interrupt enabled     
    Symbol FlagInterrupt = IOCBF.5  'interrupt has happened flag
   
    Dim Count1 As Bit
    Dim Flag As Byte
    Dim Check As Word
   
    TRISA = %00111111               'portA bits 0-5 inputs, bits 6,7 outputs for clock      checked
    TRISB = %11101111               'portB bits 0-3,5 inputs, bit 4,5,6,7 output
    TRISC = %00010100               'portC bits 2,4 inputs,  bits 0,1,3,5,6,7 outputs
   
    On_Hardware_Interrupt IntRoutine    'Interrupt when B.5  goes high
       
    Initialise:
       DelayMS 100
       Count1 = 0
       DtaInLEDe = 0
       DtaReqLED = 0
       DtaInLEDa = 0
       
       'now turn on the registers
       PriorityH = 1          'high priority for IonC
       PeriphOK = 1           'enable peripheral interrupts
       SetDirection = 1       'trigger on UP
       Intrpt = 1             'enable interrupt on change
       IOCBF = 0              'clear all the flags
       GIE = 1                'enable global interrupts
       
    Main:
          DtaInLEDa = ~ DtaInLEDa   'this led continuous fast flashing
          If Count1 = 1 Then
             DtaReqLED = 1          'this led should flash after every interrupt
          Else                      'but it doesn't
             DtaReqLED = 0           
          EndIf
    GoTo Main
           
    IntRoutine:                   'Interrupt when B.5  goes high
      Context Save
      Repeat Until GIE = 0        'ensure GIE = 0
      If FlagInterrupt = 1 Then   'on port b.5
         Count1 = ~Count1         'flip bit so that led can flip in main
      EndIf
      Repeat Until Handshake = 0  'wait until the trigger is released from B.5
      IOCBF = 0                   'clear all interrupt flags
      GIE = 1                     'I think restore does this but just in case
      Context Restore
     
Config_Start
  FEXTOSC = Off           ;External Oscillator not enabled
  RSTOSC = HFINTOSC_64MHZ ;Reset Oscillator is HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1
  CLKOUTEN = OFF          ;CLKOUT function is disable
  PR1WAY = OFF            ;PRLOCKED bit can be set and cleared repeatedl
  BBEN = OFF              ;Boot block disable
  CSWEN = On              ;Writing to NOSC and NDIV is allowe
  FCMEN = OFF             ;Fail-Safe Clock Monitor disable
  FCMENP = OFF            ;Fail-Safe Clock Monitor Disable
  FCMENS = OFF            ;Fail-Safe Clock Monitor Disable
  MCLRE = EXTMCLR         ;If LVP = 0, MCLR pin is MCLR; If LVP = 1, RE3 pin function is Mclr
  PWRTS = PWRT_OFF        ;PWRT is disable
  MVECEN = On             ;Multi-vector enabled, Vector table used for interrupt
  IVT1WAY = OFF           ;IVTLOCKED bit can be cleared and set repeatedl
  LPBOREN = OFF           ;Low-Power BOR disable
  BOREN = SBORDIS         ;Brown-out Reset enabled , SBOREN bit is ignore
  BORV = VBOR_1P9         ;Brown-out Reset Voltage (VBOR) set to 1.9
  ZCD = OFF               ;ZCD module is disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCO
  PPS1WAY = OFF           ;PPSLOCKED bit can be set and cleared repeatedly (subject to the unlock sequence
  STVREN = OFF            ;Stack full/underflow will not cause Reset
  LVP = OFF               ;HV on MCLR/VPP must be used for programming
  Debug = OFF             ;Background Debugger disable
  XINST = OFF             ;Extended Instruction Set and Indexed Addressing Mode disable
  WDTCPS = WDTCPS_31      ;Divider ratio 1:65536; software control of WDTP
  WDTE = OFF              ;WDT Disabled; SWDTEN is ignore
  WDTCWS = WDTCWS_7       ;window always open (100%); software control; keyed access not require
  WDTCCS = SC             ;Software Contro
  BBSIZE = BBSIZE_8192    ;Boot Block size is 8192 word
  SAFSZ = SAFSZ_NONE      ;NON
  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
  CPD = OFF               ;Data EEPROM code protection disable
  Cp = OFF                ;PFM code protection disable
  Config_End

top204

Hello John

You may need to also enable peripheral interrupts. i.e.

INTCON0bits_GIEL = 1 ' Enable peripheral interrupts
INTCON0bits_GIE = 1  ' Enable global interrupts

Don't bother with the priority settings in your code because they just confuse things, and they are not required unless you have a high and low priority interrupt mechanism in place. So remove them from the listing.

Also, there is no need to re-enable interrupts within the interrupt handler code, as this is automatically performed by the microcontroller, when the interrupt is exited.

For a clearer code listing, take a look in the device's .def file (C:\Program Files (x86)\ProtonIDE\PDS\Includes\Defs\), and you will see the SFRbits_name $defines, and there is no need to create Symbols for them, and they are standard names from the microchip datasheets.

John Drew

Thanks Les,
I'll give it a go in the morning.
John

tumbleweed

Be sure to set config MVECEN off