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 support@ccsinfo.com

interrupt problem
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
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

interrupt problem
PostPosted: Mon Oct 08, 2012 5:13 am     Reply with quote

i am using pic 18F2520. I have connected a LED1 to RA0, a button to RB0 and RC0 to LED2. normally LED1 will be glowing. when Button is pressed, led2 must glow. but i ve got error "Undefined identifier INT_RB4" .wats wrong with my code? please help . thanks in advance.

Code:
#include "18F2520.h"
#fuses HS, NOPROTECT, INTRC_IO
#use delay(clock=4000000)

#int_rb
void interrupt()
{
int x;
x=input_b();
output_high(PIN_C0);
x=input_b();
}

void main()
{
int16 i;
setup_oscillator(OSC_4MHZ);
enable_interrupts(INT_RB);
enable_interrupts(INT_RB4);
enable_interrupts(GLOBAL);
while(1)
{
for(i=0;i>=0;i++)
output_high(PIN_A0);
}
}
temtronic



Joined: 01 Jul 2010
Posts: 9196
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 5:23 am     Reply with quote

The compiler is telling you it doesn't understand 'INT_RB4'.

Everything is fine until this line...

enable_interrupts(INT_RB4);

... so open up the 'PIC processor header' file ..'18F2520.h' and read what are the allowable choices for interrupts.The datasheet will also discuss in great detail interrupts.

each PIC type is different,some have 'these' features, some have 'those'...
it's up to you to decide what's available and how to you it.

early PICs did not have individual interrupts for PORT B pins,some newer ones do.

hth
jay
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 5:35 am     Reply with quote

Thanks for the reply. I've looked into 18F2520.h file. There is no INT_RB4 in the interrupt section. Is my controller doesn't support to handle individual interrupt?? But i looked in to datasheet. I have connected button to pin 21 which is INT0 register (EXTERNAL INTERRUPT 0).
Ttelmah



Joined: 11 Mar 2010
Posts: 19431

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 6:58 am     Reply with quote

INT0, is INT_EXT.

Different from the RB interrupts. The latter interrupt on a 'change' on a number of pins. The former interrupts only on one edge (high to low, or low to high) on one pin. The edge can be selected with the ext_int_edge function.

Best Wishes
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 8:05 am     Reply with quote

Thanks for the information. i have changed the interrupt to INT_EXT.
Normally LED1 glows and when button is pressed, LED2 glows even when i release the button. but i want the led to glow while i press the button. and stop the LED1 glowing. wats wrong with the code now?

Code:
#include "18F2520.h"
#fuses HS, NOPROTECT, INTRC_IO
#use delay(clock=4000000)

#INT_EXT
void interrupt()
{
do
{
if(input_state(PIN_B0))
output_high(PIN_C0);
else if (!input_state(PIN_B0))
output_low(PIN_C0);
}while(!input_state(PIN_B0));
}

/*#int_rb
void interrupt()
{
int x;
x=input_b();
output_high(PIN_C0);
x=input_b();
} */

void main()
{
int16 i;
setup_oscillator(OSC_4MHZ);
enable_interrupts(INT_EXT);
ext_int_edge(INT_EXT_H2L);
enable_interrupts(GLOBAL);
while(1)
{
for(i=0;i>=0;i++)
output_high(PIN_A0);
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19431

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 8:31 am     Reply with quote

You are using the wrong define in ext_int_edge.
You also should avoid waiting in interrupts - destroys the whole point of them.
You need something like:
Code:

#INT_EXT
void interrupt(void) {
   static int1 toggle=0; //Starting state
   if (toggle==0) {
      //here interrupt was on falling edge
      output_high(PIN_C0); //turn on LED
      ext_int_edge(L_TO_H); //now look for the rising edge
      toggle=1;
   }
   else {
      //Switch back to looking for the falling edge
      output_low(PIN_C0); //turn off LED
      ext_int_edge(H_TO_L); //now look for the falling edge
      toggle=0;
   }
}

//And in main

enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);


This will interrupt on the falling edge (assume this is button pressed?), and turn on pin C0 (LED ON?). Then reprogram the interrupt to start looking for the rising edge, and exit immediately.
When the rising edge is seen, it turns off the LED, and reprograms to start looking for the falling edge again.

Best Wishes
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 10:05 am     Reply with quote

It works perfectly... thank you very much.

To my knowledge interrupts means while the main function is executing, if any interrupt is enabled, it will finish that operation and will return back to the main where it left??? Is it correct ? If I am wrong, please correct me.

To my program, when button is pressed, led2 must glow. It works perfectly with your information, but led1 keeps on glowing even when the interrupt is enabled (when button is pressed).
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 11:27 am     Reply with quote

Quote:
To my program, when button is pressed, led2 must glow. It works perfectly with your information, but led1 keeps on glowing even when the interrupt is enabled (when button is pressed).

Are you expecting LED1 to turn off?

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19431

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 1:04 pm     Reply with quote

Hardware outputs are _latched_ they stay outputting what you sent them, till you send something else. Your loop in the main effectively does nothing, just keeping turning the output on, that is already on....

Best Wishes
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Mon Oct 08, 2012 10:29 pm     Reply with quote

Yes, led1 must go off when I press the button and led2 must glow. Have I to change anything in program ?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Oct 09, 2012 1:34 am     Reply with quote

Quote:
Have I to change anything in program ?
Yes.

As Ttelmah has expilicitly stated (and I've hinted) you don't have any code to turn LED1 off. It needs to be included.

Mike

EDIT. I'm not entirely clear as to what you want your code to do.

What you are saying is not totally consistent.

What do you want to happen when:-

1) Button is released?
2) Button is pressed a second time?
Ttelmah



Joined: 11 Mar 2010
Posts: 19431

View user's profile Send private message

PostPosted: Tue Oct 09, 2012 1:45 am     Reply with quote

So:
Code:

#include "18F2520.h"
#fuses HS, NOPROTECT, INTRC_IO
#use delay(clock=4000000)

int1 button_on=FALSE;

#INT_EXT
void interrupt(void) { //detect button press
   if (toggle==FALSE) {
      //here interrupt was on falling edge
      ext_int_edge(L_TO_H); //now look for the rising edge
      button_on=TRUE; //signal that key is pressed
   }
   else {
      //Switch back to looking for the falling edge
      output_low(PIN_C0); //turn off LED
      ext_int_edge(H_TO_L); //now look for the falling edge
      button_on=FALSE; //and signal that key is released
   }
}

void main(void) {
   int1 last_button;
   setup_oscillator(OSC_4MHZ);
   last_button=button_on;
   enable_interrupts(INT_EXT);
   ext_int_edge(H_TO_L);
   enable_interrupts(GLOBAL);
   output_high(PIN_A0); //Turn one LED on
   while(1)  {
      if (last_button!=button_on) {
         //Here button has changed
         last_button=button_on;
         if (button_on) {
            output_low(PIN_A0);
            output_high(PIN_C0);
         }
         else {
            output_high(PIN_A0);
            output_low(PIN_C0);
         }
      }
   } 
}   


Now seriously, you really need to get a primer, and start working through some basic exercises yourself. The CPU does nothing without you telling it, so here, to turn off the second LED, _you_ need to have code to turn it off. The LED's stay on/off once set, till you tell them to do something else.

What you want here, could be done totally without using an interrupt at all. With:
Code:

#include "18F2520.h"
#fuses HS, NOPROTECT, INTRC_IO
#use delay(clock=4000000)

void main(void) {
   int1 last_button;
   int1 button;
   setup_oscillator(OSC_4MHZ);
   button=last_button=input(PIN_B0); //read the button
   output_high(PIN_A0); //Turn one LED on
   while(1)  {
      button=input(PIN_B0); //read button
      if (last_button!=button) {
         //Here button has changed
         last_button=button;
         if (!button) {
            output_low(PIN_A0);
            output_high(PIN_C0);
         }
         else {
            output_high(PIN_A0);
            output_low(PIN_C0);
         }
      }
   } 
}   


The interrupt gains you nothing. All you need do is read the input, and change the LED's if it has changed.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Tue Oct 09, 2012 2:15 am     Reply with quote

I'm trying to use interrupt in LED. But my final solution in the program is about,
I'm designing a pressure indicator and interfacing LCD with controller to display some sequence of functions. Normally it reads the pressure value. When the button is pressed, it displays the sequence of functions (i.e what are the functions it has already loaded, eg. INFORMATION). While the sequence was running, and if I need to stop that sequence suddenly, I to want to press the button again to stop the sequence and must read the normal pressure value (i.e., stops the sequence whenever the button is pressed again). To stop the sequence, it can be attained using interrupts. Can it be done? Please do help... thanks in advance.
Ttelmah



Joined: 11 Mar 2010
Posts: 19431

View user's profile Send private message

PostPosted: Tue Oct 09, 2012 2:31 am     Reply with quote

Not really.....

Using change/edge interrupts to read buttons is a 'bad idea'. Problem is that buttons don't just go on/off. Most exhibit 'bounce', which _will_ change as they age. With this when you push a button you see a rapid sequence of make/break's occurring over a small fraction of a second. If you try to handle this with interrupt's, they will be triggering multiple times, and it is very difficult to know when the button has finally made or released.

The best way is to implement a _timer_ in your code ticking at perhaps 50Hz, using an interrupt. Each time this is called, read the state of the keys, and require the key to _remain_ made, for perhaps three or four interrupts _before_ accepting it. This is keyboard debounce, and there are examples here of how to do this (and in every keyboard handler in the world....).

Implement a keyboard(button) driver with debounce, and then just set a flag to tell the code to change state.

Best Wishes
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Oct 09, 2012 4:47 am     Reply with quote

Quote:
but my final solution in the program is about,
im designing a pressure indicator and interfacing LCD with controller to display some sequence of functions. normally it reads the pressure value. when button is pressed, displays shows the sequence of functions(i.e what are the functions it has already loaded, eg. INFORMATION). while the sequence was running, and if i need to stop that sequence in sudden, i want to press the button again to stop the sequence and must reads the normal pressure value(i.e., stops the sequence whenever the button is pressed again). To stop the sequence, it can be attained using interrupts. can it be done? please do help... thanks in advance


It's still not clear to me what you are trying to do.

You seem to be wanting several different things to happen as you press the button.

Like Ttelmah says do a keyboard debounce. Depending on how clean your switch is, you may need to debounce both make and break.

Mike
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