Pues ya está solucionado fram_22, gracias a tu inestimable ayuda

.
El problema estaba en que en la segunda parte del oscilador la instrucción la tenía como:
__builtin_write_OSCCONH(0x01); // Initiate Clock Switch to FRC with PLL (NOSC=0b001)
y la que funcina bien es:
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to FRC with PLL (NOSC=0b001)
También hay que cambiar:
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_NONE);
por:
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT);
Es curioso porque esa configuración la copié de internet, y hay un monton de ejemplos con ello mal. Aclarar que el error que se comete es del 10% en vez del 20% que había comentado.
Dejo mi programilla midificado por si a alguien le interesa. A proposito ¿como se mete dentro de un recuadro para que no ocupe tanto como ha hecho fram_22,?
#include <p33FJ256GP710.h>
//Primera parte de la configuración del oscilador a 40 Mips. Esta copiada pero no está entendida del todo. Para entenderla mirar el fichero de cabecera del pic
_FOSCSEL(FNOSC_FRC); // Internal FRC oscillator
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // Clock Switching is enabled and Fail Safe Clock Monitor is disabled
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystanl
//INTERRUPCIÓN DEL TIMER1
void __attribute__((interrupt,no_auto_psv)) _T1Interrupt( void )
{
LATAbits.LATA0=~LATAbits.LATA0;
IFS0bits.T1IF = 0; //Se pone a cero el flag de la interrupción
}
void osc_40MIPS(void)
{
PLLFBD = 38; // M = 40
CLKDIVbits.PLLPOST = 0; // N1 = 2
CLKDIVbits.PLLPRE = 0; // N2 = 2
OSCTUN = 0;
RCONbits.SWDTEN = 0;
// Clock switch to incorporate PLL
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to FRC with PLL (NOSC=0b001)
__builtin_write_OSCCONL(0x01); // Start clock switching while (oscconbits.cOSC != 0b001); Wait for Clock switch to occur
while(OSCCONbits.COSC != 0b011) {}; //Se espera a que entre el oscilador primario con el PLL habilitado.
while(OSCCONbits.LOCK != 1) {}; //Se espera a que el PLL esté en funcionamiento
}
void Init_Timer1(void)
{
IPC0bits.T1IP = 4; // Se le da el nivel de prioridad
IFS0bits.T1IF = 0; // Reset Timer1 interrupt flag
IEC0bits.T1IE = 1; // Enable Timer1 interrupt
T1CONbits.TCS=0; // Fuente = Internos (Fcy)
T1CONbits.TCKPS=0; // Prescaler=1:1
T1CONbits.TGATE=0; // TGate inactivo
T1CONbits.TSIDL=0; //Continúa activo en modo Idle / Sleep
PR1=199; //Cuando el timer alcanza el valor del PR1 se resetea y se activa la interrupción si está habilitada
TMR1=1;
T1CONbits.TON=1; //Timer en marcha
}
int main(void)
{
osc_40MIPS();
Init_Timer1();
TRISA=0; //Ponemos puerto A como salida
LATA=0x00; //Se pone LATA porque con PORTA parece que hay problemas
while(1)
{
}
}
Voy a probar el reloj en tiempo real por sofware y os comento el resultado.
Un saludo a todos.