View previous topic :: View next topic |
Author |
Message |
ddscott
Joined: 17 Aug 2005 Posts: 4 Location: Livermore, CA
|
I2C Interrupt Handling |
Posted: Fri Aug 19, 2005 11:52 am |
|
|
I am attempting to read in a byte of data from the i2c port. The PIC is configured to operate in the slave mode. I wish to pass the data off after it is received to perform some function depending on what the data is. I want to be able to read additional data from the i2c port and possibly interrupt the ongoing task with one of higher priority. The data is read and passed as expected, but if the PIC is performing some function (toggling a pin for 10 seconds), the i2c port will not read any more data. The SSPBUF register ends with the PIC’s i2c address loaded into it and the SSPCON register has the SSPOV bit set (a byte is received while the SSPBUF register is still holding the previous byte (must be cleared in software). The PIR1 register is all 0’s indicating a ISR has not happened.
#include "C:\Program Files\PICC\Projects\Bio_Briefcase\i2c_0816.h"
// Function to do something with the data read from the I2C port; Receives int num - returns nothing
void data_in(num)
{
long i;
if (num == 0x33)
{
for (i=0; i<10000; i++)
{
output_toggle(pin_a0);
delay_ms(1);
}
}
}
// I2C interrupt service routine, reads a byte and sends it to the function data_in
#int_SSP
void SSP_isr()
{
int incoming;
long i;
if (i2c_poll() == TRUE)
{
incoming = i2c_read();
clear_interrupt(int_ssp);
data_in (incoming);
}
}
// Main program function does nothing
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(VREF_LOW|-2);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_oscillator(False);
while (true) {}
} |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 19, 2005 12:23 pm |
|
|
Don't call long routines from within an isr. Just set a global flag in the
isr to indicate that you got the data. Store the data in a global buffer.
Then poll the flag outside the isr. If the flag is set = True, then use the
data (from the global buffer) and clear the flag. Also clear the flag
initially, before you enable interrupts. |
|
|
ddscott
Joined: 17 Aug 2005 Posts: 4 Location: Livermore, CA
|
|
Posted: Fri Aug 19, 2005 1:00 pm |
|
|
Thanks, that works. I was trying to use gloabals earlier, but had other issues with my code. Thanks for getting me back on track. |
|
|
|