I just looked at the code I wrote a while ago to set up timer 2 for a periodic interrupt of 1 ms for a PIC24F (essentially same timer hardware as dsPIC33F), and it looks like so:
#define CPU_CLK_RATE 32000000L
#define PERIPH_CLOCK_RATE (CPU_CLK_RATE/2L)
#define TIMER_2_RATE 1000L
#define TIMER_2_PRE 64L // clock rate is (32000000/2)/64 = 250 KHz
#define TIMER_2_MATCH (PERIPH_CLOCK_RATE/(TIMER_2_RATE * TIMER_2_PRE))
T2CON = 0; // set control register to defaults
T2CONbits.TSIDL = 1; // discontinue when idle
T2CONbits.TCKPS1 = 1; // prescaler of 64
T2CONbits.TCKPS0 = 0; // prescaler of 64
T2CONbits.T32 = 0; // 16 bit timer
T2CONbits.TCS = 0; // FOSC/2 (32Mhz/2)
TMR2 = 0-TIMER_2_MATCH*19; // 20 millisecond delay before starting
PR2 = TIMER_2_MATCH;
SetPriorityIntT2(TIMER2_INTERRUPT_PRIORITY); // set to very high priority
EnableIntT2; // enable interrupts
T2CONbits.TON = 1
Very similar to yours, except I pre-initialized TMR2 so there would be a delay before the first interrupt. Don't know if that would help in your case or not, but you might try it.
You probably want to take the transmission time (and software UART management methods) of the Serial.print() routine into account.
If you have access to a scope, toggling I/O pins would be a lot faster. You could toggle one in the ISR and the other in the loop.
Or you could increment a counter in the ISR and sample/clear it in the loop (inside an interrupt disable/re-enable) then print it (after re-enabling interrupts). More sophisticated would be to only print the number if it exceeds the previous maximum.
However, such tests are fundamentally flawed unless the testing code constitutes a small fraction of the loop operations - just figuring out how many interrupts can occur during a max-check/print routine is meaningless in terms of the ultimate operation which would presumably be doing something else in the loop.
Generally, you will want to use circular buffering if you are acquiring data via an interrupt which must be aggregated into a larger assembly (bits into bytes, or bytes into buffers) and then acted upon in a way that is at all time consuming. It shouldn't be too hard to change your buffer size later to optimize memory consumption, especially if you keep them power-of-two sized. You may want to build in overflow alarms, and try running the finished system with an artificially reduced buffer size.
Do pay very careful attention to ensuring that the ISR can't jump in the middle of where the loop trying to update the buffer's tracking variables - if you do a read-modify-write, you'll need to protect it.
Best Answer
Looks like this might be what you want http://www.microchip.com/forums/tm.aspx?m=427159&mpage=1&print=true.