However, I've failed so far in getting anything to help with the other two interrupt uses I have.
The first of these is detecting a momentary high on an input pin.
I've tried using Port(A)(B)(AB)Change to call an interrupt handler when a pin goes high ( +5v ) but nothing seems to happen. That is, the handler sub routine doesn't seem to get called.
Can someone guide me in how to use an interrupt to detect a momentary high signal on a pin. Also, can I do this on the Port C pins?
The other interrupt use I have is using the comparator. I have a 1ms heartbeat signal input ( 0v-3v ) and I want to set a timer each time the signal falls below the internal 0.6v reference. This is in order to detect a 300ms or 500ms loss of the heartbeat.
How do I set this up to use the internal 0.6v reference on a falling signal. I'm really lost on this one except for the knowledge that Comp0Change exists as an On Interrupt event.
I'm using a 16F676.
Finally, thank for GCBasic. I used it to make a GPS tagger to plug into my camera a few years ago. The program ( using a 16F628a ) sets up the GPS receiver and if the GPS loses signal, the PIC stores the last good position and keeps feeding that to the camera until it once again receives a good signal. I found GCBasic great for that project where I used the integrated serial data port for the incoming position data in addition to a software serial port to configure the GPS receiver at initialisation.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm using external interrupts with a PIC18F4455, so I'm pretty sure it should work with the PIC16F676 if you enable the correct bits in INTCON. For the '676, which only has one external interrupt, it appears that this bit is RAIE, which is bit 3 of INTCON. Try putting in a line like "INTCON.RAIE = 1".
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I was wrong about the '676 only having one interrupt. The above code only enables the INT external interrupt, which is RA2. This is detailed in the datasheet under "Interrupts"
It appears that any of PortA bits 0-5 can also generate an interrupt when its input changes state. You set up which bits generate interrupts by setting IOCA bits 0-5.This is detailed in the data sheet under "Ports A and C".
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks, I'll have a look at that when I have some time. I've had a quick look at the data sheet ( now I've got the correct one - my stupid ) and found the IOCA stuff.
Thanks again.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've made good progress on the first part of my query ( Interrupts on input lines ) and comments on the code below would be welcome for improvements.
It has been tested and does appear to work. The only issue seems to be that I'm getting switch bounce ( that can be fixed in hardware ). Interestingly, the interrupt handling routine seems to get called at system initialisation even if there is no input on the IOC port. Coding error or just a by-product of the initialisation sequence?
;Chip Settings
#chip 16F676,4
#config OSC = INT
; Using port RA1 as the interrupt based port
#define SwitchIn PORTA.1
; An LED to show it's working
#define LEDx PORTC.4
; Sub to call when interrupt occurs
On Interrupt PORTACHANGE Call Switching
; Define PortA.1 as Input
Dir SwitchIn In
; LED output
dir PORTC.4 OUT
SET PORTC.4 off
; Defines PortA.1 for 'Interrupt On Change'
Set IOCA.1 on
main :
; Nothing happens in the main path
Do Forever
wait 1 ms
Loop
Sub Switching
; Interrupt On Change handling sub routine
If SwitchIn = On Then
; test port for high value. Reading the port also resets it ( see below ).
for ledflash = 1 to 3
set LEDx on
wait 300 ms
set LEDx off
wait 300 ms
next
' Reset the Change Interrupt flag bit (RAIF) in the INTCON register ( see below ).
RAIF = 0
End If
End Sub
; see 16F676 data sheet section 3.2.2 'INTERRUPT-ON-CHANGE' for resetting the port mismatch by a read or write
; and also why the RAIF flag needs a reset.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
;Interrupt Handlers
On Interrupt Comp1Change Call N82Max
; set the comparator for input on RA1 ( CIn- ), internal VREF for CIn+ and no external COut ( bits 0:2 )
; Set COut with bit 6
CMCON = b'01000100'
; set VRef. bits 0:3 set a voltage of about 0.6v. Bit 5 is VRR and bit 7 is VRen
VRCON = b'10100011' approx 0.6v low range
dir PORTC.4 OUT
SET PORTC.4 off
IntOn
main :
Do Forever
wait 1 ms
Loop
goto main
Sub N82Max
If Heartbeat = 1 Then
set LEDdx on
wait 60 ms
set LEDdx off
end if
End Sub
It's a LOT easier than I thought it was going to be!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
GPS tagger, do you have a schematic posted anywhere? Or can tell us where you have the pot connected. I see the LED on C.4. Looks like something many will want to try.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The pot/divider is connected to RA1. That's CIn- on a 16F676. The LED is on PortC.4.
The 16F676 is an uncomplicated device with only 1 comparator. CIn+ is on RA0 ( but I'm using the internal voltage reference so RA0 is just a normal digital port ) and if you want the output of the comparator externally, COut is on RA2 ( again I'm not using COut on RA2 and I've got it as a normal digital port ).
.
I'll have a go at a schematic. It may be a day or so before I can put any more time into this.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I'm trying to work with interrupts for the first time and I'm not really getting anywhere.
I've found the code sample on these forums ( https://sourceforge.net/projects/gcbasic/forums/forum/579125/topic/2061852?message=5002397 ) that shows the use of the Timer with interrupts. I've had a good play with that and it solves one of the uses I have for interrupts. Many thanks for that code sample.
However, I've failed so far in getting anything to help with the other two interrupt uses I have.
The first of these is detecting a momentary high on an input pin.
I've tried using Port(A)(B)(AB)Change to call an interrupt handler when a pin goes high ( +5v ) but nothing seems to happen. That is, the handler sub routine doesn't seem to get called.
Can someone guide me in how to use an interrupt to detect a momentary high signal on a pin. Also, can I do this on the Port C pins?
The other interrupt use I have is using the comparator. I have a 1ms heartbeat signal input ( 0v-3v ) and I want to set a timer each time the signal falls below the internal 0.6v reference. This is in order to detect a 300ms or 500ms loss of the heartbeat.
How do I set this up to use the internal 0.6v reference on a falling signal. I'm really lost on this one except for the knowledge that Comp0Change exists as an On Interrupt event.
I'm using a 16F676.
Finally, thank for GCBasic. I used it to make a GPS tagger to plug into my camera a few years ago. The program ( using a 16F628a ) sets up the GPS receiver and if the GPS loses signal, the PIC stores the last good position and keeps feeding that to the camera until it once again receives a good signal. I found GCBasic great for that project where I used the integrated serial data port for the incoming position data in addition to a software serial port to configure the GPS receiver at initialisation.
I'm using external interrupts with a PIC18F4455, so I'm pretty sure it should work with the PIC16F676 if you enable the correct bits in INTCON. For the '676, which only has one external interrupt, it appears that this bit is RAIE, which is bit 3 of INTCON. Try putting in a line like "INTCON.RAIE = 1".
I was wrong about the '676 only having one interrupt. The above code only enables the INT external interrupt, which is RA2. This is detailed in the datasheet under "Interrupts"
It appears that any of PortA bits 0-5 can also generate an interrupt when its input changes state. You set up which bits generate interrupts by setting IOCA bits 0-5.This is detailed in the data sheet under "Ports A and C".
Thanks, I'll have a look at that when I have some time. I've had a quick look at the data sheet ( now I've got the correct one - my stupid ) and found the IOCA stuff.
Thanks again.
I've made good progress on the first part of my query ( Interrupts on input lines ) and comments on the code below would be welcome for improvements.
It has been tested and does appear to work. The only issue seems to be that I'm getting switch bounce ( that can be fixed in hardware ). Interestingly, the interrupt handling routine seems to get called at system initialisation even if there is no input on the IOC port. Coding error or just a by-product of the initialisation sequence?
;Chip Settings
#chip 16F676,4
#config OSC = INT
; Using port RA1 as the interrupt based port
#define SwitchIn PORTA.1
; An LED to show it's working
#define LEDx PORTC.4
; Sub to call when interrupt occurs
On Interrupt PORTACHANGE Call Switching
; Define PortA.1 as Input
Dir SwitchIn In
; LED output
dir PORTC.4 OUT
SET PORTC.4 off
; Defines PortA.1 for 'Interrupt On Change'
Set IOCA.1 on
main :
; Nothing happens in the main path
Do Forever
wait 1 ms
Loop
Sub Switching
; Interrupt On Change handling sub routine
If SwitchIn = On Then
; test port for high value. Reading the port also resets it ( see below ).
for ledflash = 1 to 3
set LEDx on
wait 300 ms
set LEDx off
wait 300 ms
next
' Reset the Change Interrupt flag bit (RAIF) in the INTCON register ( see below ).
RAIF = 0
End If
End Sub
; see 16F676 data sheet section 3.2.2 'INTERRUPT-ON-CHANGE' for resetting the port mismatch by a read or write
; and also why the RAIF flag needs a reset.
Now making good progress with the comparator part as well. Test code seems to be working OK.
Some good info here :
https://sourceforge.net/projects/gcbasic/forums/forum/629990/topic/2917158
which has been modified for the 16F676.
I've tested the code initially with a potentiometer/potential divider and subsequently with a waveform generated by an oscilloscope.
;Chip Settings
#chip 16F676,4
#config OSC = INT
;Defines (Constants)
#define LEDdx PORTC.4
#define Heartbeat CMCON.COUT
;Interrupt Handlers
On Interrupt Comp1Change Call N82Max
; set the comparator for input on RA1 ( CIn- ), internal VREF for CIn+ and no external COut ( bits 0:2 )
; Set COut with bit 6
CMCON = b'01000100'
; set VRef. bits 0:3 set a voltage of about 0.6v. Bit 5 is VRR and bit 7 is VRen
VRCON = b'10100011' approx 0.6v low range
dir PORTC.4 OUT
SET PORTC.4 off
IntOn
main :
Do Forever
wait 1 ms
Loop
goto main
Sub N82Max
If Heartbeat = 1 Then
set LEDdx on
wait 60 ms
set LEDdx off
end if
End Sub
It's a LOT easier than I thought it was going to be!
GPS tagger, do you have a schematic posted anywhere? Or can tell us where you have the pot connected. I see the LED on C.4. Looks like something many will want to try.
Good point.
The pot/divider is connected to RA1. That's CIn- on a 16F676. The LED is on PortC.4.
The 16F676 is an uncomplicated device with only 1 comparator. CIn+ is on RA0 ( but I'm using the internal voltage reference so RA0 is just a normal digital port ) and if you want the output of the comparator externally, COut is on RA2 ( again I'm not using COut on RA2 and I've got it as a normal digital port ).
.
I'll have a go at a schematic. It may be a day or so before I can put any more time into this.
That would be great and no rush. Will probably set off a lot of projects for many. Not sure how to attach here though.
A bit crudely drawn, but this is the schematic to work with the comparator code.
Uploaded the wrong version! No idea how to edit posts so here's the better one -