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 29th January 2009, 09:46 AM   #1
Default Reentrancy problem

I got this error using MikroC "Reentrancy not allowed function[Spi_Write] called in both main and interrupt threads". I used PIC16F873 and having the SPI communication at the moment.

Why do I get this problem? How will I solve this? I really have to call some functions inside the interrupt to perform some task.
tattee is offline  
Old 29th January 2009, 10:00 AM   #2
Default

Quote:
Originally Posted by tattee View Post
I got this error using MikroC "Reentrancy not allowed function[Spi_Write] called in both main and interrupt threads". I used PIC16F873 and having the SPI communication at the moment.

Why do I get this problem? How will I solve this? I really have to call some functions inside the interrupt to perform some task.
A Reenterant function is one that can be called when it is already active. In the case of your interrupt routine I think you are getting interrupts while you are still inside your routine. This should not happen because the interrupt should be off while in the interupt service function.

Post the code. Use [code] ... your code here [/code] to keep the code formated.
__________________
Please post questions to the forums. PM's are for personal communication.

BCHS/3v0's Tutorials
Junebug USB PIC programmer kit., USB Bit Whacker,
The 15 Minute Printed Circuit Board! (+drill time)
3v0 is offline  
Old 29th January 2009, 10:02 AM   #3
Default

Think what would happen if an interrupt came along whilst the main code was half way through transmitting a byte. Change your code so that all the SPI stuff is in either the main code or the interrupt. If your unsure how to do this then post your code (put [code] before it and [/code] after it).

Mike.
Pommie is online now  
Old 29th January 2009, 10:20 AM   #4
Default

Im trying to communicate between PIC16F873 and a digital potentiometer using SPI communication. I attached the code below.
Attached Files
File Type: c test.c (1.8 KB, 35 views)
tattee is offline  
Old 29th January 2009, 10:44 AM   #5
Default

Change it so your interrupt routine sets a variable called pot to 0/1 and change move_pot to be,
Code:
void move_pot()
{
  if(Pot==1)
    Spi_Write(0xff); 
  else
    Spi_Write(0x00); 
  SPI_CS_POT = 0;
  PORTC.F0 = 1;
  Spi_Write(0b01);                                 
  Spi_Write(0x82);                                 //Set digital potentiometer to midpoint (5K)
  SPI_CS_POT = 1;
}
Mike.
Pommie is online now  
Old 29th January 2009, 10:50 AM   #6
Default

WoW!! That's a simple but great solution Mike! THanks! I'll try this out!
tattee is offline  
Old 29th January 2009, 10:57 AM   #7
Default

By the way, will it interrupt the main program? Do I have to put the mov_pot function to a loop so it does the changes as soon as the interrupt is activated?
tattee is offline  
Old 29th January 2009, 11:24 AM   #8
Default

Without knowing the hardware I don't know if you need to call it repeatedly. An alternative way to do it would be,
Code:
void main()
{

  init_pic();
  init_timer0();
  Spi_Init_Advanced(MASTER_OSC_DIV4,
                    DATA_SAMPLE_MIDDLE,
                    CLK_IDLE_LOW,
                    LOW_2_HIGH);
 
  move_pot();
  
  INTCON = 0b10011000;
  
  do {
    if(Pot==1)
      Spi_Write(0xff); 
    else
      Spi_Write(0x00); 

     } while(1);
 }
Or, if calling the SPI function repeatedly is a problem then set Pot to 1/2 and change the code to be,
Code:
    if(Pot==1){
      Spi_Write(0xff); 
      Pot=0;
    }else if(Pot==2){
      Spi_Write(0x00);
      Pot=0;
    }
Mike.
Pommie is online now  
Old 29th January 2009, 12:46 PM   #9
Default

Thanks Mike,

I guess the do-while will do the job. Thanks again!
tattee is offline  
Old 29th January 2009, 02:40 PM   #10
Default BoostC too

This is an issue with BoostC as well so perhaps with many microcontroller Cs.
In any case the code in an interrups should be as short as possible. No delays.... State variables as suggested above let you do the slow stuff in the main line.
russ_hensel is offline  
Old 9th February 2009, 05:49 AM   #11
Default

Hi Guys!

I just wanna update you on my project. So, far the suggestion made by Pommie has had great success. Thanks again Pommie!

Now, Ive run into another problem.. Here's the code:

Code:
void Interrupt()
{
  if(INTCON.INTF)
  {
       SWITCH = W ;
       PORTA.F1 = 1;
       INTCON.INTF = 0;
  }
  else if(INTCON.RBIF)
  {
      if(PORTB.F5 == 0)                 
      {
         SWITCH = X;
         INTCON.RBIF = 0;
      }
      else if(PORTB.F6 == 0)             
      {
         SWITCH = Y;
         INTCON.RBIF = 0;
      }
      else if(PORTB.F7 == 0)
      {
         SWITCH = X;
         INTCON.RBIF = 0;
      }
   }
}

void main()
{ 
   init_all();

   do {
        switch(SWITCH)
        {
          case X:
                  INTCON.GIE = 0;
                 //do something here           
                 INTCON = 0b10011000;
          break;

          case Y:
                 INTCON.GIE = 0;
                 //do something here   
                 INTCON = 0b10011000;
          break;

          case Z:
                 INTCON.GIE = 0;
                 //do something here   
                 INTCON = 0b10011000;
          break;
          
          case W:
                 INTCON.GIE = 0;
                 PORTA.F0 = 1;
                 INTCON = 0b10011000;
          break;
          }
     } while(1);
For the INTCON.RBIF part, everything worked fine. The code reacts exactly as expected everytime PORTS 5,6,and 7 are interrupted.. The problem comes when I try to interrupt the INTCON.INTF. my code doesn't interrupt at all. why is this happening?

take note that when I try to interrupt INTCON.INTF, the PORTA.F1 = 1; is executed but not the case W: statement.
tattee is offline  
Old 9th February 2009, 06:02 AM   #12
Default

What are SWITCH, W, X, Y and Z defined as?

Mike.
Pommie is online now  
Old 9th February 2009, 06:25 AM   #13
Default

here is the edited code:
Code:
#define VOLUME_UP            1
#define VOLUME_DOWN       2
#define DIAL              3
#define DTMF_RECIEVED      4

unsigned short SWITCH = 0;

void Interrupt()
{
  if(INTCON.INTF)
  {
       SWITCH = W ;
       PORTA.F1 = 1;
       INTCON.INTF = 0;
  }
  else if(INTCON.RBIF)
  {
      if(PORTB.F5 == 0)                 
      {
         SWITCH = X;
         INTCON.RBIF = 0;
      }
      else if(PORTB.F6 == 0)             
      {
         SWITCH = Y;
         INTCON.RBIF = 0;
      }
      else if(PORTB.F7 == 0)
      {
         SWITCH = X;
         INTCON.RBIF = 0;
      }
   }
}

void main()
{ 
   init_all();

   do {
        switch(SWITCH)
        {
          case X:
                  INTCON.GIE = 0;
                 //do something here           
                 INTCON = 0b10011000;
          break;

          case Y:
                 INTCON.GIE = 0;
                 //do something here   
                 INTCON = 0b10011000;
          break;

          case Z:
                 INTCON.GIE = 0;
                 //do something here   
                 INTCON = 0b10011000;
          break;
          
          case W:
                 INTCON.GIE = 0;
                 PORTA.F0 = 1;
                 INTCON = 0b10011000;
          break;
          }
     } while(1);
tattee is offline  
Old 9th February 2009, 06:37 AM   #14
Default

I still can't see where W, X, Y & Z are defined.

Mike.
Pommie is online now  
Old 9th February 2009, 06:40 AM   #15
Default

oh im sorry, i wasn't able to edit the line.. here it is:
Code:
#define X            1
#define Y      2
#define Z             3
#define W      4

unsigned short SWITCH = 0;

void Interrupt()
{
  if(INTCON.INTF)
  {
       SWITCH = W ;
       PORTA.F1 = 1;
       INTCON.INTF = 0;
  }
  else if(INTCON.RBIF)
  {
      if(PORTB.F5 == 0)                 
      {
         SWITCH = X;
         INTCON.RBIF = 0;
      }
      else if(PORTB.F6 == 0)             
      {
         SWITCH = Y;
         INTCON.RBIF = 0;
      }
      else if(PORTB.F7 == 0)
      {
         SWITCH = X;
         INTCON.RBIF = 0;
      }
   }
}

void main()
{ 
   init_all();

   do {
        switch(SWITCH)
        {
          case X:
                  INTCON.GIE = 0;
                 //do something here           
                 INTCON = 0b10011000;
          break;

          case Y:
                 INTCON.GIE = 0;
                 //do something here   
                 INTCON = 0b10011000;
          break;

          case Z:
                 INTCON.GIE = 0;
                 //do something here   
                 INTCON = 0b10011000;
          break;
          
          case W:
                 INTCON.GIE = 0;
                 PORTA.F0 = 1;
                 INTCON = 0b10011000;
          break;
          }
     } while(1);
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 03:09 AM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker