Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Timer1 not interrupting (16F876)

Status
Not open for further replies.

ChriX

Member
I am having problems when trying to get the Timer1 module to interrupt on overflow.

I know the timer is actually running as I have tested it by polling TMR1IF and it overflows accordingly.

Code:
; Timer1 module setup
		
		clrf TMR1L
		clrf TMR1H

		BANKSEL PIE1
		bsf PIE1,TMR1IE
		bcf PIR1,TMR1IF

		BANKSEL T1CON
		movlw b'00010000'
		movwf T1CON
		bsf T1CON,TMR1ON				; Start the timer

		bsf INTCON,GIE					; Enable interrupts	
		bsf INTCON,PEIE

Code:
ISR
		<my rubbish here>
		BANKSEL PIR1
		bcf PIR1,TMR1IF						; Clear the interrupt bit so it can happen again
		retfie

I had it all working using Timer0 but could not make this overflow slow enough for my needs, basically I have just changed the init section to timer1 and the bit which is reset in the ISR, but now I get nothing.

Thought I had something when searching and found the PEIE bit needs to be set, so I did that and still nothing.

Any ideas?
 
ChriX said:
Code:
ISR
		<my rubbish here>
		BANKSEL PIR1
		bcf PIR1,TMR1IF						; Clear the interrupt bit so it can happen again
		retfie

If this is your actual ISR code then you need to save Status and W. If before you just had a bcf INTCON,T0IF then that would have worked fine but now you have a banksel you need to save the context. See section 12.11 of the data sheet. Apart from that, your code looks fine.

If the above is an abbreviated form of your ISR then ignore everything I've said.

Mike.
 
That is precisely what I had done before, which worked as you say, did not know I had to save W and STATUS myself - thought it was done for me.

Which datasheet? There is no 12.11 in my copy of the 16F87XA datasheet.
 
If you download the data sheet from microchip it's in there. Link to datasheet

This is what it recomends you do.

Code:
interupt        movwf   int_work
                swapf   STATUS,W
                movwf   int_status;	status is nibble swaped

                ;    your stuff here

                swapf   int_status,W
                movwf   STATUS
                swapf   int_work,F;	swap to file
                swapf   int_work,W;	swap to work
                retfie

HTH

Mike.
 
Still having problems :(

Code:
				movwf   int_work
		swapf   STATUS,W
		movwf   int_status;   status is nibble swaped 

		BANKSEL PORTB

		<my stuff>

		BANKSEL PIR1
		bcf PIR1,TMR1IF						; Clear the interrupt bit so it can happen again

        swapf   int_status,W
        movwf   STATUS
        swapf   int_work,F;   swap to file
        swapf   int_work,W;   swap to work 
		retfie

I declared the memory locations for int_status and int_work starting at 0x70, it still doesn't appear to go through the ISR even once. Have uploaded my entire code now, **broken link removed**. Thank you for your help so far Mike.
 
Code:
;***********************
;* Wierd origin stuff  *
;***********************

		org 0x00							; Program starts at program memory location 0x00
		goto MAIN

		org 0x04							; When interrupted, processor looks here - redirect it to my ISR
		goto ISR

When you use "goto ISR" at 0x04, are you absolutely sure that your code will goto the actual ISR which is in the first 2K program memory in the 8K 16F876 memory space?

GOTO and CALL instruction also take into account of the two higher bits in the PCLATH to form the jump address and PCLATH could have other values when interrupt occurs.

You don't have this uncertainty if you put your ISR at 0x04 and do away with the Goto statement.
 
Found one bug here:

Code:
      BANKSEL PIE1 
      bsf PIE1,TMR1IE 
      bcf PIR1,TMR1IF

What you're doing is setting the interrupt enable bit for TMR1IE and immediately clearing it on the next instruction because you forgot to switch banks.

Fix:

Code:
      BANKSEL PIE1 
      bsf PIE1,TMR1IE 
      BANKSEL PIR1 
      bcf PIR1,TMR1IF

This bug is one of the reasons I've moved on to the PIC18 family. Quickly found it using the Mplab simulator and after you posted your full source code.
 
Motion, well spotted, that should fix it. I was wondering how the rest of his code was working with a ISR that wasn't saving context.

Mike.
 
That has fixed it, thanks very much. I can remember myself reading the memory map and seeing (or not!) that PIR was in the same bank as PIE, then when I looked again just now it's moved! :lol:

Anyway, thanks again guys.
 
Status
Not open for further replies.

Latest threads

Back
Top