View previous topic :: View next topic |
Author |
Message |
dubinc
Joined: 04 Feb 2011 Posts: 9
|
#int_ext and #int_rb problem |
Posted: Mon Feb 20, 2012 11:46 am |
|
|
Hi,
I have a big problem with these two interrupts, nothing works !! I connected a led on A5 and a button with a pull up and if I connect and push this button on RB0 (ext) or on RB4 (rb) nothing works!
I read all the post on the forum but I didn't found any solutions.
I work on a 16f877a and I need help.
Thanks
Code: |
#include <16F877A.h>
#device ICD=TRUE
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=12000000)
#byte PORTA=5
#byte TRISA=0x85
#bit led=PORTA.5
#byte PORTB=6
#byte TRISB=0x86
#bit BP=PORTB.4
#int_RB
void RB_isr(void)
{
if(BP==0)
led=!led;
}
#int_EXT
void EXT_isr(void)
{
led=!led;
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
ext_int_edge( H_TO_L );
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
enable_interrupts(global);
TRISA=0b11011111;
TRISB=0b11111111;
led=1;
while(1)
{
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Mon Feb 20, 2012 11:58 am |
|
|
I suggest you re-read the posts as well as look over the PORTB information in the 877 datasheet.
Sooner or later you'll read about having to read the port to properly access the interrupt logic.Also readup about the correct use/control of teh TRIS registers(Again in the datasheet,PORT descrition section).
Providing you have the correct current limiting resistor,proper debounce on the switch and correctly configure the I/O ports, the 877 will turn an LED on or off. Been doing that for almost 20 years.
If you still can't figure it out, just try a normel 'LED blink ' program and build from there.You could have a hardware fault(bad LED, misconnected wire, blown PIC). |
|
|
dubinc
Joined: 04 Feb 2011 Posts: 9
|
|
Posted: Mon Feb 20, 2012 12:34 pm |
|
|
Thanks for your answer.
I don't understand a thing: there is 3 years I used 16F877A dev board and I wrote exactly this code and it worked ! So why now it doesn't work !?
I read the datasheet but what is the problem with TRIS ? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Feb 20, 2012 5:02 pm |
|
|
I don't know about the TRIS problem Temtronic refers to, unless he means that setting the TRIS registers in your program conflicts with the default compiler handling of the TRIS registers. Setting them manually as you do might cause conflicts with the compiler overruling your settings. Read the CCS manual on #use standard_io.
One other problem in the PIC16 processors (and your code) is known as the Read-Modify-Write (RMW) problem. A lot has been written on this, for example http://www.piclist.com/techref/readmodwrite.htm
Code: | setup_spi(SPI_SS_DISABLED); | This is a bug in the CCS Code Wizard and specifies an invalid configuration with unpredictable results. Correct code should be:
Code: | #bit led=PORTA.5
...
#bit BP=PORTB.4 | Good coding practice is to use capital words for constants. You do this for the BP pin, but not for led. Being consistent helps to make your code easier to read.
This code is correct, but are you aware of the output_toggle() function? That is the CCS-way of toggling an output where the compiler sets the TRIS register, and in my opinion is better self explaining code. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Mon Feb 20, 2012 7:31 pm |
|
|
ah..don't you always have to read portB to clear the PortB interrupt? Or have I carried forward that requirement from the 16C84 dayze? |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
Re: #int_ext and #int_rb problem |
Posted: Mon Feb 20, 2012 8:23 pm |
|
|
Although you have set the desired TRIS (good programming practice) the compiler, by default, will, as it sees fit, set TRIS values itself. If your application wants to control TRIS you need to instruct the compiler to use FAST_IO
Code: |
#int_RB
void RB_isr(void)
{
if(BP==0)
led=~led; // <------- this is the complement operator you needed
}
#int_EXT
void EXT_isr(void)
{
led=~led; // <-------- this is the complement operator you needed
}
|
_________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
dubinc
Joined: 04 Feb 2011 Posts: 9
|
|
Posted: Tue Feb 21, 2012 5:16 am |
|
|
I modified my code following your instructions but one more time it doesn't works !
I tried to use standard_io() function but when I wanted to use it, my led was OFF at the begining of the program (normally the led is ON).
Secondly, I tried to read the port B but I don't know where I read this port. I read the port in my two interrupt sub program, is it correct ?
Code: |
#include <16F877A.h>
#device ICD=TRUE
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=12000000)
//#use standard_io(B)
#byte PORTA=5
#byte TRISA=0x85
#bit led=PORTA.5
#byte PORTB=6
#byte TRISB=0x86
#bit BP=PORTB.4
byte test;
#int_RB
void RB_isr(void)
{
if(BP==0)
led=~led;
test=input_b();
}
#int_EXT
void EXT_isr(void)
{
led=~led;
test=input_b();
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
ext_int_edge( H_TO_L );
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
enable_interrupts(global);
test=input_b();
TRISA=0b11011111;
TRISB=0b11111111;
led=1;
while(1)
{
}
}
|
|
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Tue Feb 21, 2012 5:52 am |
|
|
Although the compiler is using standard_io, you have set tris values. This is meaningless because the compiler will override these settings.
The method you have used for reading port B in the interrupt handler is fine.
The is no need to actually use interrupts because your main exec loop is empty. Instead, without enabling interrupts, and without interrupt handlers, check the interrupt flags in the mainline and process it then accordingly. The advantage with doing it this way is that once a change event occurs, you can toggle the LED and then deliberately delay for say, 50milliseconds, before repeating the cycle. This will address the very real debounce problem not handled with you current implementation. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
dubinc
Joined: 04 Feb 2011 Posts: 9
|
|
Posted: Tue Feb 21, 2012 9:29 am |
|
|
Your solution isn't bad but I want to try to find why my interrupts don't works, and I have absolutly no ideas ! I tested many code on different PIC and the result is the same. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Tue Feb 21, 2012 9:34 am |
|
|
dubinc wrote: | Your solution isn't bad but I want to try to find why my interrupts don't works, and I have absolutly no ideas ! I tested many code on different PIC and the result is the same. |
You are setting TRIS statements. Say to yourself, in standard mode this does not do what I think. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
dubinc
Joined: 04 Feb 2011 Posts: 9
|
|
Posted: Tue Feb 21, 2012 10:21 am |
|
|
I tried to delete the TRIS statements but in this way nothing works ! My led is always OFF (with #use standard_io) |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Tue Feb 21, 2012 10:30 am |
|
|
dubinc wrote: | I tried to delete the TRIS statements but in this way nothing works ! My led is always OFF (with #use standard_io) |
You cannot use the led = ~led;
This is not compatible with standard_io _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
|