|
|
View previous topic :: View next topic |
Author |
Message |
larry936
Joined: 03 Jul 2015 Posts: 3 Location: mexico df
|
two interrupts RB4 and RB5 |
Posted: Fri Jul 03, 2015 12:36 pm |
|
|
Good morning friends, I count on your help. My problem is: I need a program with two interruptions RB4 and RB5. When tightening RB4 a green LED flashes 7 seconds, after which stops flashing and lights a red LED. When tightening RB5 off the red LED and a yellow LED blinks for 7 seconds, after which the program flags and clean ports waiting for a new cycle is reset. I am using a PIC16F887.
this the CODE:
Code: | #include <gemelos_1220.h>
#use delay(clock=4000000)
#fuses XT,WDT,NOPROTECT,PUT,NOLVP
#use standard_io(a)
/// FUNCION A EJECUTARSE SI OCURRE UNA INTERRUPCION /////////////////////
void botador (void)
{
int i=0;
while(i<7){
output_high(pin_a5);
delay_ms(500);
output_low(pin_a5);
delay_ms(500);
i++;
}
{
output_high(pin_a3);
}
}
void despachador (void)
{
{
output_low(pin_a3);
}
int j=0;
while(j<7){
output_high(pin_a4);
delay_ms(500);
output_low(pin_a4);
delay_ms(500);
j++;
}
}
int FLAG_INT_RB4=0;
int FLAG_INT_RB5=0;
///////////// subrutina de interrupcion //////////////
#int_RB
void RB_isr(void)
{
FLAG_INT_RB4=1;
FLAG_INT_RB5=1;
}
void main()
{
SET_TRIS_B(0X01);
SET_TRIS_A(0X00);
port_B_pullups(0xFF);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
ext_int_edge(H_to_L);
while(TRUE)
{
////////////////procesos que se hacen si ocurre una interrupcion ///////////
//TODO: User Code
if(FLAG_INT_RB4==1){
{
FLAG_INT_RB4=0; //actualizo el flag para una nueva interrupcion
botador();
}
if(FLAG_INT_RB5==1){
FLAG_INT_RB5=0; //actualizo el flag para una nueva interrupcion
despachador();
}
}
/////////////////subrutina de espera de la interrupcion /////////////
do{
///parpadeo de luces////
output_high(pin_e1);
delay_ms(500);
output_low(pin_e1);
delay_ms(500);
} while(FLAG_INT_RB4==0);
}
} |
_________________ Good morning friends, I count on your help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 03, 2015 2:48 pm |
|
|
Your program is using #int_rb. But your #int_rb routine does not clear
the "change" condition, so you will get continuous #int_rb interrupts.
Also, the 16F887 will interrupt on both a positive and a negative edge
for a change on PortB. This line of code does not affect #int_rb
interrupts. It only affects #int_ext interrupts:
Quote: | ext_int_edge(H_to_L); |
For help on these topics, read this thread and the links in it:
http://www.ccsinfo.com/forum/viewtopic.php?t=52922 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Fri Jul 03, 2015 3:07 pm |
|
|
INT_RB, is not affected by the int_edge command. INT_RB, is an interrupt on _change_. It happens whenever the value on any of the B4 to B7 pins changes, from when the port was last read.
Then because it is an interrupt on change, the port _must be read_ to clear the change. The INT_RB code must always read the port (or bits).
As a minimum 'example', but without any real function:
Code: |
#include <gemelos_1220.h>
#use delay(clock=4000000)
#fuses XT,WDT,NOPROTECT,PUT,NOLVP
#use fast_io(b)
//standard I/O is the default.
//It is easier to handle interrupt on change with the pins
//'fixed' regarding their I/O. Hence selecting fast_io.
int1 Flag_Int_RB4=FALSE;
int1 Flag_Int_RB5=FALSE;
//Flags to say these pins have _dropped_
//This sets each flag if the pin changes _low_, when it was high
#int_RB
void RB_isr(void)
{
static int1 old_RB4=1;
static int1 old_RB5=1;
//Handle RB4
if (input(PIN_A4)) //PIN is high
old_RB4=1; //record this
else
{
if (old_RB4==1) //Pin is now low, and [u]was[/u] high
{
//RB4 has changed to low
old_RB4=0;
Flag_Int_RB4=TRUE;
}
}
//Now RB5
if (input(PIN_A5)) //PIN is high
old_RB5=1; //record this
else
{
if (old_RB5==1) //Pin is now low, and was high
{
//RB5 has changed to low
old_RB5=0;
Flag_Int_RB5=TRUE;
}
}
}
void main()
{
int temp;
set_tris)b(0X31); //Since you want to interrupt on B4, and B7
//They _must_ be [u]inputs[/u]
port_B_pullups(0xFF);
setup_comparator(NC_NC_NC_NC);
temp=input_b(); //You must read the port to reset the change latch
clear_interrupts(INT_RB);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
while (TRUE)
{
if (Flag_Int_RB4)
{
FLAG_Int_RB4=FALSE;
//RB4 has now dropped - do what you want
}
if (Flag_Int_RB5)
{
Flag_Int_RB5=FALSE;
//RB5 has now dropped - do what you want
}
}
}
|
The input operations in the interrupt reset the change latch, and test which 'way' the pins have changed.
As a 'comment', things named in 'ALL_CAPITALS', are often only used for things that are #defines. It's useful to 'know' when this is the case, so it is a 'near standard' in C, to not use ALL_CAPITALS for variables or function names. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9249 Location: Greensville,Ontario
|
|
Posted: Fri Jul 03, 2015 4:34 pm |
|
|
I'm pretty sure CCS has a code example for reading PORTB interrupts. Might be in the FAQ section of the manual. I do recall using it some years ago...
probably still in the manual ??
Jay |
|
|
larry936
Joined: 03 Jul 2015 Posts: 3 Location: mexico df
|
it works now |
Posted: Mon Jul 06, 2015 8:46 pm |
|
|
Thanks everyone for your help
especially PCM programmer, with the example you gave me, and the program does what it wanted to do. Thanks and I will adapt to a larger one. _________________ Good morning friends, I count on your help. |
|
|
larry936
Joined: 03 Jul 2015 Posts: 3 Location: mexico df
|
RB4 pause interruption |
Posted: Thu Jul 09, 2015 3:23 pm |
|
|
How are friends?
My basic routine is:
When driving a PUSHBUTTON, interruption in RB4 is activated, flashes a green led 7 seconds, after which an infrared emitter lights and remains so until an event occurs that interrupts; action immediately and this infrared RB5 second interruption occurs and a blue flashing LED 8 seconds. After which flags are cleared and actuation of PUSHBUTTON again expected.
The problem occurs when during blinking green LED or enabling infrared or during blinking blue LED, a user operates the PUSHBUTTON, losing the order and program execution. How do I get over this run between the RB4 no interruption until the end of the entire program?
Code: |
#include <gemelos_1800.h>
#use delay(clock=4000000)
#fuses XT, WDT, NOPROTECT, PUT, NOLVP
#use fast_io(b)
/////// subrutina del motor botador e infrarrojos //////
void botador (void)
{
int i=0;
while(i<7){
output_high(pin_a5);
delay_ms(500);
output_low(pin_a5);
delay_ms(500);
i++;
}
{
output_high(pin_a3);
}
}
////////subrutina apaga infrarrojos; activa motor despachador M2 ////////
void despachador (void)
{
{
output_low(pin_a3);
}
int j=0;
while(j<7){
output_high(pin_a4);
delay_ms(500);
output_low(pin_a4);
delay_ms(500);
j++;
}
}
//standard i/o is the default
//it is easier to handle interrupt on change with the pins
//fixed regarding their i/o. hence selecting fast_io-
int1 flag_int_RB4=FALSE;
int1 flag_int_RB5=FALSE;
//flags to say these pin have_dropped_
//this sets each flag if the pin changes_low_, when it was high
#int_RB
void RB_isr(void)
{
static int1 old_RB4=1;
static int1 old_RB5=1;
//handle RB4
if(input(PIN_B4)) //PIN is high
old_RB4=1; //record this
else
{
if(old_RB4==1) //pin is now low, and was high
{
//RB4 has changed to low
old_RB4=0;
flag_int_RB4=TRUE;
}
}
//now RB5
if(input(PIN_B5)) //pin is high
old_RB5=1; //record this
else
{
if(old_RB5==1) //pin is now low, and was high
{
//RB5 has changed to low
old_RB5=0;
flag_int_RB5=TRUE;
}
}
}
void main()
{
int temp;
set_tris_b(0X31); //since you want to interrupt on B4, and B7; they_must_be (u) inputs (/u);
port_B_pullups(0xFF);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
temp=input_b(); //you must read the port to reset the change latch
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
while(TRUE)
{
//TODO: User Code
if(flag_int_RB4)
{
flag_int_RB4=FALSE;
//RB4 has now dropped - do what you want
//
botador();
//
}
if(flag_int_RB5)
{
flag_int_RB5=FALSE;
//RB5 has now dropped -do what you want
//
despachador();
//
}
} ///llave de cierre del while
} ////llave de cierre del main |
_________________ Good morning friends, I count on your help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jul 11, 2015 10:23 pm |
|
|
Quote: |
The problem occurs when during blinking green LED or enabling infrared
or during blinking blue LED, a user operates the PUSHBUTTON, losing the
order and program execution. How do I get over this run between the
RB4 no interruption until the end of the entire program? |
In other words, once the pushbutton is pressed you want to completely
execute the blinking led sequence, and ignore any button presses until
the sequence is done.
You could do it this way:
1. Disable int_rb interrupts at the end of the RB_isr() routine with this
line of code:
Code: | disable_interrupts(INT_RB); |
2. After your LED blinking routine has finished executing, re-enable int_rb
interrupts with this code:
Code: |
if(flag_int_RB4)
{
flag_int_RB4=FALSE;
//RB4 has now dropped - do what you want
//
botador();
// *** ADD THESE LINES BELOW ***
temp = input_b(); // Clear the change condition
clear_interrupt(INT_RB);
enable_interrupt(INT_RB); // Ready for a new button press
}
|
Also do this for the other if(flag_int_RB5) statement. |
|
|
|
|
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
|