• AVR Freaks

AnsweredHot!PIC18F2520 - INT0/1/2 not working

Page: 12 > Showing page 1 of 2
Author
Claude van der Ryst
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2019/11/20 09:26:30
  • Location: South Africa
  • Status: offline
2019/11/21 09:28:12 (permalink)
0

PIC18F2520 - INT0/1/2 not working

Hi
 
I'm trying to write an interrupt service routine that will be triggered by INT0/INT1/INT2 or interrupt from PORTB. When I trigger the pins, only RB4 and RB5 responds to a trigger. I'm sure I have configured everything in my code correctly, but there might be something I have overlooked?
 
Here is my code:
 
#include "p18f2520.inc"

; CONFIG1H
  CONFIG OSC = HSPLL ; Oscillator Selection bits (HS oscillator, PLL enabled (Clock Frequency = 4 x FOSC1))
  CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
  CONFIG IESO = OFF ; Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

; CONFIG2L
  CONFIG PWRT = ON ; Power-up Timer Enable bit (PWRT enabled)
  CONFIG BOREN = SBORDIS ; Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
  CONFIG BORV = 3 ; Brown Out Reset Voltage bits (Minimum setting)

; CONFIG2H
  CONFIG WDT = OFF ; Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
  CONFIG WDTPS = 32768 ; Watchdog Timer Postscale Select bits (1:32768)

; CONFIG3H
  CONFIG CCP2MX = PORTC ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
  CONFIG PBADEN = OFF ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
  CONFIG LPT1OSC = OFF ; Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
  CONFIG MCLRE = ON ; MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

; CONFIG4L
  CONFIG STVREN = ON ; Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
  CONFIG LVP = ON ; Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
  CONFIG XINST = OFF ; Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode enabled)

; CONFIG5L
  CONFIG CP0 = OFF ; Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
  CONFIG CP1 = OFF ; Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
  CONFIG CP2 = OFF ; Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
  CONFIG CP3 = OFF ; Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

; CONFIG5H
  CONFIG CPB = OFF ; Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
  CONFIG CPD = OFF ; Data EEPROM Code Protection bit (Data EEPROM not code-protected)

; CONFIG6L
  CONFIG WRT0 = OFF ; Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
  CONFIG WRT1 = OFF ; Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
  CONFIG WRT2 = OFF ; Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
  CONFIG WRT3 = OFF ; Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

; CONFIG6H
  CONFIG WRTC = OFF ; Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
  CONFIG WRTB = OFF ; Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
  CONFIG WRTD = OFF ; Data EEPROM Write Protection bit (Data EEPROM not write-protected)

; CONFIG7L
  CONFIG EBTR0 = OFF ; Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
  CONFIG EBTR1 = OFF ; Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
  CONFIG EBTR2 = OFF ; Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
  CONFIG EBTR3 = OFF ; Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

; CONFIG7H
  CONFIG EBTRB = OFF ; Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)

RES_VECT CODE 0x0000 ; processor reset vector
    GOTO INITIALIZE ; go to beginning of program

ISR_VECT CODE 0x0008
    GOTO INT_CNT

MAIN_PROG CODE ; let linker place main program

INITIALIZE
 
    BCF TRISC, 6 ;TX as output
    BSF TRISC, 7 ;RX as input

    ;---CONFIGURE TXSTA
    ;Configures TXSTA as 8 bit transmission, transmit enabled, async mode, high speed baud rate
    MOVLW B'00100100'
    MOVWF TXSTA

    ;---CONFIGURE RCSTA
    MOVLW B'10000000'
    MOVWF RCSTA ;enable serial port receive

    ;---CONFIGURE SPBRG FOR DESIRED BAUD RATE
    BCF BAUDCON, BRG16 ;Divisor at 8 bit
    MOVLW D'112' ;BAUD RATE = 9600bps
    MOVWF SPBRG ;AT 4.332 MHZ & HSPLL

    BCF INTCON, GIE ;DISABLE GLOBAL INTERRUPTS
    BCF INTCON, TMR0IE ;DISABLE TMR0 INTERRUPT
    BSF INTCON, INT0IE ;ENABLE INT0 INTERRUPT
    BSF INTCON, RBIE ;ENABLE RB PORT CHANGE INTERRUPT
    BCF INTCON, RBPU ;ENABLE PORTB PULL-UPS
    BSF INTCON3, INT1IP ;ENABLE INT1 HIGH PRIORITY INTERRUPT
    BSF INTCON3, INT2IP ;ENABLE INT2 HIGH PRIORITY INTERRUPT
    BSF INTCON3, INT1IE ;ENABLE INT1 INTERRUPT
    BSF INTCON3, INT2IE ;ENABLE INT2 INTERRUPT
 
    BCF TRISA, 5 ;SET PA5 AS OUTPUT
    BCF LATA, 5 ;LED OFF

    MOVLW 0xFF
    MOVWF TRISB ;SET PORTB AS INPUT (ALL 8 BITS)
 
    BCF INTCON, INT0IF ;CLEAR INT0 INTERRUPT FLAG
    BCF INTCON, INT1IF ;CLEAR INT1 INTERRUPT FLAG
    BCF INTCON, INT2IF ;CLEAR INT2 INTERRUPT FLAG
    BCF INTCON, RBIF ;CLEAR PORTB INTERRUPT FLAG
 
    BSF INTCON, GIE ;ENABLE GLOBAL INTERRUPTS
 
START

    GOTO $ ; loop forever

INT_CNT

    BCF INTCON, GIE ;DISABLE ALL INTERUPTS

    MOVLW 0x20
    XORWF LATA,F ;TOGGLE LED
    
    MOVF PORTB, W ;MOVE PORTB CONTENTS TO WORKING REGISTER
    MOVWF TXREG ;MOVE WORKING REGISTER TO TXREG
    GOTO CHECK_TRMT_EMPTY ;CHECK IF TRMT IS EMPTY

    BCF INTCON, INT0IF ;CLEAR INT0 INTERRUPT FLAG
    BCF INTCON, INT1IF ;CLEAR INT1 INTERRUPT FLAG
    BCF INTCON, INT2IF ;CLEAR INT2 INTERRUPT FLAG
    BCF INTCON, RBIF ;CLEAR PORTB INTERRUPT FLAG
    BSF INTCON, GIE ;RENABLE THE INTERUPTS

RETFIE ;RETURN FROM INTERRUPT
    
CHECK_TRMT_EMPTY
    BTFSS TXSTA, TRMT ;check if TRMT is empty
    GOTO CHECK_TRMT_EMPTY ;if not, check again
RETURN
    
END

 
What am I missing?
#1
ric
Super Member
  • Total Posts : 26135
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/21 14:24:36 (permalink)
+1 (1)
You may spot the problem in this line
  CONFIG PBADEN = OFF ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)

It is YOUR JOB to make sure any analog capable pins are in digital mode.
For RB0 to RB3 you have two ways of doing that.
Either via the PBADEN config setting, or by writing to ADCON1 in your code.
Have a read of "EXAMPLE 10-2: INITIALIZING PORTB" in the PIC datasheet.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#2
Claude van der Ryst
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2019/11/20 09:26:30
  • Location: South Africa
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/21 15:09:22 (permalink)
0
Hi Ric
 
Thanks for the reply
 
ric
You may spot the problem in this line
  CONFIG PBADEN = OFF ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)

 

 
CONFIG PBADEN was initially ON. I just forgot to change the comment part.
 
ric
It is YOUR JOB to make sure any analog capable pins are in digital mode.
For RB0 to RB3 you have two ways of doing that.
Either via the PBADEN config setting, or by writing to ADCON1 in your code.
Have a read of "EXAMPLE 10-2: INITIALIZING PORTB" in the PIC datasheet.
 



I have tried to change the ADCON1 bit, but now RB4 and RB5 doesn't respond when I trigger the pins.
 
Here is what my code looks like now:
 

#include "p18f2520.inc"

; CONFIG1H
  CONFIG  OSC = HSPLL           ; Oscillator Selection bits (HS oscillator, PLL enabled (Clock Frequency = 4 x FOSC1))
  CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
  CONFIG  IESO = OFF            ; Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

; CONFIG2L
  CONFIG  PWRT = ON             ; Power-up Timer Enable bit (PWRT enabled)
  CONFIG  BOREN = SBORDIS       ; Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
  CONFIG  BORV = 3              ; Brown Out Reset Voltage bits (Minimum setting)

; CONFIG2H
  CONFIG  WDT = OFF             ; Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
  CONFIG  WDTPS = 32768         ; Watchdog Timer Postscale Select bits (1:32768)

; CONFIG3H
  CONFIG  CCP2MX = PORTC        ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
  CONFIG  PBADEN = OFF          ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital input channels on Reset)
  CONFIG  LPT1OSC = OFF         ; Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
  CONFIG  MCLRE = ON            ; MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

; CONFIG4L
  CONFIG  STVREN = ON           ; Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
  CONFIG  LVP = ON              ; Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
  CONFIG  XINST = OFF           ; Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode enabled)

; CONFIG5L
  CONFIG  CP0 = OFF             ; Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
  CONFIG  CP1 = OFF             ; Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
  CONFIG  CP2 = OFF             ; Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
  CONFIG  CP3 = OFF             ; Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

; CONFIG5H
  CONFIG  CPB = OFF             ; Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
  CONFIG  CPD = OFF             ; Data EEPROM Code Protection bit (Data EEPROM not code-protected)

; CONFIG6L
  CONFIG  WRT0 = OFF            ; Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
  CONFIG  WRT1 = OFF            ; Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
  CONFIG  WRT2 = OFF            ; Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
  CONFIG  WRT3 = OFF            ; Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

; CONFIG6H
  CONFIG  WRTC = OFF            ; Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
  CONFIG  WRTB = OFF            ; Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
  CONFIG  WRTD = OFF            ; Data EEPROM Write Protection bit (Data EEPROM not write-protected)

; CONFIG7L
  CONFIG  EBTR0 = OFF           ; Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR1 = OFF           ; Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR2 = OFF           ; Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR3 = OFF           ; Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

; CONFIG7H
  CONFIG  EBTRB = OFF           ; Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)

RES_VECT  CODE    0x0000        ; processor reset vector
    GOTO    INITIALIZE          ; go to beginning of program

ISR_VECT  CODE    0x0008
    GOTO INT_CNT

MAIN_PROG CODE                  ; let linker place main program

INITIALIZE
 
    BCF TRISC, 6                ;TX as output
    BSF TRISC, 7                ;RX as input

    ;---CONFIGURE TXSTA
    ;Configures TXSTA as 8 bit transmission, transmit enabled, async mode, high speed baud rate
    MOVLW B'00100100'
    MOVWF TXSTA

    ;---CONFIGURE RCSTA
    MOVLW B'10000000'
    MOVWF RCSTA                 ;enable serial port receive

    ;---CONFIGURE SPBRG FOR DESIRED BAUD RATE
    BCF BAUDCON, BRG16          ;Divisor at 8 bit
    MOVLW D'112'                ;BAUD RATE =  9600bps
    MOVWF SPBRG                 ;AT 4.332 MHZ & HSPLL

    BCF INTCON, GIE           ;DISABLE GLOBAL INTERRUPTS
    BCF INTCON, TMR0IE         ;DISABLE TMR0 INTERRUPT
    BSF INTCON, INT0IE         ;ENABLE INT0 INTERRUPT
    BSF INTCON, RBIE           ;ENABLE RB PORT CHANGE INTERRUPT
    BCF INTCON, RBPU           ;ENABLE PORTB PULL-UPS
    BSF INTCON3, INT1IP        ;ENABLE INT1 HIGH PRIORITY INTERRUPT
    BSF INTCON3, INT2IP        ;ENABLE INT2 HIGH PRIORITY INTERRUPT
    BSF INTCON3, INT1IE        ;ENABLE INT1 INTERRUPT
    BSF INTCON3, INT2IE        ;ENABLE INT2 INTERRUPT
 
    BCF TRISA, 5               ;SET PA5 AS OUTPUT
    BCF LATA, 5                ;LED OFF

    CLRF PORTB                 ;Initialize PORTB by clearing output data latches
    MOVLW 0x0F
    MOVWF ADCON1               ;Set RB<4:0> as digital I/O pins (required if config bit PBADEN is set)
    
    MOVLW 0xFF
    MOVWF TRISB                ;SET PORTB AS INPUT (ALL 8 BITS)
 
    BCF INTCON, INT0IF           ;CLEAR INT0 INTERRUPT FLAG
    BCF INTCON, INT1IF           ;CLEAR INT1 INTERRUPT FLAG
    BCF INTCON, INT2IF           ;CLEAR INT2 INTERRUPT FLAG
    BCF INTCON, RBIF           ;CLEAR PORTB INTERRUPT FLAG
 
    BSF INTCON, GIE            ;ENABLE GLOBAL INTERRUPTS
 
START

    GOTO $                     ; loop forever

INT_CNT

    BCF INTCON, GIE            ;DISABLE ALL INTERUPTS

    MOVLW 0x20
    XORWF LATA,F               ;TOGGLE LED
    
    MOVF PORTB, W              ;MOVE PORTB CONTENTS TO WORKING REGISTER
    MOVWF TXREG                ;MOVE WORKING REGISTER TO TXREG
    GOTO CHECK_TRMT_EMPTY      ;CHECK IF TRMT IS EMPTY

    BCF INTCON, INT0IF           ;CLEAR INT0 INTERRUPT FLAG
    BCF INTCON, INT1IF           ;CLEAR INT1 INTERRUPT FLAG
    BCF INTCON, INT2IF           ;CLEAR INT2 INTERRUPT FLAG
    BCF INTCON, RBIF           ;CLEAR PORTB INTERRUPT FLAG
    BSF INTCON, GIE            ;RENABLE THE INTERUPTS

RETFIE                         ;RETURN FROM INTERRUPT
    
CHECK_TRMT_EMPTY
    BTFSS TXSTA, TRMT          ;check if TRMT is empty
    GOTO CHECK_TRMT_EMPTY      ;if not, check again
RETURN
    
END

#3
ric
Super Member
  • Total Posts : 26135
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/21 15:19:23 (permalink) ☄ Helpfulby Claude van der Ryst 2019/11/22 09:06:36
+2 (2)
Do NOT twiddle the GIE bit inside your interrupt service!
It is automatically cleared and set for you.
Clearing it on entry is harmless, but pointless, it's already clear.
Setting it on exit is fatal, as it will allow another interupt before the RETFIE has been executed, which "pops" the interrupt context.
That should be a "RETFIE FAST" so it restores the W, BSR and STATUS registers on exit.
 
Get rid of the    
GOTO CHECK_TRMT_EMPTY      ;CHECK IF TRMT IS EMPTY"
line. Right now if you ever jump to it, you will exit the interrupt service bypassing the RETFIE instruction and flags clearing code. If anything, it should have been a CALL not a GOTO, but you should never put blocking code inside interrupt services anyway.,
 
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#4
1and0
Access is Denied
  • Total Posts : 10573
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/21 17:55:40 (permalink) ☄ Helpfulby Claude van der Ryst 2019/11/22 09:06:45
+3 (3)
Also, turn off the LVP config bit, as it affects the RB5/PGM pin.
#5
dan1138
Super Member
  • Total Posts : 3402
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/21 19:00:13 (permalink) ☼ Best Answerby Claude van der Ryst 2019/11/22 09:09:25
+3 (3)
Here is a custom crafted example of using the INT0, INT1 and INT2 external interrupt inputs in a PIC18F2520:
    list n=0, c=255, r=dec      ; This makes the .LST file look pretty
;
; File      : main,asm
; Date      : 2019-November-21
; Target    : PIC18F2520
; IDE       : MPLABX v5.25
; Assembler : MPASMWIN v5.84
;
; Additional files : p18f2520.inc      Special function register definitions
;                    18f2520_g.lkr     Linker script file
;
;
    config OSC = INTIO67, STVREN = ON, PWRT = OFF, BOREN = OFF
    config WDT = OFF, PBADEN = OFF, CCP2MX = PORTBE
    config MCLRE = ON, LVP = OFF, FCMEN = OFF, IESO = OFF
    config BORV = 0, WDTPS = 32768, LPT1OSC = ON
    config CP0 = OFF ,CP1 = OFF ,CP2 = OFF ,CP3 = OFF
    config CPB = OFF ,CPD = OFF
    config WRT0 = OFF ,WRT1 = OFF ,WRT2 = OFF ,WRT3 = OFF
    config WRTB = OFF ,WRTD = OFF, WRTC = OFF
    config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
    config EBTRB = OFF

    include "p18F2520.inc"

RES_VECT    CODE    0x0000      ; processor reset vector
    goto    START               ; go to beginning of program
;
; High priority interrupt vector
;
ISRH_VECT   CODE    0x0008      ; processor high priority interrupt vector
    call    $+2,FAST            ; Workaround for A1 silicon bug (DS80209H-page 7)
    pop
    goto    ISRH_Handler
;
; Low priority interrupt vector context storage memory
;
ISRL_DATA   UDATA_ACS
WREG_SAVE   res     1
STATUS_SAVE res     1
BSR_SAVE    res     1
;
; Low priority interrupt vector
;
ISRL_VECT   CODE    0x0018      ; processor low priority interrupt vector
    movwf   WREG_SAVE           ; WREG_SAVE is in the "access" bank
    movff   STATUS,STATUS_SAVE  ; STATUS_SAVE can be located anywhere
    movff   BSR,BSR_SAVE        ; BSR_SAVE can be located anywhere
;
; INT1 handler
;
    btfsc   INTCON3,INT1IE      ; Skip when INT1 disabled
    btfss   INTCON3,INT1IF      ; Skip when INT1 asserts
    bra     INT1_exit
    bcf     INTCON3,INT1IF      ; Clear INT1 assert flag
;
; Put more INT1 handler code here
;
INT1_exit:
;
; INT2 handler
;
    btfsc   INTCON3,INT2IE      ; Skip when INT2 disabled
    btfss   INTCON3,INT2IF      ; Skip when INT2 asserts
    bra     INT2_exit
    bcf     INTCON3,INT2IF      ; Clear INT2 assert flag
;
; Put more INT2 handler code here
;
INT2_exit:

    movff   BSR_SAVE,BSR        ; Restore BSR
    movf    WREG_SAVE,W         ; Restore WREG
    movff   STATUS_SAVE,STATUS  ; Restore STATUS
    retfie
;
; High priority interrupt handler
;
ISRH_Handler:
;
; INT0 handler
;
    btfsc   INTCON,INT0IE       ; Skip when INT0 disabled
    btfss   INTCON,INT0IF       ; Skip when INT0 asserts
    bra     INT0_exit
    bcf     INTCON,INT0IF       ; Clear INT0 assert flag
;
; Put more INT0 handler code here
;
INT0_exit:
    retfie  FAST
;
; Main application
;
MAIN_CODE CODE
;
; Initialize main application
;
START:
    clrf    INTCON              ; Disable all interrupts
    clrf    INTCON3
    clrf    PIE1
    clrf    PIE2

    movlw   0x07                ; Turn off comparators
    movwf   CMCON

    movlw   0x0F                ; Set all ADC inputs for digital I/O
    movwf   ADCON1

    movlw   0x07                ; Select 8MHz internal oscillator
    movwf   OSCCON
;
; Setup external interrupt 0 (always a high priority interrupt).
;
    bcf     INTCON,INT0IE       ; disable interrupt source
    bsf     INTCON2,INTEDG0     ; interrupt on low to high edge
    bsf     TRISB,TRISB0        ; Make GPIO pin INT0 an input
    bcf     INTCON,INT0IF       ; clear interrupt request
    bsf     INTCON,INT0IE       ; enable interrupt source
;
; Setup external interrupt 1, low priority
;
    bcf     INTCON3,INT1IE      ; disable interrupt source
    bsf     INTCON2,INTEDG1     ; interrupt on low to high edge
    bsf     TRISB,TRISB1        ; Make GPIO pin INT1 an input
    bcf     INTCON3,INT1IP      ; select low priority
    bcf     INTCON3,INT1IF      ; clear interrupt request
    bsf     INTCON3,INT1IE      ; enable interrupt source
;
; Setup external interrupt 2, low priority
;
    bcf     INTCON3,INT2IE      ; disable interrupt source
    bsf     INTCON2,INTEDG2     ; interrupt on low to high edge
    bsf     TRISB,TRISB2        ; Make GPIO pin INT2 an input
    bcf     INTCON3,INT2IP      ; select low priority
    bcf     INTCON3,INT2IF      ; clear interrupt request
    bsf     INTCON3,INT2IE      ; enable interrupt source
;
; Turn on interrupt system
;
    bsf     RCON,IPEN           ; Select priority interrupt model.
    bsf     INTCON,GIEL         ; Enable low priority interrupt sources
    bsf     INTCON,GIEH         ; Enable high priority interrupt sources
;
; Main process loop
;
main_process_loop:
;
; This is a demo that has nothing
; to do so just loop forever.
;
    goto    main_process_loop

    end

This code tested using the MPLABX v5.25 simulator.
 
<EDIT>
Added suggestions from ric.
post edited by dan1138 - 2019/11/22 12:43:39
#6
ric
Super Member
  • Total Posts : 26135
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/21 19:15:16 (permalink)
+2 (2)
That's a good skeleton to start with that Dan has supplied.
Possibly it needs a comment "; Put your INT0 service code here" immediately before the "INT0_exit:" label.
Similarly, the INT1 and INT2 service code can go immediately before "INT1_exit:" and "INT2_exit:" respectively.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#7
dan1138
Super Member
  • Total Posts : 3402
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/22 00:15:29 (permalink)
+1 (1)
Ric, thanks for the suggestions.

I've realized that any code can be made better with more eyes on it.

Perhaps the Original Poster can take it from here.
#8
Claude van der Ryst
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2019/11/20 09:26:30
  • Location: South Africa
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/22 09:09:42 (permalink)
0
Thanks Ric, 1and0 & Dan. All of your input has guided me in the right direction and I managed to solve my problem.
 
Here is my final code that works:
 

#include "p18f2520.inc"

; CONFIG1H
  CONFIG  OSC = HSPLL           ; Oscillator Selection bits (HS oscillator, PLL enabled (Clock Frequency = 4 x FOSC1))
  CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
  CONFIG  IESO = OFF            ; Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

; CONFIG2L
  CONFIG  PWRT = ON             ; Power-up Timer Enable bit (PWRT enabled)
  CONFIG  BOREN = SBORDIS       ; Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
  CONFIG  BORV = 3              ; Brown Out Reset Voltage bits (Minimum setting)

; CONFIG2H
  CONFIG  WDT = OFF             ; Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
  CONFIG  WDTPS = 32768         ; Watchdog Timer Postscale Select bits (1:32768)

; CONFIG3H
  CONFIG  CCP2MX = PORTC        ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
  CONFIG  PBADEN = OFF          ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital input channels on Reset)
  CONFIG  LPT1OSC = OFF         ; Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
  CONFIG  MCLRE = ON            ; MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

; CONFIG4L
  CONFIG  STVREN = ON           ; Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
  CONFIG  LVP = OFF             ; Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
  CONFIG  XINST = OFF           ; Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode enabled)

; CONFIG5L
  CONFIG  CP0 = OFF             ; Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
  CONFIG  CP1 = OFF             ; Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
  CONFIG  CP2 = OFF             ; Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
  CONFIG  CP3 = OFF             ; Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

; CONFIG5H
  CONFIG  CPB = OFF             ; Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
  CONFIG  CPD = OFF             ; Data EEPROM Code Protection bit (Data EEPROM not code-protected)

; CONFIG6L
  CONFIG  WRT0 = OFF            ; Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
  CONFIG  WRT1 = OFF            ; Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
  CONFIG  WRT2 = OFF            ; Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
  CONFIG  WRT3 = OFF            ; Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

; CONFIG6H
  CONFIG  WRTC = OFF            ; Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
  CONFIG  WRTB = OFF            ; Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
  CONFIG  WRTD = OFF            ; Data EEPROM Write Protection bit (Data EEPROM not write-protected)

; CONFIG7L
  CONFIG  EBTR0 = OFF           ; Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR1 = OFF           ; Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR2 = OFF           ; Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
  CONFIG  EBTR3 = OFF           ; Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

; CONFIG7H
  CONFIG  EBTRB = OFF           ; Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)

RES_VECT  CODE    0x0000        ; processor reset vector
    GOTO    INITIALIZE          ; go to beginning of program

ISR_VECT  CODE    0x0008
  CALL    $+2,FAST              ; WORKAROUND FOR A1 SILICON BUG (DS80209H-PAGE 7)
  POP
  GOTO INT_CNT

MAIN_PROG CODE                  ; let linker place main program

INITIALIZE
 
    BCF TRISC, 6                ;TX AS OUTPUT
    BSF TRISC, 7                ;RX AS INPUT

    ;---CONFIGURE TXSTA
    ;CONFIGURES TXSTA AS 8 BIT TRANSMISSION, TRANSMIT ENABLED, ASYNC MODE, HIGH SPEED BAUD RATE
    MOVLW B'00100100'
    MOVWF TXSTA

    ;---CONFIGURE RCSTA
    MOVLW B'10000000'
    MOVWF RCSTA                 ;ENABLE SERIAL PORT RECEIVE

    ;---CONFIGURE SPBRG FOR DESIRED BAUD RATE
    BCF BAUDCON, BRG16         ;DIVISOR AT 8 BIT
    MOVLW D'112'               ;BAUD RATE =  9600BPS
    MOVWF SPBRG                ;AT 4.332 MHZ & HSPLL

    CLRF INTCON                ;DISABLE ALL INTERRUPTS
    CLRF INTCON3               ;DISABLE ALL INTERRUPTS
    CLRF PIE1                  ;DISABLE PERIPHERAL INTERRUPTS
    CLRF PIE2                  ;DISABLE PERIPHERAL INTERRUPTS
    
    BCF INTCON, RBPU           ;ENABLE PORTB PULL-UPS
    BSF INTCON2,INTEDG0        ;INTERRUPT ON LOW TO HIGH EDGE
    BSF INTCON2,INTEDG1        ;INTERRUPT ON LOW TO HIGH EDGE
    BSF INTCON2,INTEDG2        ;INTERRUPT ON LOW TO HIGH EDGE
    BSF INTCON3, INT1IP        ;ENABLE INT1 HIGH PRIORITY INTERRUPT
    BSF INTCON3, INT2IP        ;ENABLE INT2 HIGH PRIORITY INTERRUPT

    BCF TRISA, 5               ;SET PA5 AS OUTPUT
    BCF LATA, 5                ;LED OFF
    CLRF PORTB                 ;INITIALIZE PORTB BY CLEARING OUTPUT DATA LATCHES
    
    MOVLW 0x0F
    MOVWF ADCON1               ;SET RB<4:0> AS DIGITAL I/O PINS (REQUIRED IF CONFIG BIT PBADEN IS SET)
    
    MOVLW   0x07               ;TURN OFF COMPARATORS
    MOVWF   CMCON
    
    MOVLW 0xFF
    MOVWF TRISB                ;SET PORTB AS INPUT (ALL 8 BITS)
 
    BCF INTCON, INT0IF           ;CLEAR INT0 INTERRUPT FLAG
    BCF INTCON, INT1IF           ;CLEAR INT1 INTERRUPT FLAG
    BCF INTCON, INT2IF           ;CLEAR INT2 INTERRUPT FLAG
    BCF INTCON, RBIF           ;CLEAR PORTB INTERRUPT FLAG
 
    BSF INTCON, INT0IE         ;ENABLE INT0 INTERRUPT
    BSF INTCON3, INT1IE        ;ENABLE INT1 INTERRUPT
    BSF INTCON3, INT2IE        ;ENABLE INT2 INTERRUPT
    BSF INTCON, RBIE           ;ENABLE RB PORT CHANGE INTERRUPT
    BSF RCON,IPEN              ;SELECT PRIORITY INTERRUPT MODEL.
    BSF INTCON, GIEH           ;ENABLE HIGH PRIORITY INTERRUPTS
 
START

    GOTO $                     ; loop forever

INT_CNT

    MOVLW 0x20
    XORWF LATA,F               ;TOGGLE LED
    
    MOVF PORTB, W              ;MOVE PORTB CONTENTS TO WORKING REGISTER
    MOVWF TXREG                ;MOVE WORKING REGISTER TO TXREG
    CALL CHECK_TRMT_EMPTY      ;CHECK IF TRMT IS EMPTY

    BCF INTCON, INT0IF           ;CLEAR INT0 INTERRUPT FLAG
    BCF INTCON, INT1IF           ;CLEAR INT1 INTERRUPT FLAG
    BCF INTCON, INT2IF           ;CLEAR INT2 INTERRUPT FLAG
    BCF INTCON, RBIF           ;CLEAR PORTB INTERRUPT FLAG

RETFIE FAST                    ;RETURN FROM INTERRUPT
    
CHECK_TRMT_EMPTY
    BTFSS TXSTA, TRMT          ;CHECK IF TRMT IS EMPTY
    GOTO CHECK_TRMT_EMPTY      ;IF NOT, CHECK AGAIN
RETURN
    
END

#9
ric
Super Member
  • Total Posts : 26135
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/22 13:58:56 (permalink)
+1 (1)
I assume you're using TRMT to avoid overflowing the USART TXREG.
 
That is a horribly inefficient way to do it. It forces your code to stay in the ISR until the complete character has been shifted out. The whole idea of a peripheral is thatit can do that while you're doing other things.
It's far more efficient to simply wait until the TXREG is available BEFORE you write to it.
That is what the TXIF flag tells you.
You can simply change
    MOVWF TXREG                ;MOVE WORKING REGISTER TO TXREG
    CALL CHECK_TRMT_EMPTY      ;CHECK IF TRMT IS EMPTY

to
TXWAIT:
    BTFSS PIR1,TXIF            ;Test if TXREG ss free
    GOTO  TXWAIT               ;loop if TXREG is busy
    MOVWF TXREG                ;MOVE WORKING REGISTER TO TXREG


I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#10
dan1138
Super Member
  • Total Posts : 3402
  • Reward points : 0
  • Joined: 2007/02/21 23:04:16
  • Location: 0
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/22 16:36:08 (permalink) ☄ Helpfulby Claude van der Ryst 2019/11/23 02:28:41
0
@ric, seems that Claude may be somewhat lost in how to implement the interrupt driven UART interface for a PIC18F2520.
 
It is not that straight forward in C, assembly can be a bit arcane.
 
Do you have any simple examples?
post edited by dan1138 - 2019/11/22 16:41:44
#11
ric
Super Member
  • Total Posts : 26135
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/22 18:28:34 (permalink)
0
dan1138
Do you have any simple examples?

Actually, no. I've never programmed a PIC18F in my life.
I'm a PIC16F man, and just about to stick my toe in the water with a PIC32MM (although I'll let MCC set up the basics, another first time for me...)
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#12
Claude van der Ryst
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2019/11/20 09:26:30
  • Location: South Africa
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/23 02:30:16 (permalink)
0
Hi Ric
 
Only after seeing your new reply and further testing the microcontroller out do I realise how inefficient using TRMT can be. When the interval between the interrupt requests becomes quicker, other interrupt requests doesn't get triggered because the TRMT flag forces the code to stay in ISR.
 
ric
I assume you're using TRMT to avoid overflowing the USART TXREG.
 
That is a horribly inefficient way to do it. It forces your code to stay in the ISR until the complete character has been shifted out. The whole idea of a peripheral is thatit can do that while you're doing other things.
It's far more efficient to simply wait until the TXREG is available BEFORE you write to it.
That is what the TXIF flag tells you.
You can simply change
    MOVWF TXREG                ;MOVE WORKING REGISTER TO TXREG
    CALL CHECK_TRMT_EMPTY      ;CHECK IF TRMT IS EMPTY

to
TXWAIT:
    BTFSS PIR1,TXIF            ;Test if TXREG ss free
    GOTO  TXWAIT               ;loop if TXREG is busy
    MOVWF TXREG                ;MOVE WORKING REGISTER TO TXREG





It is a pitty there isn't always good examples out there. I had a look at a few USART examples on the internet and finally used the following example and just changed the code to make it work for my application: https://www.teachmemicro.com/serial-usart-pic16f877a/
 
I will have a look at my code further and implement your suggestion. As for my original question on INT0/INT1/INT2, I feel it is answered and don't want to confuse others that are looking for help on interrupts on INT0/INT1/INT2. I think that should I have further issues with the code that I should look further into how to implement the USART or start a different threat on the USART if I can't find a solution.
 
Thanks Ric, Dan & 1and0 for your valuable input on the topic and I have learned so much in the last few days.
#13
ric
Super Member
  • Total Posts : 26135
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/23 04:35:49 (permalink) ☄ Helpfulby Claude van der Ryst 2019/11/23 04:51:53
+2 (2)
Claude van der Ryst
...
It is a pitty there isn't always good examples out there. I had a look at a few USART examples on the internet and finally used the following example and just changed the code to make it work for my application: https://www.teachmemicro.com/serial-usart-pic16f877a/

Anyone who waits on TRMT really has not read the USART section of the datasheet properly.

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#14
1and0
Access is Denied
  • Total Posts : 10573
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/23 04:49:41 (permalink) ☄ Helpfulby Claude van der Ryst 2019/11/23 04:51:57
+2 (2)
The only time I've ever used the TRMT bit is to wait for transmission to finish just before going into Sleep mode.
#15
ric
Super Member
  • Total Posts : 26135
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/23 04:50:58 (permalink)
+2 (2)
Or when you have to wait for a half-duplex bus to free, at which point you curse the inability of TRMT to generate an interrupt.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#16
Claude van der Ryst
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2019/11/20 09:26:30
  • Location: South Africa
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/23 04:57:32 (permalink)
0
ric
Claude van der Ryst
...
It is a pitty there isn't always good examples out there. I had a look at a few USART examples on the internet and finally used the following example and just changed the code to make it work for my application: https://www.teachmemicro.com/serial-usart-pic16f877a/

Anyone who waits on TRMT really has not read the USART section of the datasheet properly.




Thanks Ric
 
I found that I have to read a section in the datasheet many times to understand what is carried across to me and sometimes I still don't always understand what is explained. A good solid tried and tested code example works better for me to understand hence I searched for examples on the internet.
#17
ric
Super Member
  • Total Posts : 26135
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/23 05:08:15 (permalink)
+1 (1)
I was referring to the author of that example you linked to ;)
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#18
Claude van der Ryst
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2019/11/20 09:26:30
  • Location: South Africa
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2019/11/23 05:21:17 (permalink)
0
Thanks Ric
 
At least I have a better understanding of how to implement interrupts and the USART.
 
Thanks to everyone who contributed to my solution.
#19
oliverb
Super Member
  • Total Posts : 275
  • Reward points : 0
  • Joined: 2009/02/16 13:12:38
  • Location: 0
  • Status: offline
Re: PIC18F2520 - INT0/1/2 not working 2020/01/15 09:22:33 (permalink)
0
Just thought I'd tack on another interrupts question: I'm looking at a situation where I want to run a timer "tick" interrupt, but I also have an I2C slave interrupt and to reduce I2C clock stretching I really want to give the I2C interrupt "priority" over the timer tick. BTW this is using a 18F25K80, though I'm considering switching to the 26K42
 
Now I get the part that I can enable priority and assign one to each vector, but does that really mean that the high priority interrupt can interrupt the lower one?
 
I'm also aware that my general advice about interrupts is "don't". I might be able to get the results I want with polling.
 
post edited by oliverb - 2020/01/15 09:29:17
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2020 APG vNext Commercial Version 4.5