AGCB
Member
This is a simple A/D program w/ an ad interrupt. But the only way it will work is with the 1 second delay ( in the main loop section). If I put any other delay code in, even if it's the same time value, it will not work. It doesn't seem to have anything to do w/ the time.
It does not seem that it should need any delay at this point since the interrupt should work in the circle loop. I can not see anything in that delay routine that is different from the other routines.
Can you solve my puzzle?
Code:
list p=18f1220
#include <p18f1220.inc>
;config options at end of program
config osc = intio2, fscm = off, ieso = off ;1h
config pwrt = on, bor = on, borv = 27 ;2L
config wdtps = 1, wdt = off ;2h
config mclre = off ;3h
config stvr = off, lvp = off, debug = off ;4L
;default code protection off ;5L, 5h
;default write protection off ;6L, 6h
;default table read protection off ;7L, 7h
radix hex
;-----------------------------------------------------------------------------
;----------cpu equates (memory map)-------------------------------------------
cblock 0x000
endc
;-------------------------------------------------------------------------------
org 0x0000
goto start
org 0x0008 ;comment out if no interrupts
goto isr_high ; isr_high is compatabilty mode also
start movlw 0x60 ;internal osc 4.0 MHz
movwf osccon
bcf adcon0,ADON ;turn off AD
setf adcon1 ;digital I/O
bcf intcon,gie
clrf trisa
clrf trisb ;all outputs
bsf trisb,4 ;AN6 ad input
clrf latb ;
clrf portb ;all pins low
clrf porta
movlb 0x00 ;work in bank 0 GPRs
;----END OF BASIC INIT---------------------------------------------
;init usart----------------------------------
movlw .51 ;4800 baud
movwf SPBRG
movlw b'00100100' ;8 bit, txen, async, high speed
movwf txsta
bsf rcsta,spen ;enable serial port and pins RX/TX
;---interrupt set up-----------------------------------------
bsf intcon,gie
bsf intcon,peie
bcf pir1,adif
bsf pie1,adie
;---A/D set up ----------------------------------------------
movlw b'00011000' ;internal Vref, channel 6 (AN6/Rb4) , ad off
movwf adcon0
movlw b'00111111' ;analog input(0) on AN6/Rb4 (set tris bit also)
movwf adcon1 ; all pins digital I/O except AN6
movlw b'00100011' ;left justify (8 bit mode), 8 Tad, Frc (a/d rc clock)
movwf adcon2
;================ Main loop==================================
meas clrf adresh
movlw .6 ;20 us delay (acuisition time
rcall us_delay_lo
bsf adcon0,adon ;turn on a/d
bsf adcon0,1 ;set GO/NOT DONE bit start conversion
movlw .1 ;for some reason it won't work w/o this delay
rcall adj_delay_sec ;
circle bra circle ;wait for interrupt
;=================Sub routines here=========================
;=================ISERV here================================
;------------SAVING context, W ,status and bsr registers
; ! CONTEXT SAVING IS AUTOMATIC for isr_high when intcon,peie
; is enabled (or) when priority interrupts are disabled
;-------------------------------------------
isr_high ;auto context save
;(Insert user code here )
bcf pir1,adif
movff adresh,txreg
test1 btfss txsta,trmt
bra test1
retfie fast ;return from interrupt using using auto context saving
;---------------------------------------------
isr_low
cblock
w_temp
status_temp
bsr_temp
endc
MOVWF W_TEMP ;Copy W to TEMP register
movff status,status_temp
movff bsr,bsr_temp
;(Insert user code here )
;-------------Restore context--
movff bsr_temp,bsr
movf w_temp,w
movff status_temp,status
retfie
;=================DELAYS here===============================
; DO NOT allow interrupts while in timing loops
; bcf intcon,gie ;disable interrupts
; bsf intcon,gie ;enable interrupts
;COMBO of sec and mS delays--------------------------
;-------------Adjustable delay-----1-255 seconds (4 1/4 min)
; ;enter with number of seconds in wreg before CALL
;i.e. movlw d'xx'
cblock
bc1
bc2
bc3
dc1
dc2
dc3
secs
endc
adj_delay_sec
bcf intcon,gie ;disable global interrupts
movwf secs
repet call delay_ms
decfsz secs ;1 loop per number entered with in wreg
goto repet ;
bsf intcon,gie ;enable global interrupts
return
delay_ms
movlw d'100' ;
banksel bc3 ; Each loop here takes 1 SECOND
movwf bc3 ;
dly2 movlw .13 ;
movwf bc2 ;
clrf bc1 ;
dly1 decfsz bc1,f ;
goto dly1 ;
decfsz bc2,f ;
goto dly1 ;
decfsz bc3,f ;
goto dly2
return
;------Adjustable delay-----10-2550ms(2.55 seconds)------------
; delay = W x 10ms
; enter with multiplier in WREG before CALL
;i.e. movlw d'xx'
adj_delay_ms
bcf intcon,gie ;disable global interrupts ; delay W x 10ms
banksel dc3 ; Wx10.015ms
movwf dc3
dly2a movlw .13 ; repeat inner loop 13 times
movwf dc2 ; -> 13x(767+3)-1 = 10009 cycles
clrf dc1 ; inner loop = 256x3-1 = 767 cycles
dly1a decfsz dc1,f
goto dly1a
decfsz dc2,f ; end middle loop
goto dly1
decfsz dc3,f ; end outer loop
goto dly2a
bsf intcon,gie ;enable global interrupts
return
;---uS_delay_lo-----7 - 771 uS ( in steps of 3-----
;enter with << 1/3 (desired delay minus 3) >> in W (1 - 255) decimal
;round to nearest whole number
;I.E. desired = 66uS Enter w/ (66 minus 3)/3 in W = 21
cblock
cy
endc
us_delay_lo
bcf intcon,gie
movwf cy ;1 cycle
cy1 decfsz cy ;1 cycle, 2 if result is 0
goto cy1 ;2 cycles
bsf intcon,gie
return ;2 cycles
;call insruction adds 2 more!!
END
Can you solve my puzzle?