IOC on pin going HIGH and LOW
PIC 16F18877
Custom DT_INTS-14.bas entry:
Code:
;---[16F1885x7x]------------------------------------------------------------
; #define IOC_INT INTCON,IOCIF, INTCON,IOCIE ;-- Int On Change
#define IOC_INT PIR0,IOCIF, PIE0,IOCIE ;-- Int On Change *
Will turn LED on when pressed, and off when released:
Code:
#CONFIG
__config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_ON
__config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
__config _CONFIG3, _WDTCPS_WDTCPS_11 & _WDTE_ON & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_OFF
__config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG
DEFINE OSC 32
include "C:\PBP Includes\DT_INTS-14_16F1885x-7x.bas"
include "C:\PBP Includes\ReEnterPBP.bas"
ASM
INT_LIST macro ;IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _MyIOCinterrupts, PBP, yes
endm
INT_CREATE ;Creates the interrupt processor
ENDASM
'--------------------------------------------------------------------------
' Controlled by DT-INTS
'INTCON = %10000000
' bit 7 GIE Global Interrupt Enable bit
' 1 = Enables all active interrupts
' bit 6 PEIE Peripheral Interrupt Enable bit
' bit 5-1 Unimplemented: Read as ‘0’
' bit 0 INTEDG Interrupt Edge Select bit
'PIE0 = %00010000 ' PERIPHERAL INTERRUPT ENABLE REGISTER 0
' bit 7-6 Unimplemented: Read as ‘0’
' bit 5 TMR0IE: TMR0 Overflow Interrupt Enable bit
' bit 4 IOCIE: Interrupt-on-Change Interrupt Enable bit
' 1 = Enables the IOC change interrupt
' bit 3-1 Unimplemented: Read as ‘0’
' bit 0 INTE: INT External Interrupt Flag bit
'--------------------------------------------------------------------------
IOCCP = %00010000 ' INTERRUPT-ON-CHANGE PORTC POSITIVE EDGE REGISTER
' bit 7-0 IOCCP<7:0> Interrupt-on-Change PORTC Positive Edge Enable bits
' 1 = Interrupt-on-Change enabled on the pin
' for a positive-going edge. IOCCFx bit
' and IOCIF flag will be set upon detecting an edge.
IOCCN = %00010000 ' INTERRUPT-ON-CHANGE PORTC NEGATIVE EDGE REGISTER
' bit 7-0 IOCCP<7:0> Interrupt-on-Change PORTC Negative Edge Enable bits
' 1 = Interrupt-on-Change enabled on the pin
' for a Negative-going edge. IOCCFx bit
' and IOCIF flag will be set upon detecting an edge.
ANSELA = %00000000
ANSELB = %00000000
ANSELC = %00000000
ANSELD = %00000000
ANSELE = %00000000
TRISA = %00000000
TRISB = %00000000
TRISC = %00010000
TRISD = %00000000
TRISE = %00000000
PushSwitch VAR PortC.4
InterruptLED VAR LatC.2
ButtonWasPressed VAR byte
Pause 500 ' Let PIC stabilize
InterruptLED = 0
ButtonWasPressed = 0
@ INT_ENABLE IOC_INT
IOCCF.4 = 0
Mainloop:
if ButtonWasPressed = 1 then ' Check flag
InterruptLED = 1
else
InterruptLED = 0
endif
goto mainloop
MyIOCinterrupts:
if IOCCF.4 = 1 then
if ButtonWasPressed = 1 then ' toggle flag
ButtonWasPressed = 0
else
ButtonWasPressed = 1
endif
IOCCF.4 = 0
endif
@ INT_RETURN
end
1 Attachment(s)
Re: IOC on pin going HIGH and LOW
Using the IOC logic above, along with Bourns debounce circuit (10K/0.01uF) followed by a 74HC14, these are the signal speeds I was able to get using an ordinary pushbutton and EC11-type rotary encoder:
Attachment 9742
Switch:
33.9msec ON
146.2msec ON to ON
Encoder:
2.13msec ON
3.01msec ON to ON
To keep things in perspective, I added a LED toggle in MainLoop.
Heartbeat:
2.12usec ON
4.75usec ON to ON
Re: IOC on pin going HIGH and LOW
Quote:
followed by a 74HC14,
why the redundant extra schmitt trigger?
in the pic 16F1885x family all input pins are ST by default unless you clear the INPUT THRESHOLD CONTROL bit in the INLVLx register
Re: IOC on pin going HIGH and LOW
Quote:
Originally Posted by
richard
why the redundant extra schmitt trigger? ...
Because I started development using a 16F1937 and didn't notice the ST on the 16F18877.
(runs over to the datasheet)
:)
EDIT: Wow! That PIC is amazing; every pin has ADC and ST. That's gonna help bring costs down from those 74HC14 ICs.
:D
Re: IOC on pin going HIGH and LOW
Quote:
Because I started development using a 16F1937
unfortunately one of the very few enhanced core pic chips without INPUT THRESHOLD CONTROL.
Re: IOC on pin going HIGH and LOW
193x was a nice chip in its time but now comparing to 188xx seems so old...!
And I have many in stock...
Ioannis
1 Attachment(s)
Re: IOC on pin going HIGH and LOW
Registers associated with Interrupts are in Table 7-1 on p. 153:
Attachment 9743
From my observations, you need 2 entries in the DEFINES for 16F:
- Result bit,
- Enable bit.
#DEFINE {DT-INT interrupt NAME} {result flag REGISTER}, {result flag bit}, {enable bit REGISTER}, {enable bit}
For example:
#DEFINE IOC_INT PIR0,IOCIF, PIE0,IOCIE
Re: IOC on pin going HIGH and LOW
I keep the IOC flags right alongside the pin definitions (this is a EC11-type rotary encoder; 2 shafts + pushbutton):
Code:
;--- Setup pins ----------------------------------------------------------------
COM1_MHz_WiperA var PortA.2 ' Outer
IOC_COM1_MHz_WiperA_flag var IOCAF.2 ' IOC flag
COM1_MHz_WiperB var PortA.3 ' Outer
IOC_COM1_MHz_WiperB_flag var IOCAF.3 ' IOC flag
COM1_KHz_WiperA var PortA.0 ' Inner
IOC_COM1_KHz_WiperA_flag var IOCAF.0 ' IOC flag
COM1_KHz_WiperB VAr PortA.1 ' Inner
IOC_COM1_KHz_WiperB_flag var IOCAF.1 ' IOC flag
COM1_SPST var PortA.4 ' Swap
IOC_COM1_SPST_flag var IOCAF.4 ' IOC flag
It makes it easier (for me) to make sure things are connected exactly where I think they are. It's also much easier to move things about on the pins.