|
|
View previous topic :: View next topic |
Author |
Message |
bgpartri Guest
|
GP3 interrupt on 12F675 |
Posted: Wed Apr 30, 2003 11:11 am |
|
|
I am trying to get a 12F675 to respond to an interrupt on level change on GP3. I have set up all of the interrupt enabling switches (I think), but still no interrupt.
In the following code, I sit in the while loop waiting for an interrupt. I check GIE, GPIE and IOC and they are all set. When I push my button, I get the 4 green flashes that show I am getting GPIF (flag) bit set. But no interrupt ?!?!? What am I missing?
#include "12F675.h"
#include "675PICReg.h"
#fuses intrc_io, NOWDT, NOPROTECT, PUT, BROWNOUT, NOMCLR
#use delay (clock=2000000)
#define RED PIN_A1
#define GREEN PIN_A2
#define BUTTON PIN_A3
#bit GPIF_BIT = 0x0B.0
#bit GPIE_BIT = 0x0B.3
#bit GIE_BIT = 0x0B.7
#bit IOC_BIT = 0x96.3
.....
#INT_RB
void int_rb_isr(void)
{
got_interrupt = TRUE;
disable_interrupts(INT_RA3);
}
void FlashRED(int count)
...
void FlashGREEN(int count)
....
void main(void)
{
setup_comparator(nc_nc_nc_nc);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
FlashRED(2);
got_interrupt = FALSE;
GPIF_BIT = 0;
enable_interrupts(INT_RA3);
enable_interrupts(GLOBAL);
while(1)
{
if(GPIF_BIT)
{
FlashGREEN(4);
Delay_ms(2000);
GPIF_BIT = 0;
}
if(GPIE_BIT)
{
FlashRED(2);
Delay_ms(2000);
GPIF_BIT = 0;
}
if(GIE_BIT)
{
FlashGREEN(2);
Delay_ms(2000);
GPIF_BIT = 0;
}
if(IOC_BIT)
{
FlashRED(3);
Delay_ms(2000);
GPIF_BIT = 0;
}
if(got_interrupt == TRUE)
{
got_interrupt = FALSE;
// Wait for debounce period.
delay_ms(500);
GPIF_BIT = 0;
FlashRED(1);
FlashGREEN(1);
FlashRED(1);
// Then re-enable interrupts.
enable_interrupts(INT_RA3);
}
}
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 14083 |
|
|
Dale Botkin Guest
|
GP3 interrupt on 12F675 |
Posted: Wed Apr 30, 2003 12:14 pm |
|
|
What is INT_RA3? I don't see this in my version. There is not a separate interrupt for GP3. There's one for GP2/INT, and there's GPIO interrupt-on change. I'm using V3.124, if you're using something way newer it may have something defined that mine doesn't, but INT_RA3 wouldn't make a whole lot of sense, it would seem.
You need to set the IOCB bits yourself. These bits control which pins can cause an interrupt on change. If you want to interrupt only on a GP3 change, you would set IOCB=0x10 and enable INT_RB.
If GPIF is set and you're not getting an interrupt, it's probably because you don't have INT_RB enabled and an #INT_RB function -- at least in my version. For this to work as I think you want it to (interrupt on GP3 change) you have to:
Make GP3 an input. Outputs won't trigger an interrupt.
Set IOCB bit 3.
Read the port (this clears the IOC logic).
Enable INT_RB (GPIO interrupt-on-change).
Enable global interrupts.
Hope this helps.
Dale
___________________________
This message was ported from CCS's old forum
Original Post ID: 14086 |
|
|
Dale Botkin Guest
|
Re: GP3 interrupt on 12F675 |
Posted: Wed Apr 30, 2003 12:18 pm |
|
|
:=If GPIF is set and you're not getting an interrupt, it's probably because you don't have INT_RB enabled and an #INT_RB function
Sorry, you do have an #INT_RB -- but still no enable_interrupts(INT_RB).
___________________________
This message was ported from CCS's old forum
Original Post ID: 14088 |
|
|
bgpartri Guest
|
Re: GP3 interrupt on 12F675 |
Posted: Wed Apr 30, 2003 12:33 pm |
|
|
I tried adding the enable_interrupts(INT_RB). According to the assembler generated, it sets INTCON, and enable_interrupts(INT_RA3) sets INTCON and IOC.
00A6: BCF 03.5
.................... enable_interrupts(INT_RA3);
00AF: BSF 0B.3
00B0: BSF 03.5
00B1: BSF 16.3
.................... enable_interrupts(INT_RB);
00B2: BCF 03.5
00B3: BSF 0B.3
...................
:=:=If GPIF is set and you're not getting an interrupt, it's probably because you don't have INT_RB enabled and an #INT_RB function
:=
:=Sorry, you do have an #INT_RB -- but still no enable_interrupts(INT_RB).
___________________________
This message was ported from CCS's old forum
Original Post ID: 14089 |
|
|
bgpartri Guest
|
Re: GP3 interrupt on 12F675 |
Posted: Wed Apr 30, 2003 12:41 pm |
|
|
Thanks for the reply.
:=What is INT_RA3? I don't see this in my version. There is not a separate interrupt for GP3. There's one for GP2/INT, and there's GPIO interrupt-on change. I'm using V3.124, if you're using something way newer it may have something defined that mine doesn't, but INT_RA3 wouldn't make a whole lot of sense, it would seem.
This is addressed in your next post.
:=
:=You need to set the IOCB bits yourself. These bits control which pins can cause an interrupt on change. If you want to interrupt only on a GP3 change, you would set IOCB=0x10 and enable INT_RB.
I have set the IOC bit myself using the enable_interrupts(INT_RA3). And I check it in my while loop. IOC (0x96.3) is set.
:=
:=If GPIF is set and you're not getting an interrupt, it's probably because you don't have INT_RB enabled and an #INT_RB function -- at least in my version. For this to work as I think you want it to (interrupt on GP3 change) you have to:
:=
:=Make GP3 an input. Outputs won't trigger an interrupt.
On the 675 GP3 is always an input according to the datasheet: "The exception is GP3, which is input only and its
TRISIO bit will always read as ‘1’. Example 3-1 shows
how to initialize GPIO."
:=Set IOCB bit 3.
Done. See above.
:=Read the port (this clears the IOC logic).
I will play with this. Hmmmm.
:=Enable INT_RB (GPIO interrupt-on-change).
Already done by enable_interrupts(INT_RA3)
:=Enable global interrupts.
Done
:=
:=Hope this helps.
I gave me one more thing to investigate :)
:=
:=Dale
___________________________
This message was ported from CCS's old forum
Original Post ID: 14090 |
|
|
bgpartri Guest
|
Re: GP3 interrupt on 12F675 |
Posted: Wed Apr 30, 2003 1:22 pm |
|
|
I tried reading the port before entering the while loop. It doesn't make any difference.
:=:=Read the port (this clears the IOC logic).
:=
:=I will play with this. Hmmmm.
:=
___________________________
This message was ported from CCS's old forum
Original Post ID: 14094 |
|
|
R.J.Hamlett Guest
|
Re: GP3 interrupt on 12F675 |
Posted: Wed Apr 30, 2003 3:15 pm |
|
|
:=I am trying to get a 12F675 to respond to an interrupt on level change on GP3. I have set up all of the interrupt enabling switches (I think), but still no interrupt.
:=
:=In the following code, I sit in the while loop waiting for an interrupt. I check GIE, GPIE and IOC and they are all set. When I push my button, I get the 4 green flashes that show I am getting GPIF (flag) bit set. But no interrupt ?!?!? What am I missing?
:=
:=#include "12F675.h"
:=#include "675PICReg.h"
:=#fuses intrc_io, NOWDT, NOPROTECT, PUT, BROWNOUT, NOMCLR
:=#use delay (clock=2000000)
:=
:=#define RED PIN_A1
:=#define GREEN PIN_A2
:=#define BUTTON PIN_A3
:=#bit GPIF_BIT = 0x0B.0
:=#bit GPIE_BIT = 0x0B.3
:=#bit GIE_BIT = 0x0B.7
:=#bit IOC_BIT = 0x96.3
:=
:=.....
:=
:=#INT_RB
:=void int_rb_isr(void)
:={
:= got_interrupt = TRUE;
:= disable_interrupts(INT_RA3);
:=}
:=
:=void FlashRED(int count)
:=...
:=void FlashGREEN(int count)
:=....
:=void main(void)
:={
:=
:= setup_comparator(nc_nc_nc_nc);
:= setup_adc_ports(NO_ANALOGS);
:= setup_adc(ADC_OFF);
:= FlashRED(2);
:=
:= got_interrupt = FALSE;
:= GPIF_BIT = 0;
:= enable_interrupts(INT_RA3);
:= enable_interrupts(GLOBAL);
:= while(1)
:= {
:= if(GPIF_BIT)
:= {
:= FlashGREEN(4);
:= Delay_ms(2000);
:= GPIF_BIT = 0;
:= }
:= if(GPIE_BIT)
:= {
:= FlashRED(2);
:= Delay_ms(2000);
:= GPIF_BIT = 0;
:= }
:= if(GIE_BIT)
:= {
:= FlashGREEN(2);
:= Delay_ms(2000);
:= GPIF_BIT = 0;
:= }
:= if(IOC_BIT)
:= {
:= FlashRED(3);
:= Delay_ms(2000);
:= GPIF_BIT = 0;
:= }
:=
:= if(got_interrupt == TRUE)
:= {
:= got_interrupt = FALSE;
:= // Wait for debounce period.
:= delay_ms(500);
:= GPIF_BIT = 0;
:= FlashRED(1);
:= FlashGREEN(1);
:= FlashRED(1);
:= // Then re-enable interrupts.
:= enable_interrupts(INT_RA3);
:= }
:= }
:=
:=
:=}
You give no definition for INT_RA3. Now the chip doesn't support a seperate RA3 interrupt, but only the port change interrupt on this line, which it appears you are actually using, but 'renaming' as INT_RA3. Presumably you have a definition for this in the include file.
You don't give your definitions for 'got_interrupt', but presumably this is a global defintion somewhere in the header file.
Now the 'normal' sequence to deal with this would then be to use:
#byte IOCB=0x96
IOCB=0x8;
dummy=input_b();
GPIF_BIT=0;
enable_interrupts(GLOBAL);
enable_interrupts(INT_RB);
This should ensure that the register is read (resetting the latch), and the interrupt flag is initially clear.
You must then read the port inside the interrupt handler, otherwise the routine will never normally return from the handler, continuing to interrupt. In your case, since you disable the interrupt inside the handler, you do exit. The problem is that the 'GPIF' bit, cannot be cleared, if the port is not read (paragraph 3.2.2 in the data sheet - 'A mismatch condition will continue to set GPIF. Reading GPIO will clear the mismatch condition, and allow GPIF to be cleared').
Hence what I think is happening, is that your routine starts, and immediately interrupts. The interrupt handler, then disables the interrupt, and returns. GPIF, then immediately gets set again (hence your green LED flash).
Now several other parts won't then work (the attempt to clear GPIF, in the IOC test routine, then fails, since the port still hasn't been read), while the 'got interrupt' routine, also still fails to clear GPIF, and will interrupt as soon as the interrupt is re-enabled.
So I'd simply add a dummy read of the input port, in front of every location where you attempt to reset the GPIF bit, and change the initialisation to ensure the bit is not set at the start.
You may then get further. :-)
Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 14098 |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|