Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 9th February 2009, 06:55 AM   #16
Default

The only reason I can think of for that strange behaviour is that a port B change is happening at the same time as the int0 interrupt and so the code gets executed twice and SWITCH gets set to something else. Note that a pin going from 0 to 1 will also produce a change interrupt.

What happens if you change it to,
Code:
  if(INTCON.INTF)
  {
       SWITCH = W ;
       PORTA.F1 = 1;
       INTCON.INTF = 0;
       INTCON.RBIE = 0;    //turn off port b interrupts
       INTCON.RBIF = 0;    //and clear it
  }
  else if(INTCON.RBIF)
  {
      if(PORTB.F5 == 0)
The interrupt will get turned back on when the switch W is executed and so the code should still work correctly.

Mike.
Pommie is offline  
Old 9th February 2009, 07:29 AM   #17
Default

INTCON.INTF now works!!

The problem is case W: never stops executing. It seems that INTCON.INTF never resets.
tattee is offline  
Old 9th February 2009, 07:39 AM   #18
Default

If the changes I suggested made it work then it is the RBIF that is causing the problem. I assume that you only want the relevant code to execute when the pin goes low. The way it is currently written you could (and did) get strange results. To make it edge triggered requires a little more code but may save you some future headaches. Let me know if you want me to post the code.

To stop case W from continually executing you need to set SWITCH to zero in the case W code.

Mike.
Pommie is offline  
Old 9th February 2009, 07:56 AM   #19
Default

Sure, I would want to know about edge triggering. Ive been seeing those terms in the datasheet but i never really had an idea what it meant. It would be really helpful if you could post the code on how to do it.

By the way, Im new to firmware programming and I've learned a lot from you! Than you very much!!
tattee is offline  
Old 9th February 2009, 09:00 AM   #20
Default

This is how I would make it edged triggered,
Code:
#define X      1
#define Y      2
#define Z      4	//now powers of 2
#define W      8	//I.E bit values

unsigned short SWITCH = 0;
unsigned char Previous;


void Interrupt()
unsigned char Edges,Pins;
{
  if(INTCON.INTF)
  {
       SWITCH |= W;
       PORTA.F1 = 1;
       INTCON.INTF = 0;
  }
  if(INTCON.RBIF)
  {
      Pins=PORTB;		//read the inputs
      Pins=~Pins;		//invert so active low		
      Edges=Pins^Previous;	//find bits that have changed
      Edges&=Pins;		//and are now high
      Previous=Pins;		//keep copy for next time
      INTCON.RBIF = 0;
      if(Edges.5 == 0)                 
      {
         SWITCH |= X;		//set X bit
      }
      if(Edges.6 == 0)             
      {
         SWITCH |= Y;
      }
      if(Edges.7 == 0)
      {
         SWITCH |= X;
      }
   }
}

void main()
{ 
   init_all();

   do {
	if(SWITCH & X){		//if X bit set then
	    //X code
            SWITCH&=255-X;	///reset X bit
        }
	if(SWITCH & Y){
	    //Y code
            SWITCH&=255-Y;
        }
	if(SWITCH & Z){
	    //Z code
            SWITCH&=255-Z;
        }
	if(SWITCH & W){
	    //W code
	    PORTA.F0 = 1;
            SWITCH&=255-W;
        }

     } while(1);
The way it works is by keeping a previous copy of the state of PORTB. By XORing the current and previous states we find any bits that have changed. To find any bits that were previously zero and are now one we AND the bits that have changed with the current state. This is of course the wrong way around as we want to detect bits that went from 1 to 0 and so we simply invert PORTB after we read it.

The other main change needed is because two events may happen at the same time. Because of this we need the ability to tell the main program that this happened and so we set bits in SWITCH instead of a value. These changes wouldn't be required if only 1 event could happen at once.

Mike.
Pommie is offline  
Old 9th February 2009, 09:48 AM   #21
Default

I have one question what is the value of Previous? is there something missing before this statement?

Code:
      #define X      1
#define Y      2
#define Z      4	//now powers of 2
#define W      8	//I.E bit values

unsigned short SWITCH = 0;
unsigned char Previous;


void Interrupt()
unsigned char Edges,Pins;
{
  if(INTCON.INTF)
  {
       SWITCH |= W;
       PORTA.F1 = 1;
       INTCON.INTF = 0;
  }
  if(INTCON.RBIF)
  {
      Pins=PORTB;		//read the inputs
      Pins=~Pins;		//invert so active low		
      Edges=Pins^Previous;	//find bits that have changed
      Edges&=Pins;		//and are now high
      Previous=Pins;		//keep copy for next time
      INTCON.RBIF = 0;
tattee is offline  
Old 9th February 2009, 10:00 AM   #22
Default

Previous is the value that the port was at the last interrupt. It should be initialized to zero at power up. I normally initialize variables in code rather than letting the compiler do it.

Mike.
Pommie is offline  
Old 10th February 2009, 02:15 AM   #23
Default

Hi Mike,

I've tried the code since yesterday. the code went crazy upon execution. everything just turned ON and I cant find a way to debug it.
tattee is offline  
Old 10th February 2009, 08:26 AM   #24
Default

By the way, how do you use SPI_READ? in mikroc this is the function declaration:
Code:
unsigned short Spi_Read(unsigned short buffer);
what do I equate the buffer with? is it PORTC.4 of the PIC? since it is the SDI? I tried but it can't read the data im suppose to have.
tattee is offline  
Old 11th February 2009, 02:14 AM   #25
Default

anyone?
tattee is offline  
Old 11th February 2009, 06:45 AM   #26
Default

I can't see anything wrong with that code (except the opening brace being in the wrong place in the interrupt code). If you post code that messes up I will have a look.

Afraid I can't help with MicroC as I don't have it.

Mike.
Pommie is offline  
Old 11th February 2009, 07:04 AM   #27
Default

Code:
#define X      1
#define Y      2
#define Z      4	//now powers of 2
#define W      8	//I.E bit values

unsigned short SWITCH = 0;
unsigned char Previous;


void Interrupt()
{
  unsigned char Edges,Pins;

  if(INTCON.INTF)
  {
       SWITCH |= W;
       PORTA.F1 = 1;
       INTCON.INTF = 0;
  }
  if(INTCON.RBIF)
  {
      Pins=PORTB;		//read the inputs
      Pins=~Pins;		//invert so active low		
      Edges=Pins^Previous;	//find bits that have changed
      Edges&=Pins;		//and are now high
      Previous=Pins;		//keep copy for next time
      INTCON.RBIF = 0;
      if(Edges.5 == 0)                 
      {
         SWITCH |= X;		//set X bit
      }
      if(Edges.6 == 0)             
      {
         SWITCH |= Y;
      }
      if(Edges.7 == 0)
      {
         SWITCH |= X;
      }
   }
}

void main()
{ 
   init_all();

   do {
	if(SWITCH & X){		//if X bit set then
            //call function here
            //do something here
            SWITCH&=255-X;	///reset X bit
        }
	if(SWITCH & Y){
            //call function here
            //do something here
            SWITCH&=255-Y;
        }
	if(SWITCH & Z){
            //do something here
            SWITCH&=255-Z;
        }
	if(SWITCH & W){
            //do something here
            SWITCH&=255-W;
        }

     } while(1);
this is the code. everytime i turn ON the circuit, everything labeled
Code:
//do something here
is executed.
tattee is offline  
Old 11th February 2009, 07:09 AM   #28
Default

regarding the SPI_READ.. Do you have any idea where the received data is stored in the PIC? so that when I call SPI_READ I will point it to that address to read the received data.
tattee is offline  
Old 11th February 2009, 07:37 AM   #29
Default

What happens if you change it to,
Code:
void main()
{ 
   init_all();
   INTCON.INTF = 0;
   INTCON.RBIF = 0;
   SWITCH=0;
   do {
	if(SWITCH & X){		//if X bit set then
            //call function here
            //do something here
            SWITCH&=255-X;	///reset X bit
        }
Mike.
Pommie is offline  
Old 11th February 2009, 07:46 AM   #30
Default

After starting up the circuit, nothing happens(which should be the case). But when I try to interrupt it everything is executed again, regardless of which port was interrupted.

Last edited by tattee; 11th February 2009 at 07:46 AM.
tattee is offline  
Reply

Tags
problem, reentrancy

Thread Tools
Display Modes


Similar
Title Starter Forum Replies Latest
Servo motor~~~~ problem~.....shaking problem!!!!! Gundam82 Robotics Chat 10 4th October 2004 08:12 PM



All times are GMT. The time now is 10:14 PM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker