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.

Is my Interrupt Service Routine too big or not?

Status
Not open for further replies.

Suraj143

Active Member
Hi guys I made a 4 digit counter. If there is an input in the interrupt pin (RB0) it will increment the display one by one.

It’s working well. I want to know is my ISR ok or is it too long?
Because I want to count very speedy inputs when given to it.

Thanks

Here is the digits updating part within the ISR routine.

Code:
	org	0004h
	movwf	w_temp		;save W
	movf	STATUS,W
	movwf	status_temp	;save status	
				
		
Zeroa	incf	Digit0,F	;increment digit0
	movf	Digit0,W
	bcf	STATUS,Z
	xorlw	.10
	btfss	STATUS,Z	;check digit0 has reached 10
	goto	Leave		;No then leave
	clrf	Digit0		;YES clrf digit0 and- 
	bsf	Dselect,1	;set bit 1 in Digit select register
				
Onea	incf	Digit1,F	;increment digit1
	movf	Digit1,W
	bcf	STATUS,Z
	xorlw	.10
	btfss	STATUS,Z	;check digit1 has reached 10
	goto	Leave		;No then leave
	clrf	Digit1		;YES clrf digit1 and- 
	bsf	Dselect,2	;set bit 2 in Digit select register
				
Twoa	incf	Digit2,F	;increment digit2
	movf	Digit2,W
	bcf	STATUS,Z
	xorlw	.10
	btfss	STATUS,Z	;check digit2 has reached 10
	goto	Leave		;NO then leave
	clrf	Digit2		;YES clrf digit2 and-
	bsf	Dselect,3	;set bit 3 in Digit select register
						
Threea	incf	Digit3,F	;increment digit3
	movf	Digit3,W
	bcf	STATUS,Z
	xorlw	.10
	btfss	STATUS,Z	;check digit3 has reached 10
	goto	Leave		:NO then leave
	clrf	Digit3		;YES clrf digit3 and-
	clrf	Dselect		;sclear the Digit select register
	goto	Leave
		
Leave	movf	status_temp,W
	movwf	STATUS
	swapf	w_temp,F
	swapf	w_temp,W
	bcf	INTCON,INTF	;clear the INTF to recieve more int. 
	retfie


Here is the display multiplex stuff of 4 digits. It’s in the main routine.

Code:
Mulpx	clrf	PORTB
	clrf	PORTA				
	btfsc	Dselect,1	;if Dselect bit = 1	
	call	One		;Show only digit 0 & 1
	btfsc	Dselect,2	;if Dselect bit = 2	
	call	Two		;Show only digit 0 & 1 & 2
	btfsc	Dselect,3	;if Dselect bit = 3	
	call	Three		;Show only digit 0 & 1 & 2 & 3 
	btfss	Dselect,0	;if Dselect bit = 0
	call	Zero		;show only 0 digit
	goto	Mulpx								
		
Three	movlw	b'00001000'	;enable digit3
	movwf	PORTA
	movf	Digit3,W
	call	Table
	movwf	PORTB
	call	Delay		
Two	movlw	b'00000100'	;enable digit2
	movwf	PORTA
	movf	Digit2,W
	call	Table
	movwf	PORTB
	call	Delay						
One	movlw	b'00000010'	;enable digit1
	movwf	PORTA
	movf	Digit1,W
	call	Table
	movwf	PORTB
	call	Delay
Zero	movlw	b'00000001'	;enable digit0
	movwf	PORTA
	movf	Digit0,W
	call	Table
	movwf	PORTB
	call	Delay					
	return
 
You code looks fine. The only comment I would make is that you don't need to clear the Zero flag before the xors.

Code:
Zeroa	incf	Digit0,F	;increment digit0
	movf	Digit0,W
	[COLOR="Red"]bcf	STATUS,Z[/COLOR] <--you can delete this line.
	xorlw	.10
	btfss	STATUS,Z	;check digit0 has reached 10
	goto	Leave		;No then leave
	clrf	Digit0		;YES clrf digit0 and- 
	bsf	Dselect,1	;set bit 1 in Digit select register

I would also suggest turning off the LEDs during update.
Code:
Three	[COLOR="blue"]clrf	PORTA		;turn off display[/COLOR]
	movf	Digit3,W
	call	Table
	movwf	PORTB
	call	Delay		
[COLOR="blue"]	movlw	b'00001000'	;enable digit3
	movwf	PORTA[/COLOR]
	call	Delay		
	[COLOR="red"]return			;add this[/COLOR]
and add the return instruction.

Mike.
 
Hi,
The ISR is not too long, it looks fine :).
But I wonder, in the ISR, in the label Zeroa to Threea, why do you clear the Z flag of the STATUS register? Is it needed?
And for the multiplex routine, shouldn't all the displays be multiplexed equally? I can see that bit 0 is displayed more often.
 
Hi mike thanks for the reply.
I will remove that bcf STSTUS, Z line.
I’ll add clrf PORTA also.

And in the main routine (display show routine) I cannot add return to each digit.

Because
*when call Three occurred it must show all 4 digits.
*When call Two occurred it must show only first 3 digits. Not showing last digit.
*When call One occurred it must show only first 2 digits. Not showing last 2 digits.
*When call Zero occurred it must show only the first 1digit. Not showing last 3 digits.

Can my coding sense very speed inputs?

Thank you.
 
bananasiong said:
And for the multiplex routine, shouldn't all the displays be multiplexed equally? I can see that bit 0 is displayed more often.

No they are not multiplexed equally. This only shows the first digit when it reaches the number 10 it will turn on the digit2 segment so & so it will go on.
 
Oh I see, I got what do you mean :)
I think it should be quite obvious for the brightness of one display compared to four multiplexed displays.
 
bananasiong said:
Oh I see, I got what do you mean :)
I think it should be quite obvious for the brightness of one display compared to four multiplexed displays.

You are right I got a brightness problem with it.Also the delay can cause to the multiplexing.
 
If you want to be able to handle very high count rates then you ISR has to be as short as possible.

Something like,
Code:
	bcf	INTCON,INTF
	incfsz	Counter,F	;using incf would alter the zero flaf.
	retfie			
	retfie			;this is needed if the incfsz skips.

You don't need to save W or STATUS as none of the instructions alter them. Note, using incf will effect status.

In you main code you can now do,
Code:
		movfw	Counter
		subwf	Counter,F
		addwf	Digit0,F
		movlw	.10
UnitLoop	subwf	Digit0,F	;subtract 10 from digit 0
		btfss	STATUS,C	;did we pass zero?
		goto	DoneDigit0	;yes so were done
		incf	Digit1,F	;no, so increment 10's
		goto	UnitLoop	;do it all again
DoneDigit0	addwf	Digit0,F	;add 10 back to get right number
TensLoop	subwf	Digit1,F	;subtract 10 from digit 1
		btfss	STATUS,C	;did we pass zero?
		goto	DoneDigit1	;yes so were done
		incf	Digit2,F	;no, so increment 100's
		goto	TensLoop	;do it all again
DoneDigit1	addwf	Digit1,F	;add 10 back to get right number

etc.
The reason that W is subtracted from Counter is incase an interrupt comes along between the instructions. Note that W=10 all the way through the code.

You can also implement leading zero supression by using a flag,
Code:
	bsf	Flags,0		;use bit 0 of variable flags to indicate 
				;we are suppressing leading zeroes.
	movfw	Digit3		;get most significant digit
	btfss	STATUS,Z	;is digit three = zero
	bcf	Flags,0		;no so clear the leading zero flag
	call	Table		;get the segment pattern
	btfsc	Flags,0		;if leading zero flag is set
	movlw	0xff		;then display nothing.
	clrf	PORTA		;turn off display
	movwf	PORTB
	bsf	PORTA,3		;turn on digit 3
	call	Delay

	movfw	Digit2
	btfss	STATUS,Z
	bcf	Flags,0
	call	Table
	btfsc	Flags,0		; if leading zero flag is set
	movlw	0xff		; then display nothing.
	clrf	PORTA
	movwf	PORTB
	bsf	PORTA,2
	call	Delay
etc.

Hope that gives you some ideas.

Mike.
edit, corrected code.
 
Last edited:
Thank you mike for the support. I soon going to study your coding as well.

Pommie said:
The reason that W is subtracted from Counter is incase an interrupt comes along between the instructions. Note that W=10 all the way through the code.

Actually I'm thinking about this. Working register is something new to me actually I don’t know what it does & for what.I know it’s only a value.

Thanks a lot.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top