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.

PIC timer interrupt

Status
Not open for further replies.

st222

New Member
ok. i'm trying to get my hands dirty with PIC assembly (using MPLAB).

I'm trying timer interupt. i want toggle LED every 1000 operations and this how i think about it:

1. Use Timer1 Overflow interrupt.
2. load Timer1 with initial value of 65535 - 1000 = 64535 and let it run, and thus it will run 1000 times and overflow.

I'm just wondering if this is the best way to go. any help/ideas?

Regards,
 
Be easier to use timer 0 and designate a counter to run as a post scaler. Preload the counter with the value of 4, and each time the timer overflows and jumps to the interrupt, the counter gets decremented, then goes back to main code until the counter = 0. Once the counter = 0, the LED gets toggled. This will toggle the LED every 1024 operations. A little bit longer than 1000 but it won't be human perceivable.

Not sure which PIC you're using but here's a code example that illustrates how you would pull this off. This code would toggle RB2 every 1024 operations -

Code:
		cblock		0x70
				W_TEMP
				STATUS_TEMP
				PCLATH_TEMP
				T0COUNT
		endc

;***********************************************************************************

		org		0x0000		;reset vector
		goto		START

;***********************************************************************************

		org		0x0004		;interrupt vector

;interrupt handler

ISR		movwf		W_TEMP		;save W
		swapf		STATUS,W	;save STATUS
		movwf		STATUS_TEMP
		banksel		0		;bank 0
		movfw		PCLATH		;save PCLATH
		movwf		PCLATH_TEMP

;***********************************************************************************

		btfsc		INTCON,T0IF	;timer 0 interrupt?
		call		T0INT		;yes, service timer 0 interrupt
		goto		ISRExit		;no, exit isr

;***********************************************************************************

T0INT		decfsz		T0COUNT,F	;decrement post scale counter
		goto		T0INTExit

		movlw		0x04		;reload post scale counter
		movwf		T0COUNT
		movlw		b'00000100'	;toggle RB2
		xorwf		PORTB,F
		bcf		INTCON,T0IF	;clear timer 0 interrupt flag
T0INTExit	return

;***********************************************************************************

ISRExit		movfw		PCLATH_TEMP	;restore PCLATH
		movwf		PCLATH
		swapf		STATUS_TEMP,W	;restore STATUS
		movwf		STATUS
		swapf		W_TEMP,F	;restore W
		swapf		W_TEMP,W
		retfie				;return to main code

;***********************************************************************************

;initialization routine

START		clrf		PORTA		;clear port latches
		clrf		PORTB
		banksel		TRISA		;bank 1
		clrf		TRISB		;port b output
		movlw		0xC8		;init timer 0, set up as timer, 1:1 prescale
		movwf		OPTION_REG
		banksel		0

		movlw		0x04		;load post scale counter
		movwf		T0COUNT	
		clrf		TMR0		;init timer 0
		movlw		b'10100000'	;clear timer interrupt flag, enable
		movwf		INTCON		;timer 0 interrupt

;continue with code here
 
Last edited:
Hi Jon,

Thanks for the reply.

Sorry i didn't clarify the question. but 1000 was just an example. I may want to explore and change 1000 to say 1600, or 1500 operations. i'm using pic16f690.
 
You need to configure timer 1 to run from the instruction cycle clock.

And configure timer one to interrupt on overflow by enabling t1ie flag.

In the interrupt routine you need to reset timer1 interrupt flag t1if, and load your required value into timer1.

Youi can then use xor or whatever to toggle the led output, followed by the cutomary retfie command.

At the start of your program listing (in asm that is) you need to put your start and int vectors, heres what I do:

org 0
goto start

org4
goto int

<program listing continues here>

Then your main program is a sub called 'start' and your interrupt sub is 'int', int will be jumped to every time an interrupt is generated by the timer.

A lot of my programs are totally controlled via interrupts, the main code is just 'here goto here', the int sub just calling functions every so often.
 
Last edited:
Look up the PWM special event trigger. With that you can make timer1 have any period you like.

BTW, doing org 4: goto int is a disaster waiting to happen. Always save PCLATH and clear it before the goto or you will get nasty crashes once you use any bank but zero.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top