View previous topic :: View next topic |
Author |
Message |
jahan
Joined: 04 Apr 2005 Posts: 63
|
Interrupt B0? B1? which interrupt? |
Posted: Wed Jun 15, 2005 12:03 pm |
|
|
16F877 - PCM 3.223
design has the followings:
push buttons on B0, B1, B2 with pull up resistors.
LEDs on B3, B4, B5.
All LED off at start up.
Can anybody post simple interrupt code to check which switch was pushed (B0,B1,B2) by turning ON one LED (B3, B4, B5 respectively) for 1 second?
Last edited by jahan on Wed Jun 15, 2005 3:38 pm; edited 3 times in total |
|
|
jahan
Joined: 04 Apr 2005 Posts: 63
|
I found isr_rb but it does not check RB0, RB1 or RB2. :( |
Posted: Wed Jun 15, 2005 1:03 pm |
|
|
I found this sample code on CCS web site, but it does not use int_ext.
plus, it can check only on RB4-RB7.
Any suggestion is greatly appriciated.
Code: | #int_rb
void rb_isr(void) {
byte changes;
changes = last_b ^ port_b;
last_b = port_b;
if (bit_test(changes,4 )&& !bit_test(last_b,4)) {
//b4 went low
}
if (bit_test(changes,5)&& !bit_test (last_b,5)) {
//b5 went low
}
delay-ms (100); //debounce
}
|
|
|
|
Guest
|
I've been looking for this ... but have not found anything. |
Posted: Wed Jun 15, 2005 2:20 pm |
|
|
jahan, if you found anything , please share it with the rest of forum.
I'll be happy to see it. I'm sure others will too.
-lone-star |
|
|
jahan
Joined: 04 Apr 2005 Posts: 63
|
can somebody check this code and bless it. |
Posted: Wed Jun 15, 2005 3:38 pm |
|
|
I've come up with the following code for checking on RB0 or RB1 interrupt and increment a counter for each.
please review and bless (correct) as needed.
your feed back is greatly appreciated.
Code: | #include <16F84A.h>
#fuses NOWDT,NOPROTECT
#use delay (clock=4000000)
#use rs232(baud=9600, xmit=PIN_B6, rcv=PIN_B7)
byte FlagB0 = 0;
byte FlagB1 = 0;
char got_interrupt;
char RB0_count, RB1_count;
#bit INTF_BIT0 = 0x0B.0
#bit INTF_BIT1 = 0x0B.1
#int_ext
void int_ext_isr(void) {
disable_interrupts(INT_EXT);
got_interrupt = TRUE;
if (!input(PIN_B0)) { //B0 = low
FlagB0 = 1;
RB0_count++;
}
if (!input(PIN_B1)) { //B1 = low
FlagB1 = 1;
RB1_count++;
}
clear_interrupt(INT_EXT);
}
void Handle_Interrupt(void) {
printf("RB0=%d RB1=%d",RB0_count,RB1_count);
if (FlagB0 == 1) {
FlagB0 = 0; // clear flag
delay_ms(50); // debounce
INTF_BIT0 = 0; // reclear incase during debounce got set again
}
if (FlagB1 == 1) {
FlagB1 = 0; // clear flag
delay_ms(50); // debounce
INTF_BIT1 = 0;
}
}
void main (void) {
output_float(PIN_B0);
output_float(PIN_B1);
port_b_pullups(TRUE);
delay_us(10);
RB0_count = 0;
RB1_count = 1;
got_interrupt = FALSE;
ext_int_edge(H_TO_L);
INTF_BIT0 = 0;
INTF_BIT1 = 0;
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while(true) {
if (got_interrupt == TRUE) {
got_interrupt = FALSE;
Handle_Interrupt();
enable_interrupts(INT_EXT);
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 15, 2005 3:46 pm |
|
|
There is no interrupt on pin RB1.
From the 16F84A data sheet, in the Special Features of the CPU - Interrupts section:
Quote: | The PIC16F8X has 4 sources of interrupt:
• External interrupt RB0/INT pin
• TMR0 overflow interrupt
• PORTB change interrupts (pins RB7:RB4)
• Data EEPROM write complete interrupt |
|
|
|
jahan
Joined: 04 Apr 2005 Posts: 63
|
Thank you for your feed back |
Posted: Wed Jun 15, 2005 4:31 pm |
|
|
I could not figure out why I cannot see anything on RB1.
Now I see why!!!
Do you know of any PIC MCU to have more than 1 External INT (similar to RB0 on 16F84A)?
Thankx again. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Wed Jun 15, 2005 5:45 pm |
|
|
The 18F452 has 3 external interrupts: B0, B1, and B2. |
|
|
Sandgroper Guest
|
Re: Thank you for your feed back |
Posted: Wed Jun 15, 2005 6:16 pm |
|
|
jahan wrote: | I could not figure out why I cannot see anything on RB1.
Now I see why!!!
Do you know of any PIC MCU to have more than 1 External INT (similar to RB0 on 16F84A)?
Thankx again. |
You can still use interrupts for multple inputs on the PIUC16F84 but it requires a little more work. The upper four bits on port B support interrupt on change. When the interrupt occurs you read the current port value and compare it to the previous value (similar to jahan's example). The difference is the bit that has changed. However do not do any debouce delays in the interrupt handler. A "cleaner" way of doing the debouce is to start a (debounce) timer in the Interupt on Change (IOC) handler. The timer is reset / restarted whenever an IOC event of interest (ie one of the bits you are interested in) occurs.
Whenever the debouce timer expires you know that it has been "debouce-time" since any of the inputs of interest changes and therefore you have a new "debounce" switch reading available. The timer flag can be polled either in the program body or used to fire a timer interrupt indicating a new value is available.
The disadvantage with this handler is that any read of port b outside the handler will clear the IOC interrupt condition. It also means that if you are using other bits of port B for outputs you cannot use any read-modify-write instructions such as bsf, bcf. This is because the read part of the instruction will clear the IOC flag.
BTW - With the exception of using existing (legacy) development systems, I do not understand why people still use the 16F84 for new projects. It had its day but is now a dinosaur. The 18F family offers significant features, performance and flexibility over the 16F family at a similar price point.
Rgds, Andrew |
|
|
Christophe
Joined: 10 May 2005 Posts: 323 Location: Belgium
|
|
Posted: Thu Jun 16, 2005 5:43 am |
|
|
just poll your inputs and use a flag...
Code: | //*************************** AAN UIT CONTROL ********************************//
if (!input(AAN_UIT) && !sleep_mode)
{
sleep_mode = TRUE;
printf("%c%S%c",COMMANDO_BYTE, SLEEP_COMMANDO,0);
}
if (input(AAN_UIT) && sleep_mode)
{
sleep_mode = FALSE;
printf("%c%S%c",COMMANDO_BYTE, WAKE_COMMANDO,0);
} |
sends command when switch is moved (AAN_UIT) |
|
|
|