![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
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. | |
| |
| | #2 | |
| Quote:
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) | ||
| |
| | #3 |
|
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. | |
| |
| | #4 |
|
Im trying to communicate between PIC16F873 and a digital potentiometer using SPI communication. I attached the code below.
| |
| |
| | #5 |
|
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;
}
| |
| |
| | #6 |
|
WoW!! That's a simple but great solution Mike! THanks! I'll try this out! | |
| |
| | #7 |
|
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?
| |
| |
| | #8 |
|
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);
}
Code: if(Pot==1){
Spi_Write(0xff);
Pot=0;
}else if(Pot==2){
Spi_Write(0x00);
Pot=0;
}
| |
| |
| | #9 |
|
Thanks Mike, I guess the do-while will do the job. Thanks again! | |
| |
| | #10 |
|
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. | |
| |
| | #11 |
|
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);
take note that when I try to interrupt INTCON.INTF, the PORTA.F1 = 1; is executed but not the case W: statement. | |
| |
| | #12 |
|
What are SWITCH, W, X, Y and Z defined as? Mike. | |
| |
| | #13 |
|
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);
| |
| |
| | #14 |
|
I still can't see where W, X, Y & Z are defined. Mike. | |
| |
| | #15 |
|
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);
| |
| |
|
| 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 |