# external interrupt

Status
Not open for further replies.

#### neelam29

##### New Member
hi
i am trying to make a system including frequency meter. for frequency

measurement method:- measuring time between two consequtive pulses. i'm

feeding the frequency at external interrupt pin. i'm facing a small

problem. when i start the system lcd displays the correct frequency

value. (i've added 5 seconds delay for refreshing the data) but second

time the frequency is refreshed the value comes wrong and after that

everytime absart values are displayed. i've tried everything. i've

tried re-intializing everything but nothing is helping out. here's the

me.

Kind regards.

Code:
	LIST	p=16F877A, W=2, X=ON, R=DEC	;tell assembler what chip we are using
include "P16F877A.inc"			;include the defaults for the chip
ERRORLEVEL	0,	-302		;suppress bank selection messages
__CONFIG    0x393A			;sets the configuration settings (oscillator type etc.)

cblock	0x20			;start of general purpose registers
count
count1
counta
countb
COUNT_SEC
LoX
Bit_Cntr
Timer_H
Flags
Flags2
tmp1
tmp2
tmp3
NumL
NumH

AARGB0
AARGB1
AARGB2
AARGB3
BARGB0
BARGB1
LOOPCOUNT
REMB0
REMB1

TenK
Thou
Hund
Tens
Ones
templcd
templcd2
Acc1L			;16 bit maths register 1
Acc1H
Point			;position of decimal point

;FREQUENCY VARIABLES
FreqL
FreqH
TIMER1_LOW
TIMER1_HIGH

w_temp 				; To save off current W register contents
status_temp

freq_over

endc

LCD_PORT	Equ	PORTD
LCD_TRIS	Equ	TRISD
LCD_RS		Equ	0x05			;LCD handshake lines
LCD_RW		Equ	0x06
LCD_E		Equ	0x07

ORG	0x0000
NOP
BCF	PCLATH,	3
BCF	PCLATH,	4
GOTO	start

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>frequency call>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

ORG	0x0004

MOVWF 	w_temp 		; save off current W register contents
MOVF 	STATUS,w 		; move status register into W register
MOVWF 	status_temp 	; save off contents of STATUS register

BTFSC	T1CON, TMR1ON
goto	Stop_timer1

CLRF	TMR1H
CLRF	TMR1L
BSF		T1CON, TMR1ON
GOTO	END_ANS_INT

Stop_timer1
BCF		T1CON, TMR1ON
MOVF	TMR1H, W
MOVWF	TIMER1_HIGH
MOVF	TMR1L, W
MOVWF	TIMER1_LOW
BSF		freq_over, 0X00

;BCF		INTCON, INTE
END_ANS_INT
MOVF 	status_temp,w 	; retrieve copy of STATUS register
MOVWF 	STATUS 		; restore pre-isr STATUS register contents
SWAPF 	w_temp,f
SWAPF 	w_temp,w 		; restore pre-isr W register contents
BCF		INTCON, INTF

retfie
;=====================================================================

start
errorlevel	-302
bsf	INTCON,INTE		; Enable external interrupt
bsf	INTCON,GIE

Initialise	clrf	count
clrf	PORTA
clrf	PORTD
clrf	PORTC
clrf	Flags

clrf	REMB0
clrf	REMB1
movlw	b'00110000'
movwf	T1CON

SetPorts	bsf 	STATUS,		RP0	;select bank 1
movlw	0x00			;make all LCD pins outputs
movwf	LCD_TRIS
movlw	B'00000001'			;make all pins outputs
movwf	TRISB
bsf     OPTION_REG, NOT_RBPU
bcf 	STATUS,		RP0	;select bank 0
call	LCD_Init		;setup LCD module
call	LCD_CurOff		;turn cursor off
call 	Delay5

Main

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>> READING VALUES FROM EXT. INT. FOR FREQUENCY >>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

movlw	b'00110000'
movwf	T1CON
BCF	freq_over, 0X00

bsf	INTCON,INTE		; Enable external interrupt

CHECK_INT
BTFSS	freq_over, 0X00
GOTO	CHECK_INT

BCF	INTCON,INTE
BCF	freq_over, 0X00

CALL	CALCULATE_FREQ

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DISPLAY FREQ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

movlw	0xC0			;move to 1st row, first column
call	LCD_Cmd
movf	FreqH,w
movwf	NumH
movf	FreqL,w
movwf	NumL
call	LCD_Decimal		;and display on LCD (in decimal)
movlw	' '
call	LCD_Char		;display a space
nop
nop

CALL	Delay5sec
goto	Main			;loop for ever

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CALCULATE_FREQ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CALCULATE_FREQ
movlw	0x5F
movwf	AARGB0
movlw	0x5E
movwf	AARGB1
movlw	0x10
movwf	AARGB2
movf	TIMER1_HIGH,W
movwf	BARGB0
movf	TIMER1_LOW,W
movwf	BARGB1

call	FXD2416U		;DIVIDE 6250000/TIMER VALUE TO GET FREQUENCY WITH .1 RESOLUTION
movf	AARGB1,w
movwf	FreqH
movf	AARGB2,w
movwf	FreqL
RETLW	0X00
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;LCD ROUTINES.........
;DIVIDE ROUTINES.......

end

#### motion

##### New Member
First of all, there are safer and more accurate ways to measuring the time duration between edges than using the external interrupt. Using the capture module is an example.

Anyway, my guess is that although you have disabled external interrupts while calculating and displaying the frequency, the clock continues to be applied to the external interrupt pin. While the PIC is busy displaying the calculated result, the "INTCON, INTF" flag will be set but this will not cause an interrupt because it is masked.

After the 5 second delay, the moment you set "INTCON, INTE", with the "INTCON, INTF" flag already set, an interrupt is immediately fired even if the edge occured much earlier. The second clock edge will be encountered soon after that and the frequency read will be much higher.

The ff. code should correct this problem.

Code:
Main
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>> READING VALUES FROM EXT. INT. FOR FREQUENCY >>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

movlw   b'00110000'
movwf   T1CON
BCF   freq_over, 0X00

BCF      INTCON, INTF ; **** Clear this first *****
bsf   INTCON,INTE      ; Enable external interrupt

CHECK_INT
BTFSS   freq_over, 0X00
GOTO   CHECK_INT

BCF   INTCON,INTE
BCF   freq_over, 0X00

CALL   CALCULATE_FREQ

#### neelam29

##### New Member
hi thanks motion, your solution worked out very well.

i wanted to ask u abt the capture mode. wht is it actually m new to pic so i m not familiar with it. i just read in the datasheet abt it. but cant understand how to use it for frequency meter. can u please explain me abt it or give me a small example based on it.

thanks once again

#### motion

##### New Member
neelam29 said:
hi thanks motion, your solution worked out very well.

i wanted to ask u abt the capture mode. wht is it actually m new to pic so i m not familiar with it. i just read in the datasheet abt it. but cant understand how to use it for frequency meter. can u please explain me abt it or give me a small example based on it.

thanks once again
Before I would get into the capture mode, I would like to mention the problems I see with using the external interrupt. The interrupt service time could severely limit the maximum frequency you can measure, maybe only up to 50-80Khz with increasing inaccuracy as frequency goes up. You didn't mention the frequency range you are trying to measure but since you are getting the reciprocal of the time interval, then I assume it is between 60Hz to 50Khz, not a very big range. You might do better if you simply count the number of pulses over a 1-5 second interval for example.