PDA

View Full Version : Intermittent code cannot run



Pic2008
- 7th November 2008, 11:30
When I first power ON the PIC16F877, sometimes I don't see the LED turn ON, which means my code not running. Anything wrong?



include "modedefs.bas"

define osc 20

asm
device pic16f877,hs_osc,BOD_OFF,wdt_off,pwrt_on,protect_o ff
endasm

clear

ADCON1=%00000111 'PIC16F877 turn off analog comparator,
OPTION_REG.7 = 0 'enable internal pull up GPPU
OPTION_REG.6 = 0 'falling edge INT
TRISB = %00010001
'*********************** ASSEMBLY INTERUPT VARIABLES ***********************
wsave var byte $20 system
wsave1 var byte $a0 system ' Necessary for devices with RAM in bank1
wsave2 var byte $120 system ' Necessary for devices with RAM in bank2
wsave3 var byte $1a0 system ' Necessary for devices with RAM in bank3
ssave var byte bank0 system
psave var byte bank0 system

a var byte
b var byte
c var byte
d var byte
task var byte
enc_counter var word
RxD var PORTC.7
TxD var PORTC.6
led var PORTE.2

goto start 'skip over interupt handler

'*********************** ASSEMBLY INTERUPT HANDLER *************************

define INTHAND myint
Asm

myint

; Save W, STATUS and PCLATH registers, if not done previously
;movwf wsave
;swapf STATUS, W
;clrf STATUS
;movwf ssave
;movf PCLATH, W
; movwf psave

movlw high 100 ; Wait 100us to debounce encoder
movwf R0 + 1
movlw low 500
call PAUSEUSL

incf _d, w ;d dummy counter
nop
movwf _d


incfsz _enc_counter,W ; Add one to low byte
decf _enc_counter+1,F ; No carry (negates next step)
incf _enc_counter+1,F ; Add one to high byte
movwf _enc_counter ; Store updated low byte back.
iorwf _enc_counter+1,W ; Set Z flag


bsf _led ;turn on led


; Restore saved registers

movf psave, W
movwf PCLATH
swapf ssave, W
movwf STATUS
swapf wsave, F
swapf wsave, W

bcf INTCON, INTF
bcf INTCON, RBIF ; Clear the Interupt Flag
RETFIE ; Return from interrupt
endasm


start:
intcon=%10011000 ' enable int
a= 1

high led
pause 500
low led

duncan303
- 7th November 2008, 11:45
When I first power ON the PIC16F877, sometimes I don't see the LED turn ON, which means my code not running. Anything wrong?



include "modedefs.bas"

define osc 20

asm
device pic16f877,hs_osc,BOD_OFF,wdt_off,pwrt_on,protect_o ff
endasm

clear

ADCON1=%00000111 'PIC16F877 turn off analog comparator,
OPTION_REG.7 = 0 'enable internal pull up GPPU
OPTION_REG.6 = 0 'falling edge INT
TRISB = %00010001
'*********************** ASSEMBLY INTERUPT VARIABLES ***********************
wsave var byte $20 system
wsave1 var byte $a0 system ' Necessary for devices with RAM in bank1
wsave2 var byte $120 system ' Necessary for devices with RAM in bank2
wsave3 var byte $1a0 system ' Necessary for devices with RAM in bank3
ssave var byte bank0 system
psave var byte bank0 system

a var byte
b var byte
c var byte
d var byte
task var byte
enc_counter var word
RxD var PORTC.7
TxD var PORTC.6
led var PORTE.2

goto start 'skip over interupt handler

'*********************** ASSEMBLY INTERUPT HANDLER *************************

define INTHAND myint
Asm

myint

; Save W, STATUS and PCLATH registers, if not done previously
;movwf wsave
;swapf STATUS, W
;clrf STATUS
;movwf ssave
;movf PCLATH, W
; movwf psave

movlw high 100 ; Wait 100us to debounce encoder
movwf R0 + 1
movlw low 500
call PAUSEUSL

incf _d, w ;d dummy counter
nop
movwf _d


incfsz _enc_counter,W ; Add one to low byte
decf _enc_counter+1,F ; No carry (negates next step)
incf _enc_counter+1,F ; Add one to high byte
movwf _enc_counter ; Store updated low byte back.
iorwf _enc_counter+1,W ; Set Z flag


bsf _led ;turn on led


; Restore saved registers

movf psave, W
movwf PCLATH
swapf ssave, W
movwf STATUS
swapf wsave, F
swapf wsave, W

bcf INTCON, INTF
bcf INTCON, RBIF ; Clear the Interupt Flag
RETFIE ; Return from interrupt
endasm


start:
intcon=%10011000 ' enable int
a= 1

high led
pause 500
low led



did you want the led to flash or just come on only once? maybe a goto (somewhere) at the end of the start: routine to create a loop somewhere otherwise the program just ends.

also always good practice to place END at the very end of all programs.

As for the intermittent part try a pause somewhere near the begining of the prog to allow the pic to "settle"

HTH

______

Pic2008
- 7th November 2008, 12:18
Actually I have other code after the LOW led. After many trial and error, if i remove intcon then this problem will not occur.
But this is not the solution because I need the interrupt to enable for it to increment the enc_counter.

Darrel Taylor
- 8th November 2008, 02:45
Calling PBP library routines from ASM interrupt handlers, is generally not a good idea.

The commands will overwrite PBP's system variables in the middle of working on another command in the main program. The effects are completely unpredictable.

In your case, the only system var used by PAUSEUSL is R0. So if you save and restore the R0 Word variable much like psave and ssave, it should work better.
<br>