CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

INT_EXT
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Vamsi
Guest







INT_EXT
PostPosted: Thu Oct 11, 2007 9:42 am     Reply with quote

Hi.. I am trying to use external interrupts on PIC18F4520..
RB0/INT0 is pulled high. when i press a switch it will be pulled down and an interrupt should be generated.

FOllowing is my code
Code:
#include<18F4520.h>
#device ICD=TRUE
#use delay(clock=4000000)

int value=0;
void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
SET_TRIS_B(0xFF);
SET_TRIS_D(0x00);

while(1);
}

#INT_EXT
 PORTB_INTERRUPT()
{
delay_ms(100);
OUTPUT_TOGGLE(PIN_D2);

}


I should be able to toggle PIN D2 when i press the swtich.. but i am not able to do so.. i.e. an interrupt is not generated....

Please help me
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 10:51 am     Reply with quote

You need to set the edge that is going to trigger the external interrupt.

Only use your ISR to set a flag that will be referenced in your mainline code.

Look at the 18F4520.h file to see the correct 'terminology' for setting the edge trigger.

Don't use delays in an ISR.

Try these suggestions and return with your results and somebody will help with the next set of questions.

John
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 11:02 am     Reply with quote

You didn't post your #FUSE statements so I'll post a suggestion for them here.

#FUSES XT // osc <= 4MHZ
#FUSES NOWDT // no watchdog
#FUSES PUT // power up timer
#FUSES NOLVP // no Low Voltage Programming (almost standard fuse)
#FUSES NOPBADEN // make portb pins to be digital inputs and not analog

You don't need to set the tris unless you're using fast_io

When enabling interrupts, enable each individual interrupt and THEN enable the global interrupt

In normal practice, make your ISR as short as possible. NEVER put a delay inside. Something like this would have a flag set, inside the ISR, and then evaluate that flag somewhere else (most likely in main() ).

You might want to look at ext_int_edge() to determine which edge you want the interrupt to trigger on.

Hope this helps.

Ronald
Vamsi
Guest







INT_EXT
PostPosted: Thu Oct 11, 2007 12:24 pm     Reply with quote

I have tried as suggested.. but still i am not able to toggle PIN_D2.... please suggest me something so that it works

the new code is
Code:

#include<18F4520.h>
#device ICD=TRUE
#use delay(clock=4000000)

#FUSES XT // osc <= 4MHZ
#FUSES NOWDT // no watchdog
#FUSES PUT // power up timer
#FUSES NOLVP // no Low Voltage Programming (almost standard fuse)
#FUSES NOPBADEN // make portb pins to be digital inputs and not analog

int value=0;
void main()
{
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
EXT_INT_EDGE(L_TO_H);




while(1);
}

#INT_EXT
 PORTB_INTERRUPT()
{

OUTPUT_TOGGLE(PIN_D2);

}


thank you
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 12:55 pm     Reply with quote

I think this should work:


Code:
#include<18F4520.h>
#device ICD=TRUE
#use delay(clock=4000000)

#FUSES XT // osc <= 4MHZ
#FUSES NOWDT // no watchdog
#FUSES PUT // power up timer
#FUSES NOLVP // no Low Voltage Programming (almost standard fuse)
#FUSES NOPBADEN // make portb pins to be digital inputs and not analog

int1 ext_int_flag = false;

#INT_EXT
 PORTB_INTERRUPT()
{
   ext_int_flag = true;
}

void main()
{
   EXT_INT_EDGE(L_TO_H);
   clear_interrupt(INT_EXT);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   while(1);
   {
      if(ext_int_flag)
      {
         ext_int_flag = false;
         OUTPUT_TOGGLE(PIN_D2);
      }

   }
}
Vamsi
Guest







INT_EXT
PostPosted: Thu Oct 11, 2007 1:08 pm     Reply with quote

I am sorry it doesnt work...

any other suggestions ??
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 1:23 pm     Reply with quote

Code:

void main()
{
   EXT_INT_EDGE(L_TO_H);
   clear_interrupt(INT_EXT);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   while(1);             //  !!!! DELETE THE SEMICOLON
   {
      if(ext_int_flag)
      {
         ext_int_flag = false;
         OUTPUT_TOGGLE(PIN_D2);
         delay_ms(200);         //  I would add this delay   
      }

   }
}



Hope it should work.

Humberto


Last edited by Humberto on Thu Oct 11, 2007 1:26 pm; edited 1 time in total
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 1:26 pm     Reply with quote

Change:

Code:
EXT_INT_EDGE(L_TO_H);


to

Code:
EXT_INT_EDGE(H_TO_L);


Quote:
RB0/INT0 is pulled high. when i press a switch it will be pulled down and an interrupt should be generated.


Either should work, but the second is more correct for what you intend to do.

General approach for debugging should be:

Get a basic program written and loaded to confirm hardware. Can you toggle an LED successfully with the hardware?

Check each pin for your functionality one at a time (if you're working on a board you've assembled.)

Sequentially add features/parts.
Vamsi
Guest







INT_EXT
PostPosted: Thu Oct 11, 2007 1:59 pm     Reply with quote

I tried all this but still it doesnt work.... yes i also tried toggling LED at PIN_D2 it works otherwise...

again the code is

Code:

#include<18F4520.h>
#device ICD=TRUE
#use delay(clock=4000000)

#FUSES XT // osc <= 4MHZ
#FUSES NOWDT // no watchdog
#FUSES PUT // power up timer
#FUSES NOLVP // no Low Voltage Programming (almost standard fuse)
#FUSES NOPBADEN // make portb pins to be digital inputs and not analog

int1 ext_int_flag = false;

#INT_EXT
 PORTB_INTERRUPT()
{
   ext_int_flag = true;
}

void main()
{
   EXT_INT_EDGE(L_TO_H); //also tried H_TO_L
   clear_interrupt(INT_EXT);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   while(1)
   {
      if(ext_int_flag)
      {
         ext_int_flag = false;
         delay_ms(100);
         OUTPUT_TOGGLE(PIN_D2);
      }

   }
}


Any suggestions??
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 2:07 pm     Reply with quote

I would add a 'heart beat' LED flash to the program to ensure that it's not hanging somewhere.

What board are you using?

Do you have a scope available?
vamsi
Guest







INT_EXT
PostPosted: Thu Oct 11, 2007 2:33 pm     Reply with quote

yes i do have a scope and i am using PICDEM2 PLUS with PIC18F4520
w2drz



Joined: 27 Dec 2006
Posts: 55
Location: Western New York - USA

View user's profile Send private message Visit poster's website

INT_EXT
PostPosted: Thu Oct 11, 2007 2:39 pm     Reply with quote

This code should do the test,
I still do not know how to post code correct but here is what I have.
Also do NOT do several other things while doing a post .
tom


#include<18F4520.h>
#device ICD=TRUE
#use delay(clock=4000000)

#FUSES XT // osc <= 4MHZ
#FUSES NOWDT // no watchdog
#FUSES PUT // power up timer
#FUSES NOLVP // no Low Voltage Programming (almost standard fuse)
#FUSES NOPBADEN // make portb pins to be digital inputs and not analog

int1 ext_int_flag = false;

#int_ext
void PB0_isr (void) ()
{
ext_int_flag = true;
}

void main(void) ()
{
output_low (PIN_D2);
clear_interrupt(INT_EXT);
EXT_INT_EDGE (H_TO_L);
enable_interrupts (INT_EXT);
enable_interrupts(GLOBAL);

do {
if(ext_int_flag)
{
ext_int_flag = false;
output_toggle (PIN_D2);
}

}
while(1);
}


Last edited by w2drz on Fri Oct 12, 2007 2:18 pm; edited 4 times in total
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 4:09 pm     Reply with quote

Well.....

I pulled out my PICDem2+ and dusted off.

This is what I've learned. It doesn't look as though you can use the LEDs at the same time as the pushbutton. Look at the signal on B0 with the button pushed and not. I then pulled one lead of the RB0 LED and got the interrupt signal to look good.

From there I've got no idea why the INT_EXT won't fire.


PCM_Programmer to the white courtesy phone.

BTW - I tried disabling the portb pullups and reading pin_b0 to ensure that it was configured as an input.




UPDATE: The INT_EXT bit is getting set but the ISR isn't happening.



It looks as though it can never get to the point where it checks the EXT0IF bit in line 0054. There is never a GOTO 0054 called in the rest of the program.


Code:
004A:  MOVFF  04,13
004E:  BTFSS  FF2.4
0050:  GOTO   005A
0054:  BTFSC  FF2.1
0056:  GOTO   00A0
005A:  MOVFF  0F,00


And I can confirm the EXT0IF never gets cleared, so the ISR must not get called.


************************
Take out the ICD declaration.
Ttelmah
Guest







PostPosted: Fri Oct 12, 2007 2:38 am     Reply with quote

There would not be a goto anywhere in the program. The lines above, drop through to this, if FF2.4 is set. This is the intrrupt _enable_ bit. The sequence is:
Interrupt triggers.
If GIE is set, the chip performs an automatic 'call' to address 8 (or 18, fo a low priority interrupt if interrupt priorities are enabled). At this point, all the registers are saved.
Then, working in the order that the interrupt handlers are defined (or in the order set in a #priority statement if present), the code tests each interrupt enable bit in turn, and then the corresponding interrupt flag bit. Only if _both_ are set for a particular interrupt, is the handler called.
The code you show, is the correct handler for this interrupt, and will work.
As posted, your code is either massively faulty, or just the posting screws it up. You have several lines :
Code:

output_low (PIN_D2);

clear_interrupt(INT_EXT);
EXT_INT_EDGE (H_TO_L);
enable_interrupts (INT_EXT);
enable_interrupts(GLOBAL);

Which as shown, are never executed...
Try:
Code:

#include<18F4520.h>
#device ICD=TRUE
#use delay(clock=4000000)

#FUSES XT // osc <= 4MHZ
#FUSES NOWDT // no watchdog
#FUSES PUT // power up timer
#FUSES NOLVP // no Low Voltage Programming (almost standard fuse)
#FUSES NOPBADEN // make portb pins to be digital inputs and not analog

int1 ext_int_flag = false;

#int_ext
void PB0_isr (void)  {
   ext_int_flag = true;
}

void main(void) {
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   do {
      if(ext_int_flag)  {
          ext_int_flag = false;
          output_toggle (PIN_D2);
      }
   } while(TRUE);
}

This exceutes correctly as posted, and toggles pin D2, whenever an interrupt is received.

Best Wishes
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Fri Oct 12, 2007 2:59 am     Reply with quote

I could only get it to work after pulling the lead on R21 on the PICDem 2+ board (That's the RB0 LED current limit resistor) and removing the ICD=TRUE.

Ttelmah, will your code work without enabling the interrupts? (I'm not where I can test it, otherwise I would.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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