View previous topic :: View next topic |
Author |
Message |
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
INT ext |
Posted: Mon Dec 05, 2011 3:42 pm |
|
|
Dear all,
I made this small program and unfortunately the INT EXT is not working and the RB Interrupt is working fine. PIC used is 16f876 on 4MHz crystal.
Code: |
#include <garage.h>
#int_RB
void RB_isr(void)
{
if(input(PIN_B4) )
{
output_A(13);
}
if(input(PIN_B5) )
{
output_A(17);
}
if(input(PIN_B6) )
{
output_A(18);
}
}
#int_EXT
void EXT_isr(void)
{
if(input(PIN_B1) == 1 )
{
output_A(02);
}
if(input(PIN_B2) == 1 )
{
output_A(03);
}
if(input(PIN_B3) == 1 )
{
output_A(04);
}
}
#int_TIMER1
void TIMER1_isr(void)
{
}
void main()
{
set_tris_b(0xff);
set_tris_a(0x00);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //524 ms overflow
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1)
{
sleep();
}
} |
thanks for your help |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Dec 05, 2011 4:49 pm |
|
|
you have potentially troublesome overlap here :
1- i will assume U know the EXT int is triggered by pin B0 not B1
2- also i ALWAYS do a full READ of port_B
dumi=input_b();
before exiting the ISR to avoid hanging / missed int problems
&&
personally i would do this with BOTH ISRs that you show
3- i would do a CLEAR_INTERRUPT() call to each int you enable
BEFORE enabling them in your INIT startup routine
4- lastly and i would NOT have the timer ISR call an empty routine |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 05, 2011 5:02 pm |
|
|
1. Describe the external circuit on pin B0 (for INT_EXT).
2. What are the voltage levels placed on pin B0 by this circuit ?
3. What is the Vdd voltage of the PIC ?
4. What are your #fuses ?
5. What is your compiler version ?
Quote: | 4- lastly and i would NOT have the timer ISR call an empty routine |
It doesn't do any harm. |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Tue Dec 06, 2011 1:38 am |
|
|
thanks for your reply asmboy and PCM Programmer.
I am using PIC16F876, 4MHz, and the supply voltage is constant 5V. I know that the EXT works on B0 but I've put diodes to B1, B2, and B3 (instead of OR gates) to have three inputs on the EXT. I am 100% that the design is correct, do not worry
the compiler I am using is the 4.093. Is this makes any difference?
Why I should clear interrupts before enable them? To be 100% sure that everything is clear? I've never hear this before but if this is the case, it makes sense...thanks. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Dec 06, 2011 4:07 am |
|
|
A lot of interrupts can get 'accidentally' triggered when you initialise the chip. For instance, the edge triggered interrupts may get set if you change the edge they are programmed to use. Timers may roll over after the chip wakes (typically they start at 0xFFFF, so a roll over to '0' happens with just one clock cycle). Things like RS232 inputs may see the input drawn low for a few uSec before buffer chips like the MAX232 wake up. So it is always 'safer' to assume they may well be set at boot, or write the handler so it doesn't matter if they do accidentally trigger.
Now, are you sure you are using the right 'edge' for INT_EXT?. Unlike the RB interrupt, which triggers on both edges of a signal, this only triggers on one. You are testing for pins being high, so you need to have the interrupt trigger on the 'low to high' edge, or this will never be the case. Look at the ext_int_edge setting.
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Dec 06, 2011 4:20 am |
|
|
You have not configured for the INT_EXT to be triggered by the rising or falling edge.
I don't know the default setting, but lets assume it is the falling edge, then your INT_EXT interrupt will fire but reading of the B1 to B3 pins will always be 0 and nothing is being output.
For testing this I suggest you add an extra test to the INT_EXT routine where you output a value when B1-B3 all are zero.
Edit: I see Ttelmah posted a similar reply while I was typing this. |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Tue Dec 06, 2011 10:50 am |
|
|
thanks to all,
I've replaced the following code:
Code: |
#int_EXT
void EXT_isr(void)
{
if(input(PIN_B1) == 1 )
{
output_A(02);
}
if(input(PIN_B2) == 1 )
{
output_A(03);
}
if(input(PIN_B3) == 1 )
{
output_A(04);
}
} |
with this:
Code: |
#int_EXT
void EXT_isr(void)
value = input_b();
{
if(value = 0b00000011)
{
output_A(02);
}
if(value = 0b00000101)
{
output_A(03);
}
if(value = 0b00001001 )
{
output_A(04);
}
}
|
but still no luck. I also inserted the ext_edge (l_to_h) but still not working. Any help please? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Dec 06, 2011 10:55 am |
|
|
Two problems:
Unless you _know_ the values of the top four bits are going to be '0', again 'of course' it won't work.
It also won't work, because '=' is the value assignment operator, not the 'test' operator '=='.
if ((value & 0xF) == 0b0000011)
Best Wishes |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Tue Dec 06, 2011 11:36 am |
|
|
yes, I inserted "==" and not "="..it was a misprint. still no luck with
Code: | if((input_val& 0xF) == 0b00001001)
{
output_A(04);
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Dec 06, 2011 11:51 am |
|
|
Still, you have not added debug code for the situation where none of the inputs is what you expect them to be. Now you assume the interrupt is not working where it very well might work but with different input values.
One reason for different input values is the edge on which INT_EXT is triggered. You, again, assume it is the positive edge but nowhere in your code this is configured so it might as well be the triggered by the negative edge. Ttelmah gave you a hint for the command to change this setting. |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Tue Dec 06, 2011 12:06 pm |
|
|
sorry I always forget to put the whole code. Here it is:
Code: |
//variables
byte input_val;
#int_RB
void RB_isr(void)
{
if (input(PIN_B4))
{
output_A(13);
}
if(input(PIN_B5) )
{
output_A(17);
}
if(input(PIN_B6) )
{
output_A(18);
}
}
#int_EXT
void EXT_isr(void)
{
if (INPUT(PIN_B1))
{
output_A(30);
}
}
#int_TIMER1
void TIMER1_isr(void)
{
}
void main()
{
set_tris_b(0xff);
set_tris_a(0x00);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //524 ms overflow
ext_int_edge( h_TO_l );
clear_interrupt(INT_RB);
clear_interrupt(INT_EXT);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1)
{
sleep();
}
} |
|
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Tue Dec 06, 2011 12:08 pm |
|
|
the code that I submitted is the latest one I am experiment in... |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Dec 06, 2011 1:15 pm |
|
|
you are still not initializing fully
Quote: |
You have not configured for the INT_EXT |
WHICH direction of change will take the INT ISR???????? |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Tue Dec 06, 2011 1:59 pm |
|
|
sorry asmboy but I am not understanding you. What do yo mean by "initializing fully "? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Tue Dec 06, 2011 2:15 pm |
|
|
The edge interrupt(s - depending on processor) can be configured to trigger on either a rising or falling edge. Look up ext_int_edge() in the help file. |
|
|
|