CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

GP3 interrupt on 12F675

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bgpartri
Guest







GP3 interrupt on 12F675
PostPosted: Wed Apr 30, 2003 11:11 am     Reply with quote

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
PostPosted: Wed Apr 30, 2003 12:14 pm     Reply with quote

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
PostPosted: Wed Apr 30, 2003 12:18 pm     Reply with quote

:=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
PostPosted: Wed Apr 30, 2003 12:33 pm     Reply with quote

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
PostPosted: Wed Apr 30, 2003 12:41 pm     Reply with quote

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
PostPosted: Wed Apr 30, 2003 1:22 pm     Reply with quote

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
PostPosted: Wed Apr 30, 2003 3:15 pm     Reply with quote

:=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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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