Jump to content

Interrupt Just When 0 To 1 Happens


Recommended Posts

hi, i'm using the boostC compiler, and i'm wondering, is there a simple way to do an interrupt just when the input modify from 0 to 1??

 

actually, i never do any interrupt, so, if anyone has a simple code just to explain how interrupts goes it will be good enough

 

thanks!!!

 

 

Not sure that all Pic's have it but the ones I have used have RB0 as an interrupt input. It can be programed to trigger either for rising or falling edge (0 to 1 or 1 to 0).

 

The four top bits of PortB can also be used to generate an interrupt on any change on any of them. You cannot select the rising or falling edge on these and have to read them to find out which pin changed.

 

On a 16F84A you can set up the use of the RB0 interrupt by making RB0 an input and using the following lines in an init routine:

 

trisb.0 = 1; // make RB0 an input

clear_bit(intcon,INTF); // clear RB0 flag bit in case it was set

set_bit(intcon,GIE) ; // General interrupt enabe

set_bit(intcon,INTE) ; // enable RB0 interrupts

 

In the void interrupt( void ) function you should clear the RB0 interrupt flag with

 

clear_bit(intcon,INTF); // clear RB0 flag

 

Best thing is to check the datasheet for the Pic you are using but if you can use

RB0 what you want to do should be very easy.

 

Jim

Link to post
Share on other sites
thank's for your help, but if you can just write a real (functional) code i'll be aprecciate

 

thanks once again

Could you let me know what is the target PIC.

 

I assume that in the main function you start out with a call to a function that will do the basic start up setup of the Pic with things like assigning what pins are inputs and outputs. That is where the init lines have to go. If you do not use a function to set up the PIC then the lines should be towards the start of main() before you get into code that the program is doing. The only reason to use an interrupt is to make sure that whatever is happening gets stoped when an event happens (your transition from 0 to 1 on a pin)

 

You will have to write the code for the void interrrupt(void) function that makes the Pic do what you want when the event happens. The clear_bit(intcon,INTF); just resets the flag for the next time the interrupt happens and should be in the in the interrupt function.

 

One thing is to make sure you really need to use an interrrupt. One small drawback of using interrupts in BoostC is that they are not thread safe. If in the interrupt routine you use a function (like delay_s()) you cannot use the delay functions in main().

 

Let me know which Pic you plan to use and some idea of what the program

is supposed to do.

 

Jim

Link to post
Share on other sites

Ok.

 

i'm using the pic 16f84a. and i think that the interrupt is really necessary, but that kind of trouble (using the same function twice) i will not have.

 

i write this code:

 

#include <system.h>
#pragma CLOCK_FREQ 4000000
#ifdef _PIC16
#pragma DATA 0x2007, _XT_OSC & _WDT_OFF
#endif

int senha[4]; //stores one predetermined password
int temp[4]; //stores the password that is been digited
int k; //variable that counts how many digits is been typed
bool aux;

void interrupt( void ){
if( k<4 ){
temp[k] = (test_bit(portb,1) != 0) + (2 * (test_bit(portb,2) != 0)) + (4 * (test_bit(portb,3) != 0)) + (8 * (test_bit(portb,4) != 0));
k=k+1;
}


if( k == 4 ){
if( senha[0] == temp[0] & senha[1] == temp[1] & senha[2] == temp[2] & senha[3] == temp[3] ){ 
	set_bit(portb,6); 
	aux = false; 
}
k = 0;
}

clear_bit(intcon,INTF);
}

void main(){
senha[0] = 1; senha[1] = 2; senha[2] = 3; senha[3] = 4;

clear_bit(intcon,INTF); // clear RB0 flag bit in case it was set
set_bit(intcon,GIE); // General interrupt enabe
set_bit(intcon,INTE); // enable RB0 interrupts
set_bit(option_reg,6); // ativa na transição positiva
trisb = 31; //Pins 0 a 4 -> Input; Pin 5 a 7 -> Output.
portb = 0;  
aux = false;
k = 0;
while(true){ 
	if( test_bit(porta,1) ) { 
		aux = false; 
		clear_bit(portb,6); 
	}


	while( test_bit(porta,0) || aux){
		aux = true;		
                                               set_bit(portb,7); 
		delay_s(1);
		clear_bit(portb,7);		
		int i;

		for( i=0; i<20000; i=i+1 ){
			delay_ms(1);
			if( test_bit(porta,1) ) { 
				aux = false;
				clear_bit(portb,6); 
				break; 
			}
		}			
                               }
}

}

 

i think that should work nice, and in the simulation under the proteus it does. but (after having troubles to program this to the pic, troubles that i just can't explain) in the pic it doesn't.

 

when i active the interrupt when the test_bit(porta,0) is false (the program isn't in the while( test_bit(porta,0 || aux ) ), works fine. but when is true just don't work :/

 

well, hope that now i have explained my doubts better.

 

thanks to everyone!!

Link to post
Share on other sites
Ok.

 

i'm using the pic 16f84a. and i think that the interrupt is really necessary, but that kind of trouble (using the same function twice) i will not have.

 

i write this code:

 

#include <system.h>
#pragma CLOCK_FREQ 4000000
#ifdef _PIC16
   #pragma DATA 0x2007, _XT_OSC & _WDT_OFF
#endif

int senha[4]; //stores one predetermined password
int temp[4]; //stores the password that is been digited
int k; //variable that counts how many digits is been typed
bool aux;

void interrupt( void ){
if( k<4 ){

   temp[k] = (test_bit(portb,1) != 0) + (2 * (test_bit(portb,2) != 0)) + (4 * (test_bit(portb,3) != 0)) + (8 * (test_bit(portb,4) != 0));
   k=k+1;
}


if( k == 4 ){
   if( senha[0] == temp[0] & senha[1] == temp[1] & senha[2] == temp[2] & senha[3] == temp[3] ){ 
       set_bit(portb,6); 
       aux = false; 
   }
   k = 0;
}

   clear_bit(intcon,INTF);
}

void main(){
   senha[0] = 1; senha[1] = 2; senha[2] = 3; senha[3] = 4;
   
   clear_bit(intcon,INTF); // clear RB0 flag bit in case it was set
   set_bit(intcon,GIE); // General interrupt enabe
   set_bit(intcon,INTE); // enable RB0 interrupts
   set_bit(option_reg,6); // ativa na transição positiva
   trisb = 31; //Pins 0 a 4 -> Input; Pin 5 a 7 -> Output.
   portb = 0;  
   aux = false;
   k = 0;
   while(true){ 
       if( test_bit(porta,1) ) { 
           aux = false; 
           clear_bit(portb,6); 
       }

       
       while( test_bit(porta,0) || aux){
           aux = true;        
                                               set_bit(portb,7); 
           delay_s(1);
           clear_bit(portb,7);        
           int i;

           for( i=0; i<20000; i=i+1 ){
               delay_ms(1);
               if( test_bit(porta,1) ) { 
                   aux = false;
                   clear_bit(portb,6); 
                   break; 
               }
           }            
                               }
   }
       
}

 

i think that should work nice, and in the simulation under the proteus it does. but (after having troubles to program this to the pic, troubles that i just can't explain) in the pic it doesn't.

 

when i active the interrupt when the test_bit(porta,0) is false (the program isn't in the while( test_bit(porta,0 || aux ) ), works fine. but when is true just don't work :/

 

well, hope that now i have explained my doubts better.

 

thanks to everyone!!

 

I tried the code with the IDE debugger and the interrupt always works as planned.

I understand that the program is to preform an action if a correct code is entered on a matrix keyboard but have some problems understanding what porta.0 and porta.1 are for. The program could be a lot easier to understand and debug if the variables have more explict names like key_count instead of just k. Same goes for things like clear_bit(portb.6);. You can use a # define statement to make the code a lot more readable for anyone. Something like #define open_door clear_bit(portb.6);.

A line like open_door; makes the code a lot more readable.

 

It also has the advantage that if you decied to change a port number or port that you only have to change it in one place in the #define.

 

You can also define things used in tests so that test_bit(porta.0) becomes manuel_reset "#define manuel reset test_bit(porta.0)" (without the semicolon)

 

I learned this a while ago after going back to modify programs I wrote after a few months (maybe even days!) and not remembering what a one letter variable is actually doing. Being very explicit in the C program has no effect on the size the program will in the PIC.

 

One problem in the IDE debugger is that the plugins like Button or Led Block do not really correspond to what happens most of the time in the real world. The output on ports is usually pulled to high(1) with pull up resistors and to turn on a led you send 0 to turn on the led. Switch closures are the same. Most keypads short the output to ground and produce 0 when a key is pushed. There were messages a while ago asking the possibility to chose how the plugins operate but no word as to when it will happen. Does the proteus let you chose ?

 

It would be helpfull if you could make the code a bit clearer.

 

Jim

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...