PIC18F4550, A/D Interrupts, Assembly Language

Click For Summary
SUMMARY

The discussion focuses on implementing A/D interrupts on the PIC18F4550 microcontroller to control an LED blinking at RA1 based on a potentiometer connected to RA0. The user reports that the Interrupt LED functions correctly for approximately 30 cycles before ceasing to respond to potentiometer changes, with only the Main LED blinking thereafter. Despite attempts to reset the A/D interrupt flag and enable bits, the issue persists, indicating a potential flaw in the interrupt handling code or configuration.

PREREQUISITES
  • Understanding of PIC18F4550 microcontroller architecture
  • Familiarity with assembly language programming for embedded systems
  • Knowledge of A/D conversion processes and interrupt handling
  • Experience with configuring microcontroller peripherals
NEXT STEPS
  • Review PIC18F4550 A/D interrupt configuration settings
  • Learn about the PIC18F4550 interrupt vector table and its implications
  • Investigate common pitfalls in A/D interrupt routines in assembly language
  • Explore debugging techniques for embedded assembly code on PIC microcontrollers
USEFUL FOR

Embedded systems developers, assembly language programmers, and engineers working with PIC microcontrollers who are troubleshooting A/D interrupt issues.

El Moriana
Messages
33
Reaction score
0
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.

The circuit/hardware works fine; I have managed to use the pot to make the LED blink without interrupts (i.e. using a loop waiting for conversion to finish).
I have tried resetting the AD Interrupt flag and ADC enable bits, no effect.

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=========
 
Physics news on Phys.org
I might be able to help you. can you show me the circuit you drew?
 
NP
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 9 ·
Replies
9
Views
4K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 9 ·
Replies
9
Views
3K
  • · Replies 2 ·
Replies
2
Views
7K
  • · Replies 10 ·
Replies
10
Views
4K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K