Hi Rob and Rob, :)
I've tried with or without ISR, with AND IOCAP reset or normal IOCAP reset.
This IOC is erratic and has a lot of latency. The RDY_IN signal is 20ms
square 50% duty cycle, the RDY_OUT signal has a latency most of the
time...but sometimes has a 20mS pulse as it should. The code which somehow
"works" is below, however the need of clearing the IOCAF0 in the main loop
is weird. Without it IOC is not working. If the RDY_IN (pin_A0) signal
disappears, the RDY_OUT (pin_A5) remains high.
INTCON_IOCIF is read only, it's content is changed by IOCAF. To clear
INTCON_IOCIF the whole IOCAF register has to be cleared.

Perhaps I missed something...

------------------------------------------
pin_A0_direction = input
pin_A5_direction = output

OPTION_REG_WPUEN = 1 ; pull-up disabled on portA
;WPUA_WPUA0 = low ; pull-up disabled on RA0
INLVLA_INLVLA0 = high ; schmitt trigger on RA0 enabled

-- main program
-- 
----------------------------------------------------------------------------
INTCON_GIE = high   ; enable global interrupts
INTCON_PEIE = high  ; enable peripheral interrupts
INTCON_IOCIE = high ; enable interrupt on change,
 IOCAP_IOCAP0 = high ; enable positive edge interrupt on change on RDY_IN
IOCAF = 0; clear IOCAF flags

procedure IOC () is
 pragma interrupt

   if INTCON_IOCIF & IOCAF_IOCAF0 then
      asm bsf pin_A5
 ;     IOCAF = 0  ; it's never cleared here
;        assembler ; AND clear IOCAF
;       movlw 0xff
;       bank xorwf IOCAF, w
;       bank andwf IOCAF, f
;        end assembler
   else
      asm bcf pin_A5
   end if
;        assembler ; AND clear IOCAF
;       movlw 0xff
;       bank xorwf IOCAF, w
;       bank andwf IOCAF, f
;        end assembler
   IOCAF = 0

end procedure

forever loop
      IOCAF = 0   ; clear INTCON_IOCIF
end loop

On Fri, Oct 1, 2021 at 11:56 AM Rob Hamerling <[email protected]>
wrote:
I think the cause of your problem is that you set INTCON_GIE = high, but
have no ISR (Interrupt Service Routine).
An interrupt (hardware jump to the interrupt vector at address 0x0004)
becomes practically a restart of the program.
Possible solutions: INTCON_GIE = low, or use an ISR to handle the IOC
interrupt (but no delay in an ISR!)

Regards, Rob.



On 30/09/2021 17.51, vsurducan wrote:


According to the PIC12F1572 datasheet, rising edge IOC can be detected by
enabling edge detection on input pins (IOCAPx or IOCANx)
and reading the IOC flag (IOCAFx) or the INTCON_IOCIF, then clearing the
flag for the next IOC detection.
Seems it does not work.  Any ideas?  Thx.

include 12lf1572                     -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT           -- internal oscillator
pragma target PLLEN    DISABLED                  -- PLL off
pragma target CLKOUTEN DISABLED                  -- no clock output
pragma target WDT      DISABLED                  -- watchdog
pragma target BROWNOUT ENABLED                  -- brownout reset
pragma target LVP      DISABLED                  -- no low voltage
programming
pragma target MCLR     INTERNAL                  -- internal reset
--
--
OSCCON_SCS = 0                      -- select primary oscillator
OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SPLLEN = ENABLED             -- 4x PLL: 8 -> 32 MHz
--
enable_digital_io()                 -- make all pins digital I/O

include delay

alias pin_RDY_IN is pin_A0
alias pin_RDY_IN_direction is pin_A0_direction
pin_RDY_IN_direction = input


alias pin_RDY_OUT is pin_A5
alias pin_RDY_OUT_direction is pin_A5_direction
pin_RDY_OUT_direction = output
pin_RDY_OUT = low

OPTION_REG_WPUEN = 0
WPUA_WPUA0 = 0 ; pull-up disabled on RA0


-- main program
-- 
----------------------------------------------------------------------------
INTCON_GIE = high   ; not necessary without interrupt routine
INTCON_IOCIE = high ; enable interrupt on change, not necessary without
interrupt routine
IOCAP_IOCAP0 = high ; enable positive edge interrupt on change on RDY_IN


forever loop

; if INTCON_IOCIF  then
  if IOCAF_IOCAF0  then  ; a positive edge interrupt on change on RDY_IN
occured
    pin_RDY_OUT = high
    delay_1mS (20)
    pin_RDY_OUT = low
    IOCAF_IOCAF0 = low    ; clear IOCAF0 flag
;    INTCON_IOCIF = low
 else ; no interrupt occured
    pin_RDY_OUT = low
 end if

end loop




-- 
You received this message because you are subscribed to the Google Groups
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/jallib/CAM%2Bj4qvv6k0rGBYftBOhsT7HR4wJe8GrM8_vEGUPiTk3MVa%2B8Q%40mail.gmail.com
<https://groups.google.com/d/msgid/jallib/CAM%2Bj4qvv6k0rGBYftBOhsT7HR4wJe8GrM8_vEGUPiTk3MVa%2B8Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
.


-- 
*Rob H*amerling, Vianen, NL

> --
> You received this message because you are subscribed to the Google Groups
> "jallib" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jallib/dd13bf5c-9a69-5157-afa9-fa27d38ece98%40gmail.com
> <https://groups.google.com/d/msgid/jallib/dd13bf5c-9a69-5157-afa9-fa27d38ece98%40gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jallib/CAM%2Bj4qt%2BGQHwtw4kd-g4yduwaAUhRAhugonqsHs772g28MJruw%40mail.gmail.com.

Reply via email to