How to make a PIC18F4550 use A/D interrupts to blink an LED

Thread Starter

Halim.Akiki

Joined Dec 29, 2014
44
1. What I am trying to do
I am attempting to make a PIC18F4550 use A/D interrupts to blink an LED at RA1. [Interrupt LED]
The frequency of the blinking LED is determined by a potentiometer linked to RA0.
To gauge when the loop is outside of the interrupt routine, I have added an LED at RA2 that is set to blink when the program loops in the main code. [Main LED]

2. The Problem
The Interrupt LED blinks properly, responding to potentiometer changes for 30 or so cycles, after which, only the Main LED blinks, unresponsive to potentiometer changes.
It seems clear that the code no longer interrupts after a point and the main code loops thereafter.
However, I am at a loss at what causes the code to stop interrupting.

3. Code

Code:
;=========PROGRAM INFORMATION=========
;Designed to sense voltage from pot, convert to digital and use result to set delay time of a blinking LED.
;Run off internal oscillator - 1MHz mode (default int osc)
;Conversion voltage references set to VDD and VSS
;Analog input in RA0
;Blinking LED positioned RA1
;Main loop test-LED positioned RA2 (visual cue of looping main code)

;=========PIC SPECIFIC IMPORTS=========
#include<P18F4550.INC>

;=========CONFIGURATION BITS=========
    CONFIG WDT = OFF    ; watchdog timer off
    CONFIG MCLRE = OFF  ; MCLR pin off, no debugging, no need to set pin hi
    CONFIG DEBUG = OFF  ; debug mode off
    CONFIG FOSC = INTOSCIO_EC   ; internal oscillator
    CONFIG XINST = OFF  ; disable extended instruction set
    CONFIG CP0 = OFF    ; disable code protection
    CONFIG LVP = OFF    ; disable low voltage programming

;=========VARIABLE DECLARATION=========
Delay1 res 2    ;delay loop variables
DelTmr res 2    ;delay loop multiplier, will be influenced by result of A/D conversion

;=========VECTORS=========
        ;RESET
RESET_VECTOR    CODE    0x0000
        goto    init    ; go to initialisation

        ;INTERRUPT
INT_VECTOR      CODE    0x0008
        ;Blink + Delay
        btg     LATA, LATA1 ; blink RA1
        call    delay
      
        ;Reset interrupt
        ;bcf        PIR1, ADIF  ; clear A/D interrupt flag [no effect]
        ;bsf        PIE1, ADIE  ; enable A/D interrupt [no effect]
        bsf     INTCON, GIE ; enable interrupts

        goto    main    ; return to main loop

;=========METHODS=========
;DELAY
delay:  movff ADRESH, DelTmr ;move 8bit A/D result to DelTmr
      
        infsnz  DelTmr, F   ; make sure no overflows occur
        decf    DelTmr, F   ;

dloop:  decfsz  Delay1
        goto    dloop
        decfsz  DelTmr
        goto    dloop

        return

;=========INITIALIZATION=========
        ;Pins
init:   clrf    PORTA   ; clear porta
        clrf    TRISA   ; porta > outputs
        clrf    LATA    ; clear porta latch
        bsf     TRISA, TRISA0   ; RA0 > input
      
        ;No Internal Osc selection, will keep osc at 1MHz

        ;A/D Module
        movlw   b'00001110' ; AN0 set to analog input + VSS,VDD ref.
        movwf   ADCON1      ;
        clrf    ADCON0     ; select AN0 (channel 0) as A/D channel
        movlw   b'00001000' ; results are left-justified, Tac = 2*Tosc
        movwf   ADCON2      ;
      
        bsf     ADCON0,ADON ; enable A/D Conversion Module
      
        ;Interrupts
        bcf     RCON, IPEN  ; disable interrupt priority
        bsf     INTCON, PEIE    ; enable peripheral interrupts
        bcf     PIR1, ADIF  ; clear A/D interrupt flag
        bsf     PIE1, ADIE  ; enable A/D interrupt
        bsf     INTCON, GIE ; enable interrupts globally
      
;=========MAIN CODE=========
main:   bsf     ADCON0, GO_DONE ; start A/D Conversion

inf:      
        btg     LATA, LATA2 ; blink RA2
        call    delay       ;

        goto    inf ; infinite loop

        END
;=========END OF CODE=========
Moderators note: please use code tags for pieces of code
 
Last edited by a moderator:
Top