|
|
View previous topic :: View next topic |
Author |
Message |
harry_bach
Joined: 20 Nov 2004 Posts: 2 Location: Edinburgh, Scotland
|
incorporating two interrupts (rda and ext) |
Posted: Sat Nov 20, 2004 12:10 pm |
|
|
I have a problem incorporating two interrupts (rda and ext) on the PIC18F452. I have an application that transmits data from flash to a server using xmodem via a mobile phone. This is working fine, but yesterday I added a simple trigger for this process using the external interupt ext. I find that when I add the ISR for the external interupt the serial interrupt stops working. When I break the code it appears the GIE (INTCON.7) is set to 0, but I cannot find where this occurs. Interestingly PEIE remains set. Its as if its already inside an ISR ? I have included snippets of code below.
Could someone point out what I am doing wrong please ?
I guess my real problem is I don't really understand when to use enable_interrupts(global) if I am switching on and off the rda enable bit (PIE.5) through the code. Is it each time I change the bit or only once at the beginning.
Code: | void main()
{
initialise();
do
{
//sleep();
MakeThatCall();
} while (status != ERROR);
IndicateError();
}
//*************************************************************************
//******************************** PIC ***********************************
//*************************************************************************
//------------------------------------------------------------------------
#int_rda
void serial_isr(void)
{
TempBuffer=getc();
if ((TempBuffer!=CR)&&(TempBuffer!=LF)&&(TempBuffer!=SP))
{
*RxBufferTop++=TempBuffer;
if (RxBufferTop>(RxBuffer+BUFFER_SIZE))
{
RxBufferTop=RxBuffer; // Reset pointer
}
}
}
//------------------------------------------------------------------------
#int_ext
void PermissionToSend_isr(void)
{
/* if (INTEDG0) // if detected edge is rising
{
FlashYellowLedFast(2); // testing !!!!!!!!!!!!
Reset_CPU();
}
else
{
delay_cycles(1);
} */
}
//------------------------------------------------------------------------
int8 EnableRegistration()
{
int8 i;
for(i=0; i<10; i++)
{
delay_ms(150);
FlushRS232();
ClearBuffer();
SERIAL_ON;
GLOBAL_INTERUPTS;
printf("AT+COPS=0\r\n");
if (WaitModemResponseOKLong())
return TRUE;
}
return FALSE;
}
//------------------------------------------------------------------------
int8 WaitModemResponseOKLong()
// Waits for each tick period and examines the RxBuffer for 'OK'
// If a timeout occurs status set to error
{
WaitCounter=0;
do
{
delay_ms(TICK);
if(WaitCounter++>AWAIT_OK_LONG)
{
status = ERROR;
return FALSE;
}
if(strstr(RxBuffer, ERRORR))
return FALSE;
} while(!(strstr(RxBuffer, OK)));
SERIAL_OFF;
GLOBAL_INTERUPTS;
return TRUE;
} |
_________________ Harry. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Nov 20, 2004 3:32 pm |
|
|
I don't think you gave enough information yet.
You need to post your #use rs232() statement.
It wouldn't hurt to post your #use delay() and
#fuses statements, too.
Also post the lines where you define these macros:
SERIAL_ON;
SERIAL_OFF;
GLOBAL_INTERUPTS;
If they have #bit or #byte statements in them,
then post those too. |
|
|
harry_bach
Joined: 20 Nov 2004 Posts: 2 Location: Edinburgh, Scotland
|
|
Posted: Sun Nov 21, 2004 1:32 pm |
|
|
Just to explain further MakeThatCall() uses a series of sub-functions including EnableRegistration(). All these sub functions follow the same pattern sending an AT command and await a response using functions like WaitModemResponseOKLong(), which compare a fixed string responds with an RxBuffer which in turn is filled by the RDA ISR. The code works in its current form, but if I add any code in the int_ext ISR the GIE bit sets to 0 somewhere and so when serial data is received the serial ISR is not called (even with the enable_interrupts(INT_EXT) commented out in the initialise() function.
Code: | #use delay(clock=4000000)
#fuses XT,NOWDT,WDT1
#use RS232 (baud=9600, xmit=PIN_C6, RCV=PIN_C7, bits=8, ERRORS)
#use i2c (master)
#define GLOBAL_INTERUPTS enable_interrupts(global)
#define SERIAL_ON enable_interrupts(int_rda)
#define SERIAL_OFF disable_interrupts(int_rda)
void initialise(void)
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
MODEM_OFF;
//PD_FLOAT; // need PD to float or as input on old board 4.3 phone board
PD_LOW; // Need to set PD as an O/P on the daughter board
status=IDLE;
FlashLedFast(2);
//ext_int_edge(0, H_TO_L); // Set edge to trigger on
//enable_interrupts(INT_EXT);
//enable_interrupts(GLOBAL);
} |
_________________ Harry. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 21, 2004 4:48 pm |
|
|
A few comments:
1. You should have NOLVP in your #fuses statement. Without that,
you risk having random lock-ups.
2. I'm not sure why you have WDT1 in your #fuses statement.
I would have only NOWDT during the debugging process.
3. I don't know why you want to shut off RS-232 interrupts periodically.
I would just let them run. You have a circular buffer to receive
the characters. If you're not going to check the buffer for a long
time, then perhaps set a global flag if the buffer overflows.
Or perhaps just clear the buffer, before you go to use it again.
4. I would enable interrupts for INT_RDA and GLOBAL once, near the
start of the program, in main().
5. You have this line:
It compiles without error, but you should specify the SDA and SCL pins.
Without those pins, it looks to me like the compiler is generating semi-garbage code and that's not good.
6. I'm not sure what the purpose of you INT_EXT routine is:
Code: | #int_ext
void PermissionToSend_isr(void)
{
/* if (INTEDG0) // if detected edge is rising
{
FlashYellowLedFast(2); // testing !!!!!!!!!!!!
Reset_CPU();
}
else
{
delay_cycles(1);
} */
} |
So if you get an external interrupt, you want to reset the CPU ?
What's the definition of 'INTEDG0' ?
I wonder if the CPU is getting reset at a time when you don't intend it to ?
Your basic complaint is that INT_RDA stops when you "add code" to the
INT_EXT routine. Well, adding code that resets the CPU on some edge
(or noise on the pin), is not my idea of a good test.
I would strip out everything in that routine except the delay_cycles(1)
and see if your problem goes away. |
|
|
|
|
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
|