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 support@ccsinfo.com

My program does not come out of the interruption

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



Joined: 11 Dec 2010
Posts: 60

View user's profile Send private message

My program does not come out of the interruption
PostPosted: Fri May 25, 2012 3:50 am     Reply with quote

Hello all.

I have spent much time trying to solve the problem, but without success.

What kind of syntax should I use for that interrupt routine is finished, return to the main program.

Today, when I get a pulse on pin B1, the interrupt is enabled, but the C5 pin will not turn off.

I've tried various programs but can not do it, when the interruption ends back to the main program.

Code:
#include <16F887.h>
#fuses INTRC_IO, NOWDT, NOMCLR, PUT, BROWNOUT, NOLVP
#use delay(clock=8000000)
#use RS232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)

int1 a;

#INT_RB
void conta() 
{
output_high(PIN_C5);
a=0;
}


void pic_init()
{
   SETUP_TIMER_0(T0_INTERNAL|T0_DIV_8);    //overflow a 1.024mS incrementa a 4uS
   setup_timer_2(T2_DIV_BY_16,255,1);      //2.0 ms overflow, 2.0 ms interrupt
   setup_ccp1(CCP_PWM);

   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   setup_oscillator(OSC_8MHZ);
   enable_interrupts(GLOBAL);
   setup_uart(1);
}

void main()
{

int a;

OUTPUT_A(0);
OUTPUT_B(0);
OUTPUT_C(0);
OUTPUT_D(0);
OUTPUT_E(0);

   set_tris_A(0b00000000);
   set_tris_B(0b00000010);
   set_tris_C(0b00000000);
   set_tris_D(0b00000000);
   set_tris_E(0b0000);

pic_init();


a=1;
   clear_interrupt(INT_RB1);
   enable_interrupts(INT_RB1); //a change on RB triggers interrupt

while(a)
   {
   output_high(PIN_A1);
   delay_ms(500);
   output_low(PIN_A1);
   delay_ms(500);
   }
   

disable_interrupts(INT_RB1);
disable_interrupts(global);
delay_ms(500);
output_low(pin_c5);

while(1);

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Fri May 25, 2012 4:12 am     Reply with quote

It would.

You _must_ read portb, in the INT_RB handler.

If you look at the data sheet:
"Reading or writing PORTB will end the mismatch
condition and allow flag bit RBIF to be cleared."

The compiler will clear the interrupt if it can, but it _cannot_ be cleared, until port B is read.

As a general 'comment', this is true of all interrupts where something holding something, or comparing something like this applies. So (for instance), the INT_RDA, _must_ read the byte from the serial, or it'll trigger for ever. INT_TBE, _must_ write a byte to the serial transmit buffer (or disable itself), or again it'll trigger for ever.

Best Wishes
Dave_25152



Joined: 11 Dec 2010
Posts: 60

View user's profile Send private message

PostPosted: Fri May 25, 2012 4:45 am     Reply with quote

Thanks for the reply.

So how can I solve this problem?

During the interruption, nothing is written / read on PORTB.

I do not understand ...


I wanted to enable an interrupt with a pulse outside. This disruption would put a TIMER to 0 and back again to the main program.

As was not working, I decided to use a LED's to make things simpler, but the problem continues ...



I really appreciate the time you are losing to answer me.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri May 25, 2012 5:51 am     Reply with quote

Quote:
So how can I solve this problem?

As said, by performing a read on port B. May be a dummy read.
Quote:
During the interruption, nothing is written / read on PORTB.

But it's required. It's specific for the port B change interrupt. The last read state is stored internally and compared with the present state. As long as a mismatch exists, the interrupt is triggered. Basically simple.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Fri May 25, 2012 6:05 am     Reply with quote

Your program IS exiting the interrupt normally, but it immediately re-enters because you have not set a new state for port B. The PIC keeps comparing the current state to the very old one and they stay different so it interrupts.
_________________
The search for better is endless. Instead simply find very good and get the job done.
Dave_25152



Joined: 11 Dec 2010
Posts: 60

View user's profile Send private message

PostPosted: Fri May 25, 2012 8:29 am     Reply with quote

The problem is now solved.


Thank you very much!
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Fri May 25, 2012 8:41 am     Reply with quote

Hi,

You know, for the sake of future forum users, a report of "The problem is now solved" doesn't really help a lot! Why not post a copy of your working code so that others may benefit from the forum, just as you did???

John
Dave_25152



Joined: 11 Dec 2010
Posts: 60

View user's profile Send private message

PostPosted: Fri May 25, 2012 8:53 am     Reply with quote

OK. You have every reason.

Here is the code.



Code:
int1 a;

#INT_RB
void conta() 
{
//output_high(PIN_B2); //any change on PORTB
disable_interrupts(INT_RB1);
clear_interrupt(INT_RB1);
output_low(pin_c5);
a=0;
}



void pic_init()
{
   SETUP_TIMER_0(T0_INTERNAL|T0_DIV_8);    //overflow a 1.024mS incrementa a 4uS
   setup_timer_2(T2_DIV_BY_16,255,1);      //2.0 ms overflow, 2.0 ms interrupt
   setup_ccp1(CCP_PWM);

   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   setup_oscillator(OSC_8MHZ);
   enable_interrupts(GLOBAL);
   setup_uart(1);
}

void main()
{

int a;

OUTPUT_A(0);
OUTPUT_B(0);
OUTPUT_C(0);
OUTPUT_D(0);
OUTPUT_E(0);

   set_tris_A(0b00000000);
   set_tris_B(0b00000010);
   set_tris_C(0b00000000);
   set_tris_D(0b00000000);
   set_tris_E(0b0000);

pic_init();


a=1;
output_high(PIN_C5);
   clear_interrupt(INT_RB1);
   enable_interrupts(INT_RB1); //a change on RB triggers interrupt

while(a)
   {
   output_high(PIN_A1);
   delay_ms(500);
   output_low(PIN_A1);
   delay_ms(500);
   }
   

while(1);

}



I think yesterday had tested this code, but had not worked.

Now put, and is working well Smile
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri May 25, 2012 10:44 am     Reply with quote

Even more useful:-

Highlight the crucial elements which actually solved the problem.

Rather than buried in a mass of code.

Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 25, 2012 11:22 am     Reply with quote

You are still not reading pin B1 inside the #int_rb routine, so you have
not cleared the "Change Condition". Instead, you have disabled INT_RB1
interrupts inside the isr.

If your purpose was just to get one INT_RB interrupt, and then don't get
any more of them, your method would work. But if you want to keep
the #int_rb routine enabled, and available to process more interrupts,
then you certainly need to read pin B1 with the input() function inside
the #int_rb routine.

See this sample code. Notice how it reads the "SW_PIN" inside the isr:
http://www.ccsinfo.com/forum/viewtopic.php?t=41951&start=1
Dave_25152



Joined: 11 Dec 2010
Posts: 60

View user's profile Send private message

PostPosted: Fri May 25, 2012 12:16 pm     Reply with quote

Hello

Yes, I just want to create a single interruption. But I'll use your method is certainly better.

As I told you, yesterday I tried the above program and did not work very well.


Thank you.


Code:
#INT_RB
void conta() 
{
int1 int;

clear_interrupt(INT_RB1);

int = input(PIN_B1);

output_high(PIN_C5);
}
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat May 26, 2012 1:06 am     Reply with quote

Code:
#INT_RB
void conta() 
{
int1 int;

clear_interrupt(INT_RB1);
int = input(PIN_B1);
output_high(PIN_C5);
}

The code works, because CCS also clears the interrupt flag before exiting the interrupt function.

Your clear_interrupt() call is useless, it's performed before reading port B, so the interrupt flag isn't actually cleared.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat May 26, 2012 1:47 am     Reply with quote

You're making it difficult for us to help you.

Quote:
As I told you, yesterday I tried the above program and did not work very well.

What does work?

What does not work that should?

What are you expecting to happen?

Mike
Dave_25152



Joined: 11 Dec 2010
Posts: 60

View user's profile Send private message

PostPosted: Sat May 26, 2012 4:50 am     Reply with quote

Dave_25152 wrote:


Now put, and is working well Smile


The problem is solved.

Now works fine, using the latest code that I put ... ;)

It was enough just to read of PORTB.

Thank you.
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