|
|
View previous topic :: View next topic |
Author |
Message |
d00dajo
Joined: 20 Jul 2004 Posts: 34
|
Trouble using RB<4:7> Int-on-Change with keygrid |
Posted: Tue Jul 20, 2004 1:31 am |
|
|
Hi,
I am new to the PIC uController family and I seem to have run into a problem with the port B interrupt on change (RB4:7). The PIC in question is a PIC16F628a and the hardware consists of 9 buttons connected in gridlayout. That is, there are three outputs ROW1,ROW2,ROW3 and three inputs COL1,COL2,COL3 (RB7:RB5). Internal pullups are enabled on the PORTB and '0' are presented at ROW1,2,3. Pressing button 1 will connect ROW1 and COL1, which will give a change of High to Low on RB7, which triggers the RB_Interrupt. Similar for the other buttons. Now, since the buttons are connected in a grid format, I need to decode which button was pressed. The simple way is to output low on ROW1, high on ROW2,3 and read the inputs. If one COL is low, I have found the button (Button1,2 or 3). Otherwise, I continue and ouput low on ROW2 and high on ROW1,3 and read the inputs and so on. Now, obviously, this method of decoding the buttons will undoubtetly give rise to new interrupts (The COL input will go from 0 to 1 to 0 during the decode routine). So, I need to disable the RB_INT interrupts during this decode, this I do using disable_interrupts(INT_RB);
Now, something goes wrong anyway, because while pressing button1 (as an example), the RB interrupt service routine runs over and over again(This is NOT because of bounces on the buttons!). I cant seem to find the error in thought, perhaps someone can assist? Code below:
/*This is the interrupt serivce routine for INT_RB*/
#int_RB
void RB_isr()
{
disable_interrupts(INT_RB);
set_tris_a(0x10);
set_tris_b(0xF0);
output_low(PIN_A6); //A6 and A/ are just a LED indicating ISR run.
output_high(PIN_A7); //
delay_ms(500); //Debounce
output_low(PIN_A7);
if( (input(COL3) == 0) || (input(COL2) == 0) ||(input(COL1) == 0))
{
BHBP = 1;
}
enable_interrupts(INT_RB);
}
void decodeButton2()
{
disable_interrupts(INT_RB);
output_low(ROW1);
output_high(ROW2);
output_high(ROW3);
if ( input(COL1) == 0 )
{
button = 0x01;
}
if( input(COL2) == 0){
button = 0x02;
}
if( input(COL3) == 0){
button = 0x04;
}
//When pushing button1 the output_high(ROW1) is what
//triggers the looping interrupt service routine.
output_high(ROW1);
output_low(ROW2);
output_high(ROW3);
if ( input(COL1) == 0 )
{
button = 0x08;
}
if( input(COL2) == 0){
button = 0xFF;
}
output_low(ROW1);
output_low(ROW2);
output_low(ROW3);
enable_interrupts(INT_RB);
}
void main()
{
set_tris_a(0x10);
set_tris_b(0xE0);
button = 0x00;
port_b_pullups(TRUE); //Enable Internal Pullups
output_low(ROW1); //Output Low on ROWs
output_low(ROW2);
output_low(ROW3);
mode = NORMAL; //Reset to Normal Operation!!!
enable_interrupts(INT_RB); //Enable Interrupt-on-change RB7:4
enable_interrupts(GLOBAL); //Enable Interrupts
while( TRUE )
{
if(BHBP==1)
{
BHBP=0;
decodeButton2();
}
if(button == 0x01)
{
output_high(PIN_B0); //B0 to B3 are LED indicators.
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
}
if(button==0x02)
{
output_low(PIN_B0);
output_high(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
}
}
}
//Daniel |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jul 20, 2004 5:58 am |
|
|
Hi,
You really should post this in the other section. This section is intended for posting of code that you wish to share with others and not for problems/questions.
Now as to your problem. The first thing that pops out to me is that you are not clearing the interrupt flags before you enable them. Even though you disable the interrupt, then event still happens and the flag will get set. When you enable the int, the flag was set so the int gets serviced. |
|
|
d00dajo
Joined: 20 Jul 2004 Posts: 34
|
|
Posted: Tue Jul 20, 2004 6:15 am |
|
|
Hi!
Sorry for posting in the wrong section.
Not clearing the interrupt you say... Hmm, I was under the impression that disable_interrupts would do exactly that.... Would you happen to know the name of the instruction that will clear the actual "interrupt has occured" . I didnt find such an instruction in my manual, but it's probably my misstake.
Thanks for your help
//Daniel |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jul 20, 2004 6:23 am |
|
|
Well you would have to look at the lst file to see if the flag is cleared with the disable call or even the enable call. I would hope not as you might actually need this sort of information. All the more reason I never used the CCS functions. But to clear the flag, just clear the bit in the PIR or Intcon register. Look in the data sheet for the PIC that you are using. The RB interrupt flag on many PICs is bit 0 of the INTCON register. |
|
|
d00dajo
Joined: 20 Jul 2004 Posts: 34
|
|
Posted: Tue Jul 20, 2004 6:44 am |
|
|
Just as you suspected, the INTCON<0> register was indeed the problem. Thank you for your assistance!
//Daniel |
|
|
Darren Rook
Joined: 06 Sep 2003 Posts: 287 Location: Milwaukee, WI
|
|
Posted: Tue Jul 20, 2004 6:56 am |
|
|
Even though the problem was solved, the topic has been moved to the appropiate forum. |
|
|
|
|
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
|