View previous topic :: View next topic |
Author |
Message |
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
interrupt problem |
Posted: Mon Oct 08, 2012 5:13 am |
|
|
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: 9244 Location: Greensville,Ontario
|
|
Posted: Mon Oct 08, 2012 5:23 am |
|
|
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
|
|
Posted: Mon Oct 08, 2012 5:35 am |
|
|
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: 19540
|
|
Posted: Mon Oct 08, 2012 6:58 am |
|
|
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
|
|
Posted: Mon Oct 08, 2012 8:05 am |
|
|
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: 19540
|
|
Posted: Mon Oct 08, 2012 8:31 am |
|
|
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
|
|
Posted: Mon Oct 08, 2012 10:05 am |
|
|
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
|
|
Posted: Mon Oct 08, 2012 11:27 am |
|
|
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: 19540
|
|
Posted: Mon Oct 08, 2012 1:04 pm |
|
|
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
|
|
Posted: Mon Oct 08, 2012 10:29 pm |
|
|
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
|
|
Posted: Tue Oct 09, 2012 1:34 am |
|
|
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: 19540
|
|
Posted: Tue Oct 09, 2012 1:45 am |
|
|
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
|
|
Posted: Tue Oct 09, 2012 2:15 am |
|
|
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: 19540
|
|
Posted: Tue Oct 09, 2012 2:31 am |
|
|
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
|
|
Posted: Tue Oct 09, 2012 4:47 am |
|
|
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 |
|
|
|