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

two interrupts RB4 and RB5

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
larry936



Joined: 03 Jul 2015
Posts: 3
Location: mexico df

View user's profile Send private message

two interrupts RB4 and RB5
PostPosted: Fri Jul 03, 2015 12:36 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jul 03, 2015 2:48 pm     Reply with quote

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: 19498

View user's profile Send private message

PostPosted: Fri Jul 03, 2015 3:07 pm     Reply with quote

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: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 03, 2015 4:34 pm     Reply with quote

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

View user's profile Send private message

it works now
PostPosted: Mon Jul 06, 2015 8:46 pm     Reply with quote

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

View user's profile Send private message

RB4 pause interruption
PostPosted: Thu Jul 09, 2015 3:23 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 11, 2015 10:23 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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