IIR filter on a 16bit MCU (PIC24F)
I didn't dive super far into your filter design, but just looking at the source code brings a couple of things up.  For example, these lines:

aux1 = ((long)b0*xn) &lt;&lt; 1;
aux2 = ((long)a1*y) &lt;&lt; 1;
y = ((aux1 + aux2) &gt;&gt; 16);


The first issue I see is the ((long)b0*xn).  I have ran across compilers that would compile this incorrectly as ((long)(b0*xn)), which is entirely wrong.  Just to be on the safe side, I would write this as (((long)b0)*((long)xn)).  To be sure, this is paranoid programming, but...

Next, when you do the "&lt;&lt;1", this is NOT the same as "*2".  For most things, it's close, but not for DSP.  It has to do with how the MCU/DSP handles overflow conditions and sign extensions, etc.  But even if it did work as a *2, you are removing one bit of resolution that you don't need to remove.  If you really have to do a *2, then do a *2 and let the compiler figure out if it could substitute a &lt;&lt;1 instead.

The >>16 is also problematic.  Off the top of my head, I don't know if it's going to do a logical or arithmetic shift.  You want an arithmetic shift.  Arithmetic shifts will handle the sign bit correctly where a logical shift will insert zeros for the new bits.  Besides, you can save bits of resolution by getting rid of the &lt;&lt;1 and changing the >>16 to >>15.  Well, and changing all of these to normal multiplies and divides.

So here's the code I would use:

aux1 = ((long)b0) * ((long)xn);
aux2 = ((long)a1) * ((long)y);
y = (short)((aux1+aux2) / 32768);


Now, I don't claim that this will solve your problem.  It may or may not, but it does improve your code.