View previous topic :: View next topic |
Author |
Message |
Dave_25152
Joined: 11 Dec 2010 Posts: 60
|
My program does not come out of the interruption |
Posted: Fri May 25, 2012 3:50 am |
|
|
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: 19515
|
|
Posted: Fri May 25, 2012 4:12 am |
|
|
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
|
|
Posted: Fri May 25, 2012 4:45 am |
|
|
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
|
|
Posted: Fri May 25, 2012 5:51 am |
|
|
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
|
|
Posted: Fri May 25, 2012 6:05 am |
|
|
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
|
|
Posted: Fri May 25, 2012 8:29 am |
|
|
The problem is now solved.
Thank you very much! |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Fri May 25, 2012 8:41 am |
|
|
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
|
|
Posted: Fri May 25, 2012 8:53 am |
|
|
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 |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri May 25, 2012 10:44 am |
|
|
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
|
|
Posted: Fri May 25, 2012 11:22 am |
|
|
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
|
|
Posted: Fri May 25, 2012 12:16 pm |
|
|
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
|
|
Posted: Sat May 26, 2012 1:06 am |
|
|
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
|
|
Posted: Sat May 26, 2012 1:47 am |
|
|
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
|
|
Posted: Sat May 26, 2012 4:50 am |
|
|
Dave_25152 wrote: |
Now put, and is working well |
The problem is solved.
Now works fine, using the latest code that I put ... ;)
It was enough just to read of PORTB.
Thank you. |
|
|
|