Interrupt On Change Question on 16F1825


+ Reply to Thread
Results 1 to 2 of 2
  1. #1
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    815

    Default Interrupt On Change Question on 16F1825

    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


    Code:
    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 
    ' ------------------------------------------------------

  2. #2
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    815

    Default Re: Interrupt On Change Question on 16F1825

    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

    Code:
     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
    Code:
       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
    Code:
          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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts