PDA

View Full Version : Interrupt On Change Question on 16F1825



longpole001
- 23rd August 2012, 01:57
Hi Guys , having some problems getting IOC working on the 16F1825 , and wondered if its cos the pin is used both as input and output at times though out the program

Question is
A. Do i need to disable interrupts during the time the pin is used as an output or its does not matter as its an output ?
b. when using DT-int14 for this chip , i am aware that the interupt needs to be cleared before returning , is this a ASM clear or can this be a PBP clear - see part code
c. Do i need to enable IOC in Intcon or not worry as its done in the DT_ints-14 code

Cheers

Sheldon




INCLUDE "DT_INTS-14.bas"

INCLUDE "ReEnterPBP.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?

INT_Handler IOC_INT,_GetIRcode, PBP, yes ; call GetIRcode subroutin on Interupt
endm
INT_CREATE ; Creates the Interrupt Processor
ENDASM


INTCON = %10001000 ' Interupts Clear - GIE,PEIE,TMR0IE,INTE,IOCIE,TMR0IF,INTF,IOCIF
IOCAN.4 = 1 ' Enable interupt on change on portA.4 for negative going edge ( for getIR routine )
IOCAF.4 = 0 ' Clear Interupt on Change flag on portA.4



@ INT_ENABLE IOC_INT ; Enable PortA Change on Interrupt




' ============ Get IR Code Routine ================
' * *
' * ******* IOC - Interupt Handler routine ******* *
' * *
'================================================= =====


GetIRcode:

' TRISA.4 = 1 ' setup input=1,output=0 TRISA.3 = 1 to input
PULSIN IR,1,Leader ' get leader high pulse time value in on TRISA.4 ( pulsin_max set to 21600 = 108ms )
IF Leader < 800 tHEN ' look for 4500us high pulse - below 4000us then its 2nd key area pulse or data/ address bits (800^ 5us= 4000us)
IOCAF.4 = 0 ; clear IOCAF - clear the IOC flags port A
@ INT_RETURN
return
Endif

IF Leader > 960 tHEN ' above 4800us then it no sig (960*5us=4800us)
IOCAF.4 =0 ; clear IOCAF - clear the IOC flags port A
@ INT_RETURN
return
endif

x=0 ' ensure 0
FOR X = 0 TO 31 ' grab 32 incoming pulses
PULSIN IR,1,leader ' now measuring high-going pulse widths
BtnVal(x) = leader/2 ' leader divide by 2 so Btnval(x) is byte (<255) not word value
NEXT X

z = 0 ' Z points to start range of byte
S = 7 ' S points to end range of byte
X = 0 ' start X at 0 to line up with BtnVal array
y = 0 ' ensure 0
for Y = 1 to 4 ' Get in Array and decode 4 bytes from 32 bit pulses
T = 7 ' Set T to 7 so that it puts BtnVal(0) in to D7 location
FOR X = Z TO S ' sort 8 pulses of byte
IF BtnVal[X] > 120 THEN ' > 120 x (5uS *2) = > 1.2mS pulse period = 1 (150)
DByteTmp = DByte[Y] ' get into temp var
DByteTmp.0[T]=1 ' Set value to 0 or 1 , T reverses bit order of BtnVal(x) so byte has correct bin value to write byte
ELSE
DByteTmp = DByte[Y] ' get into temp var
DByteTmp.0[T]=0 ' Set value to 0 or 1 , T reverses bit order of BtnVal(x) so byte has correct bin value to write byte
ENDIF

DByte[Y] = DByteTmp ' get it back into DByte(y)
T = T - 1 ' T points to next MSB on loop
NEXT X

Z = x ' Z = X (0,8,16,24) points to start of next byte
S = 7 + X ' S (7,15,23,31) points to End of next DByte BtnVal offset to X
next Y ' loop for 4 bytes


' only save code if it differant to stored IR code
' **** this will need to change when using the config IR section
x=1 ' ensure 1
for x = 1 to 4
read x , STDByte[x] ' read the last saved IR code at startup
if DByte[x] <> STDByte[x] then
write x,DByte[x]
endif
next x
IOCAF.4 =0 ; clear IOCAF - clear the IOC flags port A.4
@ INT_RETURN ; return used for Interupt call

Return
' ------------------------------------------------------

longpole001
- 23rd August 2012, 05:05
well for those that make be looking at IOC with DT-int14 with the 16F1825 chips i have sorted out my current issue

the program i use needs to send IR code strings out pin 4 at start and then at other times when needed , it also gets IR codes via the same pin and uses DT-INT-14 Interrupt On Change trap , when it receiving codes and waiting for inputs


1. The 16F1825 supports individual Int flags per pin on port A (only) for IOC ,
2. DT-int-14 asm code does not clear the flags upon a return ( known ) and does not seem to effect when enabled "@ INT_ENABLE IOC_INT" Globel interupts and IOC enable for this Chip - see comments marked **


3. When a Pin is used for IOC inputs and is also used as output pin , then You must do the following

a. Ensure IOCN or IOCP level value for the pin used as input for IOC trigger is setup prior to int call - see code
b. Disable globle interupts and Disable IOCE flag in INTCON reg else the same pin set as out put will not output at all - disabling Dt-int-14 - does not solve this prob **


placed prior to main called routines



INTCON = 0 ' Interupts Clear at start- GIE,PEIE,TMR0IE,INTE,IOCIE = on,TMR0IF,INTF,IOCIF
IOCAN.4 = 1 ' Enable interupt on change on portA.4 for negative going edge ( for getIR routine )
IOCAF.4 = 0 ' Clear Interupt on Change flag on portA.4



In the output pin routine you need to

at begining of the code put


INTCON.7 =0 ' Disable Global INTERUPTS
INTCON.3 =0 ' Disable IOCIE
TRISA.4 = 0 ' setup input=1,output=0 TRISA.4 = 0 to output ( turn on here so correct pulse output)


At end put


INTCON.7 =1 ' ENABLE Global INTERUPTS
INTCON.3 =1 ' Enable IOCIE
TRISA.4 = 1 ' setup input=1 for GetIR routine use when IOC portA
IOCAF.4 = 0 ' Clear Interrupt on change flag IOCA.4 ( Port A- 4 for when it changes from high for used GetIR routine



The other code attached shows the get Ir code and nothing is changed as it is called after the send code routines at start

I found that by just enabling and disabling using DT-int-14 call " @ INT_ENABLE IOC_INT " did not work and adding the above code in allowed the IOC int routine trap to work and allow the same pin to output as required

cheers

Sheldon