|
|
View previous topic :: View next topic |
Author |
Message |
valemike Guest
|
i2c is error-prone when TIMER1 is enabled... |
Posted: Mon Feb 28, 2005 7:27 am |
|
|
What is the interaction of timer1 and the i2c module (PIC is a slave in this case)? It seems that when the slave has multiple ISRs, then the Master i2c PIC experiences errors trying to get an ACK out of the slave. The only way i can eliminate the errors is when i do a #priority statement:
#include <18F448.h>
#include "slider_commands.h"
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8000000)
#priority SSP,RTCC,TIMER1
Though this makes my problems go away, i feel that i only did a kludge.
What is the proper way to handle such intermittent errors? (Perhaps to make my own ISR?
As you can see below, the code for the INT_RTCC and INT_TIMER1 is very minimal, although TIMER1's isr does execute around 30 times per second.
Code: |
#INT_RTCC
void timer1_isr(void)
{
GLOBAL_refresh_led_flag = 1;
}
#INT_TIMER1 // This function is called every time
void clock_isr() { // timer 1 overflows (65535->0), which is
// approximately 19 times per second for
if(--int_count==0) { // this program.
++seconds;
int_count = INTS_PER_SECOND;
}
if (--int_half_count==0)
{
++half_seconds;
int_half_count = INTS_PER_HALF_SECOND;
}
}
#INT_SSP
void ssp_interupt ()
{
i2c_interrupt_handler();
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Mon Feb 28, 2005 8:26 am |
|
|
#priority, is not a 'kludge'. It simply sets what order the interrupts are tested in the software parser. The fact that this makes the problem go away, tells you that the problem is that the other interrupts are occurring frequently enough, to actually 'starve' the SSP interrupt of processor time. You have some odd 'labelling', which does not help make things clear (the RTCC, is timer0, not timer1...). You do not say what the prescaler used is for this, but then comment that timer1, is occuring 30 times/second, while the code says that timer1 is occuring 19 times/second.
Realistically, if you have high frequency timer interrupts, it is better to derive one from the other, rather than having multiple handlers. So if timer1, is at twice the interval of timer0, then get rid of timer1 completely, and just execute a toggle in timer0, and call the required code on alternate interrupts. The reason this is 'better', is the overhead associated with interrupt handling. The processor, has to save about twenty registers, then test the interrupt source, then call the actual code, and then restore all the registers. The total overhead, is typically something in the order of perhaps 40 to 50uSec on a machine at 8MHz!...
Using just one timer interrupt, avoids having this overhead occuring twice.
Are you sure the interrupts are occurring at the expected frequency?. What clock rate are you running the I2C?.
If I assume that the I2C, is running at 100KHz, and a few bytes are sent sequentially, then these will potentially arrive at intervals of only 1/12500th second. This means that assuming the I2C code takes a few uSec, there is not really time to execute a timer interrupt between receiving one byte and the next, or the buffer will overflow. Hence it becomes vital to check the SSP interrupt, before any timer calls. Assuming your timers are in fact synchronous to one another, as it stands, you will probably get RTCC triggereing, then Timer1, and since they are written with the RTCC first, without #priority, both of these would have to be serviced before the SSP interrupt can be called. This then leads to potentially something in the order of 170uSec delay before the SSP interrupt is serviced, which would result in a buffer overflow being signalled....
Best Wishes
Best Wishes |
|
|
|
|
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
|