I embedded comment within your message and also supplied whole program at end that uses 16f88 and blinks LED on PORTA. It uses 32kHz crystal for TMR1 and 4MHz INTOSC for program execution. Rikard Bosnjakovic wrote: > A project of mine is almost finished. The final(?) problem seems to be > I cannot get the interrupt working properly. Consider this (extracted) > code: > > > init > banksel INTCON ; Clear all but Timer1 > interrupt-masks > clrf INTCON > clrf PIE1 > clrf PIE2 > bsf PIE1, TMR1IE > bsf INTCON, GIE ; Enable global > interrupts Be careful, you should initialize everything before enabling interrupts or it could fly into your ISR right here. > > banksel T1CON ; Setup Timer1 > bsf T1CON, T1OSCEN ; Enable internal > oscillator bsf T1CON, TMR1CS ; Use > external clock (built-in 32kHz) > > call delay_5_secs > > bsf T1CON, TMR1ON ; Start > timer1-oscillator > > mainloop: > goto mainloop ; Just for the sake > of nothing > > isr_code Is there an ORG statement or something here to place the ISR at 0x004? > bsf TMR1H, 7 ; set TMR1H to 0x80 > > context_save ; save > variables/status etc I think it would be a good idea to save context as the very first thing when entering ISR. Also to be sure to switch to BANK0 in case main level code happened to be in BANK1 temporarily. > > bcf INTCON, INTF ; Clear hardware > interrupt flag > > btfsc PIR1, TMR1IF ; Did Timer1 overflow? > call once_a_sec ; Yes, do our > timer-stuff > > context_restore ; restore variables > retfie > > once_a_sec > bcf PIR1, TMR1IF ; Reset interrupt flag > bcf PORTA, 4 ; turn off the red LED > bsf PORTA, 5 ; turn on the green led > return > > > Expected behaviour: After the PIC is switched on and after a delay of > 5 secs (it's there to ensure proper oscillator-startups), the red led > should be turned off and the green turned on. > > What's happening: The red LED keeps on being lit, which means that > I've either done the init wrong and the ISR is never called, or the > ISR is wrong. > > I am using the internal 32kHz-oscillator in the 16F886-chip. Or, > that's atleast what I want to. > > Are there any obvious errors I've done? Here is a sample that should be fairly easy to convert to your model PIC. I think it is a good example of how to save context, use ISR and initialize TMR1. ;--------------------------------------------------------------------------------------------- ; HEADER: ;--------------------------------------------------------------------------------------------- LIST P=16f88 RADIX DEC INCLUDE "p16f88.inc" ;Program Configuration Register 1 __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO ;Program Configuration Register 2 __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;--------------------------------------------------------------------------------------------- ; EQUATES: ;--------------------------------------------------------------------------------------------- STARTOFRAM equ 0x20 ;First Usable RAM Location (Bank 0) ENDOFRAM equ 0x6F ;Last Usable RAM Location (Bank 0) FIXEDAREA equ 0x70 ;Start of shared memory between banks BANK1RAM equ 0xA0 ;Start of Bank 1 RAM ENDOFBANK1 equ 0xEF ;End of Bank 1 RAM cblock STARTOFRAM ;Application specific variables temp endc cblock FIXEDAREA ; Make sure we can always get to these ; ; ISR Register Save Areas ; INT_FLAGS W_TEMP STATUS_TEMP FSR_TEMP PCLATH_TEMP endc ;--------------------------------------------------------------------------------------------- ; ENRTY POINTS: ;--------------------------------------------------------------------------------------------- org 0x000 goto Start ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII ; ; ISR ; ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII org 0x004 ; Interrupt handler right here movwf W_TEMP ;Save everything swapf STATUS, W movwf STATUS_TEMP movfw FSR movwf FSR_TEMP movfw PCLATH movwf PCLATH_TEMP bcf STATUS, RP1 bcf STATUS, RP0 ; Bank 0 btfsc PIR1, TMR1IF ;Is it a TMR1 interrupt goto Timeout ;Yes goto IntExit ;----------------------------------------------------------------------------- ; ; ISR routines ; ;----------------------------------------------------------------------------- ;------------------------------------------------------------------------------ Timeout ; toggle LED pin movfw PORTA xorlw 0x01 movwf PORTA ; wait for TMR1L to increment so that we only change on TMR1H when the clock input is high movfw TMR1L movwf temp ; Save a copy of TMR1L WaitForTMR1ToChange: movfw TMR1L ; xorwf temp,W ; Has TMR1L changed? skpnz goto WaitForTMR1ToChange ; Reload TMR1H for rollovers ; movlw 0xC0 ; Preload for 1/2 second rollover movlw 0x80 ; Preload for 1 second rollover ; movlw 0x00 ; Preload for 2 second rollover movwf TMR1H bcf PIR1, TMR1IF ; Clear interrupt flag goto IntExit ;------------------------------------------------------- IntExit movfw PCLATH_TEMP movwf PCLATH movfw FSR_TEMP movwf FSR swapf STATUS_TEMP, W movwf STATUS swapf W_TEMP, F swapf W_TEMP, W retfie ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ; ; Main Level Code ; ;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM Start bcf STATUS, RP1 bsf STATUS, RP0 ; Switch to Bank 1 movlw b'00000000' ; All pins output movwf TRISA & 0x7F movlw b'00000000' ; All pins output movwf TRISB & 0x7F ; movwf WPU & 0x7F movlw 0x00 ; All pins digital i/o for now movwf ANSEL & 0x7F ; movlw b'01110000' ;Set internal osc to 8Mhz movlw b'01100000' ;Set internal osc to 4Mhz ; movlw b'00000000' ;Set internal osc to 31khz movwf OSCCON & 0x7F bcf STATUS, RP1 bcf STATUS, RP0 ; Switch to Bank 0 clrf PORTA ; Drive all pins low clrf PORTB call TMR1Init bsf INTCON, GIE ; Turn on GLOBAL Interrupts Main ; sleep ; Your choice, makes no difference nop goto Main ;------------------------------------------------------------------------ ; ; Timers and Stuff ; ;------------------------------------------------------------------------ TMR1Init ; ; Setup for using external crystal movlw b'00001110' ; TMR1 oscillator off, and timer stopped, prescale /1 ; |||||||+-------------- TMR1ON (started later) ; ||||||+--------------- TMR1CS (external 32768 crystal) ; |||||+---------------- /T1SYNC (unsynchronized for sleep) ; ||||+----------------- T1OSCEN (enabled) ; |||+------------------ T1CKPS0 ; ||+------------------- T1CKPS1 ; |+-------------------- TMR1GE (T1RUN on 16F88) ; +--------------------- T1GINV (Unused on 16F88) movwf T1CON ; Clear the timer registers clrf TMR1H clrf TMR1L ; Clear the interrupt flag bcf PIR1, TMR1IF ; Enable peripheral interrupts bsf INTCON, PEIE ; Enable TMR1 interrupts bcf STATUS, RP1 bsf STATUS, RP0 ; Select Bank 1 bsf PIE1 & 0x07F, TMR1IE ; Turn on TMR1 ints bcf STATUS, RP1 bcf STATUS, RP0 ; Select Bank 0 ; Turn on Timer 1 bsf T1CON, TMR1ON ; Start timer running return end -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist