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.

Don't care

Status
Not open for further replies.
Yep, I remember reading that long ago (grin).

You'll get the same results with pre:1 and post:16 Mike.

BTW, like Nigel, I prefer using the "set and forget" TMR2 for periodic interrupts (1.0-msec for me) for many simple standard tasks in an ISR (switch debounce, beep, RTC, timer functions, etc.)
 
Last edited:
Mike said:
I prefer using the "set and forget" TMR2 for periodic interrupts (1.0-msec for me) for many simple standard tasks in an ISR (switch debounce, beep, RTC, timer functions, etc.)

How does this work exactly? (shell we start a new thread?)
 
You simply setup the Timer 2 control registers, PR2 register, and interrupt registers in the initialization section of your code. Then process the periodic interrupts in your ISR.

Sorry if I may have caused you any confusion...
 
Mike said:
You simply setup the Timer 2 control registers, PR2 register, and interrupt registers in the initialization section of your code. Then process the periodic interrupts in your ISR.

That's what I usually do :) Thanks.


I will ask an opinion on TMR2 operation later :)
 
Last edited:
Should you want slower interrupts then look at the "special event trigger" of the PWM module. This provides for a 16 bit period using Timer1. Again it is a set and forget timer. This is the timer I normally use for precision timing operations. Embarrassingly, you load it with N-1 as it too resets on the next increment.

Mike.
 
I thought:
Code:
	org	0x0000
	goto	Initialize

	org	0x0004
Interrupt
	movwf   w_temp
	swapf   STATUS,   w
	clrf	STATUS
	movwf   s_temp
	movf	PCLATH,   w
	movwf   p_temp
	clrf	PCLATH

	btfss   PIR1,TMR2IF
	goto	Int_Re

	bcf	PIR1,TMR2IF
;.
;.
;.
;.
;.
;.
;.
Int_Re
	movf	p_temp,   w
	movwf   PCLATH
	swapf   s_temp,   w
	movwf   STATUS
	swapf   w_temp,   f
	swapf   w_temp,   w
	retfie

Initialize
;.
;.
;.
	bcf	STATUS,   RP0
	movlw	b'00011101'               ;Prescale*postscale=16
	movwf   T2CON
	bsf	STATUS,   RP0
	movlw   d'245'
	movwf	PR2

	bsf	PIE1,   TMR2IE
	bcf	STATUS,   RP0
	bsf	INTCON,   PEIE
	bsf	INTCON,   GIE
;.
;.
;.
Main
;.
;.

I thought everything happens in the interrupt vector (from label Interrupt to Initialize) need to be considered? Because they happen around every 4ms, and take around 17 us to execute?
I have tried with PR2 set to 249, prescaler 4 and postscaler 4, in the interrupt vector, I increment 1 to a defined constant every time interrupt occurs, up to 250 times as 1 second. Then I tested my counter for 7 hours count down. When the counter count to 0, my stop watch showed 7 hours and 7 second. It means it delay for 1 second for every hour.
So I did calculation below:

[(1 us x Prescaler x Postscaler x PR2) + z] x 250 x 3600 = 3601 seconds
where z is the time taken for the instruction in the interrupt vector to be executed and 3600 is 1 hour. So:
[(1us x 4 x 4 x 249) + z] x 250 x 3600 = 3601
then I know my z is fixed (approximately 17 us) and I have to change PR2 and the '250' to get the nearest.

Am I doing wrongly?

Thanks
 
I just compiled your code in MPLAB and made a few changes - set PR2 to 249 and added a counter set to 250. Setting a breakpoint in the counter reload code gave me exactly 1 second intervals. Try it in the simulator with the stopwatch.

Here's the code,
Code:
	include	"P16F628.inc"

	cblock	0x20
Count

w_temp
s_temp
p_temp

	endc



	org	0x0000
	goto	Initialize

	org	0x0004
Interrupt
	movwf   w_temp
	swapf   STATUS,   w
	clrf	STATUS
	movwf   s_temp
	movf	PCLATH,   w
	movwf   p_temp
	clrf	PCLATH

	btfss   PIR1,TMR2IF
	goto	Int_Re

	bcf	PIR1,TMR2IF

	decfsz	Count,F
	goto	Int_Re
	movlw	d'250'
	movwf	Count;	set breakpoint here

;.
Int_Re
	movf	p_temp,   w
	movwf   PCLATH
	swapf   s_temp,   w
	movwf   STATUS
	swapf   w_temp,   f
	swapf   w_temp,   w
	retfie

Initialize
;.
	bcf	STATUS,   RP0
	movlw	b'00011101'               ;Prescale*postscale=16
	movwf   T2CON
	bsf	STATUS,   RP0
	movlw   d'249'
	movwf	PR2

	bsf	PIE1,   TMR2IE
	bcf	STATUS,   RP0
	bsf	INTCON,   PEIE
	bsf	INTCON,   GIE
;.
;.
;.
Main	goto	Main
;.
;.

	end

HTH

Mike.
 
Yes, I do something similar to this. But the time taken to execute the instructions in the interrupt vector don't need to be counted? In my case, I use the interrupt vector to do multiplexing for four 7-segment display, and do counting down. These codes are located just before setting the break point (after bcf PIR1,TMR2IF)

Thanks
 
I have tried with PR2 set to 249, prescaler 4, postscaler 4 and a counter 250, and tested for 7 hours. But it lag for 1 second for every hour. After changing PR2 to 245 and a counter to 254, it becomes more accurate. I've tested for 10 hours, it lag for 1.x second for every ten hour.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top