View previous topic :: View next topic |
Author |
Message |
karlosguay
Joined: 12 Jun 2013 Posts: 20
|
I can not stop RB interrupt |
Posted: Wed Jun 12, 2013 10:28 am |
|
|
I'm working with a 16F946. I need to use 2 ints: external in B0 and change in B6.
The code is:
Code: |
IOCB = 0b01000000;
enable_interrupts (INT_TIMER1);
enable_interrupts (INT_RB6);
enable_interrupts (GLOBAL);
bit_set(OPTION_REG,6);
enable_interrupts (INT_EXT);
#INT_EXT
void MiroPulso()
{
pulso=get_timer0();
disable_interrupts (INT_RB);
bit_clear(INTCON,1);
set_timer0(0);
}
#INT_RB
void pulsostriac()
{
int temp;
output_high (PIN_D2);
delay_us(999);
output_low (PIN_D2);
temp |= input(PIN_B6);//esto lo hago para parar la interrupciĆ³n
bit_clear(INTCON,0);//clear RBIF
} |
Why I can't stop int B6??
the INT_EXT is running but don't stop INT_RB |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Jun 12, 2013 2:24 pm |
|
|
Read the manual and/or the data sheet carefully.
The INT_RB interrupt flag is cleared by reading port_B.
You're not.
Mike |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 12, 2013 6:15 pm |
|
|
What external device is connected to Pin B6 ?
Post a detailed description of the external circuit connections to Pin B6.
Also post your CCS compiler version. |
|
|
karlosguay
Joined: 12 Jun 2013 Posts: 20
|
|
Posted: Thu Jun 13, 2013 2:27 am |
|
|
Thanks to Admin for edit my Discussion. Good job.
Hi Mike, i change the code of INT_RB but no work fine.
In B6 there are a 50 Hz square signal. I need INT_RB to switch on a Triac.
I use CCS 4.114.
Code: |
IOCB = 0b01000000;
enable_interrupts (INT_TIMER1);
enable_interrupts (INT_RB);
enable_interrupts (GLOBAL);
bit_set(OPTION_REG,6);
enable_interrupts (INT_EXT);
#INT_EXT
void MiroPulso()
{
pulso=get_timer0();
disable_interrupts (INT_RB);
bit_clear(INTCON,1);
set_timer0(0);
}
#INT_RB
void pulsostriac()
{
output_high (PIN_D2);
delay_us(999);
output_low (PIN_D2);
if input(PIN_B6){};//esto lo hago para parar la interrupciĆ³n
bit_clear(INTCON,0);//clear RBIF
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Thu Jun 13, 2013 2:56 am |
|
|
First, you don't have to clear the interrupt flags in either interrupt.
The compiler does this automatically for you, unless you specify the interrupt with 'no_clear'. Waste of an instruction.
Next problem, use of a delay in an interrupt. This probably will not let the code work. The PIC, does not allow re-entrant code (something called inside itself). This is because of the architecture of the chip, which doesn't have a register stack. Hence if a function is used in the interrupt handler, interrupts _have_ to be disabled around the same code everywhere in the 'main' code. Means that if _anything_ uses delays in the external code, the interrupt will not be responded to, till these finish. Think about using hardware for this delay. The CCP, can be programmed to trigger it's output a period in the future. So if you use the CCP for the required trigger pulse, you could simply program this to clear the pulse in a mSec, set the pulse, and leave the interrupt.
Always much nicer to let hardware do things if you can.....
Then use "ext_int_edge(L_TO_H);" instead of fiddling around with the option register.
Then again, don't fiddle with IOCB. Instead use "enable_interrupts(INT_RB6);". This enables INT_RB, and sets up the masking for it to operate on B6, all in one operation. You still need to call your handler INT_RB.
Then you have brackets missing on the line to read the port in the interrupt.
Post _real_ code.
Much simpler than using 'if', which also may well get optimised away by the compiler realising you do nothing when you read the port, is:
Code: |
int1 dummy;
dummy=input(PIN_B6);
|
Best Wishes |
|
|
karlosguay
Joined: 12 Jun 2013 Posts: 20
|
|
Posted: Thu Jun 13, 2013 4:36 am |
|
|
Many thanks.
I move the code "delay_us(999)" to the MAIN, and work fine.
And all the advices are very good.
Many, many THANKS. |
|
|
|