View previous topic :: View next topic |
Author |
Message |
Perrinsky
Joined: 16 Nov 2014 Posts: 2
|
INT_RB issue with PIC 16F887 |
Posted: Sun Nov 16, 2014 1:31 am |
|
|
Hi, I have a question about why the next code works perfectly with the 16F877 but if I change the device to a 16F887 it does nothing.
Code: |
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
BYTE blink = 0;
#int_rb
void button_isr() {
delay_ms (20); //debounce
if( !input(PIN_B4) && !blink )
blink = 1;
else
if( !input(PIN_B4) && blink )
blink = 0;
}
void main() {
enable_interrupts(global);
enable_interrupts(int_rb);
ext_int_edge( H_TO_L );
do {
if(blink){
output_high(PIN_D7);
delay_ms(500);
output_low(PIN_D7);
delay_ms(500);
}
} while (TRUE);
}
|
Thanks in advance, best regards. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19566
|
|
Posted: Sun Nov 16, 2014 1:46 am |
|
|
First, it won't 'work perfectly with the 16F877'. There are major problems:
1) Ext_int_edge, does nothing. It is not for interrupt on change.
2) Your interrupt will on average not be called for nearly 1/4 second. This is caused by having a delay in the interrupt. A search will find why this shouldn't be done....
As written you might as well not use the interrupt at all. Just poll the input after each delay in the main. This is how the code will be functioning....
As for why it runs differently on the 887, this is a 'read the data sheet' one. What is on pin B4, on the 887, that isn't there on the 877?. Keyword analog.... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9255 Location: Greensville,Ontario
|
|
Posted: Sun Nov 16, 2014 6:19 am |
|
|
hmm...
first line..
#include <16F877.h>
Although you say you changed the device header, as posted your code will use the 877 header NOT the 887 header.
You must post the exact code you're using NOT the one that worked for another PIC..
As Mr T points out there are several things wrong with the 877 code however there may be more with your 887 code as we don't know what other changes you may have made.
jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 16, 2014 9:57 am |
|
|
To amplify previous posts,
Recent versions set ANSELH to 0, which makes pin B4 digital i/o. Which
would mean that's not the problem. He didn't give his compiler version
so we don't know if his version does this.
Quote: | .................... void main() {
005D: MOVF STATUS,W
005E: ANDLW 1F
005F: MOVWF STATUS
0060: CLRF blink
0061: BSF STATUS.RP0
0062: BSF STATUS.RP1
0063: MOVF ANSELH,W
0064: ANDLW C0
0065: MOVWF ANSELH
|
The real reason will be the delays. If he had warnings turned on, he
would see this:
Quote: |
>>> Warning 216 "PCM_Test.c" Line 31(1,2): Interrupts disabled during
call to prevent re-entrancy: (@delay_ms1) |
|
|
|
Perrinsky
Joined: 16 Nov 2014 Posts: 2
|
|
Posted: Tue Nov 18, 2014 1:22 am |
|
|
Hi again guys and thanks for your answers. Sorry I missed the version, it's the 4.104.
My code is almost the same:
Code: |
#include <16F887.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#byte STATUS=0x03
#byte ANSELH=0x189
BYTE blink = 0;
#int_rb
void button_isr() {
if( !input(PIN_B4) && !blink )
blink = 1;
else
if( !input(PIN_B4) && blink )
blink = 0;
}
void main() {
enable_interrupts(global);
enable_interrupts(int_rb);
STATUS=0b01100000; /* RP1 = RP0 = 1
ANSELH=0;
setup_adc_ports(no_analogs);
do {
if(blink){
output_high(PIN_D7);
delay_ms(500);
output_low(PIN_D7);
delay_ms(500);
}
} while (TRUE);
}
|
I made a few improvements after reading your answers (thanks a lot). I've tried also to set ANSELH to zero and STATUS byte with RP1 and RP0 to 1 but it's still doing nothing.
Sorry I'm new to interrupts and I haven't found any example that works with this PIC.
Thanks again to all. |
|
|
|