Muchas gracias de nuevo, Jonathan!! Pues me he pasado ayer toda la tarde revisando y no encuentro nada, las variables de memoria las declaro todas seguidas en el programa principal. Lo que si he observado es que si introduzco los valores por teclado muy rapido funciona bien, pero si los introduzco a una velocidad normal ya va mal... no se si esto servira de algo, asi que voy a colgar el codigo, es bastante extenso, pero puede que otros ojos lo vean mejor que los mios..  Hay subrutinas que no pongo porque es evidente lo que hacen y ocuparia mucho mas el codigo:
;      ZONA DE DATOS
GUARDA_W   EQU   0X20         ; variables para guardar los registros
GUARDA_S   EQU 0X21
GUARDA_FSR   EQU   0X22
PDel0      EQU   0x24
PDel1      EQU   0x25
PDel2      EQU   0x26
R_ContA      EQU   0x27            ; Contadores para los retardos.
R_ContB      EQU   0x28
R_ContC      EQU   0x29
ASCII_H      EQU   0x2A
ASCII_M      EQU   0x2B
ASCII_L      EQU   0x2C
HEXADECIMAL   EQU   0x2D
HEXADECIMAL_X   EQU   0X2E
ASCII1      EQU   0X2F
ASCII2      EQU   0X30
INNER      EQU   0x31      ;delay variable mS
OUTER      EQU   0x32      ;delay variable mS
Digito      EQU   0x33
   CBLOCK   0X40   ; aqui esta el status de lo enviado
startdelimiterst
lenght_hst
lenght_lst
apiidentifierst      ; desde aqui se calcula el checksum
frameidst            ;
statusst      ; (ack/nack)
checksumst
FF
CHECK
   ENDC
   CBLOCK   0X50   ; aqui estan los datos enviados
startdelimitertx
lenght_htx
lenght_ltx
apiidentifiertx      ; desde aqui se calcula el checksum
frameid            ;
address_htx         ;
address_ltx         ;   CHECKSUM
optionstx         ;
dato1tx            ;
dato2tx            ; hasta aqui
checksumtx
datotx
rc_reg         ; 0x5C
   ENDC
   CBLOCK   0x5F   ; aqui estaran los datos recibidos
counter
startdelimiter
lenght_h
lenght_l
apiidentifier
saddress_h
saddress_l
rssi
options
dato1
dato2
checksum
cuenta_timer1            ; 0x5B
posicion_cursor
   ENDC
   CBLOCK 0x6E
TEMPORAL
CONTADOR      ; todo esto sirve para los comandos AT
MEMORIA   
MEMORIA2
MEMORIA3
MEMORIA4
MEMORIA5
MEMORIA6
teclapulsada   ; almacena la tecla actual pulsada
pulsaciones      ; pulsaciones que quedan para finalizar
centenas      
decenas
unidades
velocidad      ; velocidad en hexadecimal
tipo         ; tipo
circ         ; circunstancia
flujo         ; sirve para saber en que punto nos encontramos
   ENDC
      processor 16F876
      LIST   P=16F876   ;Se indica el modo de procesador
      
      INCLUDE   <P16f876.inc>   ;se incluye la definicion de los
               ;registros internos
      __config 3D31
;----------------------------------------------------------------------------
      org    0x00      ;vector de inicio
      goto    INICIO
      org    0x04      ;despues del vector de interrupcion
      goto   ServicioInterrupcion 
      
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
;----------------------------------------------------------------------------
INICIO   
   call   configura_micro
   call    inicializa_lcd
   call   MuestraBien
   call   PDelay      ; retardo de 2 segundos
otratipo
            call   Borra_home
                  movlw   0x80            ;Direccion caracter
                call    LCD_REG      
   call   PideTipo
   movlw   0x01
   movwf   pulsaciones      ; inicializamos pulsaciones maximas
   
   clrf   flujo      ; esta en tipo --> flujo=0
   movlw   0xFF      ; ponemos a algo distinto de 0
   movfw   centenas
   movfw   decenas
   movfw   unidades
otra
   call    Teclado_Inicializa
   call   Habilita_Int_Teclado
   sleep
   ; mira si tiene que volver a dormir o no
      movlw   0x0A
      subwf   teclapulsada,0      ; es A?
      btfsc   STATUS,Z         ; 
      goto    otratipo      ; si, borra
      movlw   0x0B
      subwf   teclapulsada,0      ; es B?
      btfsc   STATUS,Z         ; 
      goto    fintipo      ; si, pasa a lo siguiente
   call   Retardo_100ms
   goto otra
fintipo
;********************************************************************
otravel
            call   Borra_home
                  movlw   0x80            ;Direccion caracter
                call    LCD_REG   
   call   PideVel
   movlw   0x03
   movwf   pulsaciones      ; inicializamos pulsaciones maximas
   
   movlw   0x01
   movwf   flujo         ; esta en velocidad --> flujo=1
   clrf   centenas
   clrf   decenas
   clrf   unidades
   call   Cursor_on
otra2
   call    Teclado_Inicializa
   call   Habilita_Int_Teclado
   sleep
   ; mira si tiene que volver a dormir o no
      movlw   0x0A
      subwf   teclapulsada,0      ; es A?
      btfsc   STATUS,Z         ; 
      goto    otravel      ; si, borra
      movlw   0x0B
      subwf   teclapulsada,0      ; es B?
      btfsc   STATUS,Z         ; 
      goto    FinVel      ; si, va a calcular
   call   Retardo_100ms
   goto    otra2
FinVel   
; metemos el valor de la velocidad en dato1tx
      movfw   velocidad
      movwf   dato1tx
;********************************************************************
otracirc
            call   Borra_home
                  movlw   0x80            ;Direccion caracter
                call    LCD_REG   
   call   PideCirc
   movlw   0x01
   movwf   pulsaciones      ; inicializamos pulsaciones maximas
   
   movlw   0x02
   movwf   flujo      ; esta en circunstancia --> flujo=2
   movlw   0xFF
   movwf   centenas
   movwf   decenas
   movwf   unidades   ; para que sea erroneo si no se mete nada
   call   Cursor_on
otra3
   call    Teclado_Inicializa
   call   Habilita_Int_Teclado
   sleep
   ; mira si tiene que volver a dormir o no
      movlw   0x0A
      subwf   teclapulsada,0      ; es A?
      btfsc   STATUS,Z         ; 
      goto    otracirc      ; si, borra
      movlw   0x0B
      subwf   teclapulsada,0      ; es B?
      btfsc   STATUS,Z         ; 
      goto    FinCirc      ; si, va a calcular
   call   Retardo_100ms
   goto    otra3
      
FinCirc      
   call   montadato2tx
;*******************************************************************
;*******************************************************************
;*******************************************************************
;*******************************************************************
;
; ya esta todo metido, nos preparamos para transmitir
;
   call   configura_micro
;**************************
   call   Borra_home
   call    INITX         ; inicializamos la transmision
   call   SET125K         ; micro a 125Kbps
retransmitir
   movlw   0X40         ; dirección de memoria RAM a escribir.
   movwf   counter         ; el TX STATUS que manda el Xbee
   call   BORRAAPIST
   call   RX            ; nos preparamos para recibir por interrupciones
   call   APITX
   call   Retardo_10ms   ; tiempo reducido al maximo
   call   MUESTRAAPIST
LeeVelocidad
      banksel   PORTA
          bcf     PORTA,2         ;Desactiva LCD
      call   LeeTecla
      movwf   teclapulsada
      bsf   STATUS,RP0   ;banco 1 
   movlw   b'00000000'         ; deshabilita interrupciones
   movwf   INTCON
      bcf         STATUS,RP0      ; banco 0
;*******************************************************
; aqui lee lo introducido, lo almacena en variables y calcula lo que va a enviar
; antes de nada ha de mirar si es A o B para salir del bucle y ordenar los datos
; antes de calcular el valor de la velocidad en hexadecimal
      movlw   0x0A
      subwf   teclapulsada,0      ; es A?
      btfsc   STATUS,Z         ; 
      goto    otravel         ; si, repite
      movlw   0x0B
      subwf   teclapulsada,0      ; es B?
      btfsc   STATUS,Z         ; 
      goto    calcular_vel      ; si, va a calcular
      ; no es ni A ni B
      ; almacena lo tecleado
;   
      goto    continuavel   ; esta bien, continua
error_vel
            call   Borra_home
                  movlw   0x80            ;Direccion caracter
                call    LCD_REG                           
            call   Cursor_off
            call    MensVelInc
            call   PDelay      ; retardo 2 segundos
      goto otravel   ; vuelve a pedir la velocidad
continuavel
      decf   pulsaciones
      
      movlw   0x02
      subwf   pulsaciones,0      ; es centenas?
      btfsc   STATUS,Z         ; 
      goto    mete_centenas      ; si, lo guarda
      
      movlw   0x01
      subwf   pulsaciones,0      ; es decenas?
      btfsc   STATUS,Z         ; 
      goto    mete_decenas      ; si, lo guarda   
      movlw   0x00
      subwf   pulsaciones,0      ; es unidades?
      btfsc   STATUS,Z         ; 
      goto    mete_unidades      ; si, lo guarda
      ; si llega aqui es que se ha pasado, no hace nada y
      ; espera a que se  pulse A o B
      
      goto finesperavel
mete_centenas
   movfw   teclapulsada
   movwf   centenas
   
   goto fincalcula
mete_decenas
   movfw   teclapulsada
   movwf   decenas
   goto fincalcula
mete_unidades
   movfw   teclapulsada
   movwf   unidades
   goto fincalcula
calcular_vel      ; llega aqui si se pulsa B
   ; aqui mira si son 1, 2 o 3 digitos pulsados y organiza los datos
   ; si pulsaciones es 0 es que ha metido 3 datos, si es 1 ha metido 2 datos
      movlw   0x00
      subwf   pulsaciones,0   ; pulsaciones-0=pulsaciones --> afecta al flag Z
      btfsc   STATUS,Z         ; ha metido 3 digitos?
      goto    bienmetido         ; si, esta bien ordenado
                        ; no, hay que reordenar los 2 datos
      movlw   0x01         ; ha metido 2?
      subwf   pulsaciones,0   ; 
      btfss   STATUS,Z         ; ha metido 2 digitos?
      goto    error_vel         ; no, esta mal
   ; si, hay que ordenarlos
      movfw   decenas
      movwf   unidades
      movfw   centenas
      movwf   decenas      ; ya esta ordenado
      clrf   centenas   ; centenas tiene que ser 0
bienmetido   ; a partir de aqui hay que pasar los 3 bytes a un solo valor
      clrf   velocidad
;   centenas
      movlw   0x00
      subwf   centenas,0      ; centenas-0 --> afecta al flag Z
      btfsc   STATUS,Z      ; centenas es 0?
      goto   metedecenas      ; si, centenas es 0
                        ; no, centenas no es 0
      movlw   d'100'
      addwf   velocidad         ; valor+100
      
metedecenas   ; multiplica las decenas por 10 (bucle)
      movlw   0x0B   
      movwf   TEMPORAL   ; reutilizo esta variable como contador 
bucle
      decf   TEMPORAL
      btfsc   STATUS,Z      ; es 0?
      goto    meteunidades   ; si, guarda el resultado
      ; no, sigue en el bucle
      movfw   decenas
      addwf   velocidad,1         ; decenas+decenas   
      goto    bucle
   ; ya esta almacenado en valor
   
meteunidades   ; solamente hay que sumar las unidades
      movfw   unidades
      addwf   velocidad,1
;   en valor tenemos el resultado de la velocidad en hexadecimal
;    si es mayor de 120 esta mal
      movlw   0x79         ; 121
      subwf   velocidad,0      ; velocidad-121 = negativo
      btfsc   STATUS,C      ; si C=0 es negativo --> salta
      goto    error_vel      ; la velocidad esta mal --> repetir
      movlw   0xA            ; 10
      subwf   velocidad,0      ; velocidad-10 = negativo
      btfss   STATUS,C      ; si C=1 es positivo --> bien
      goto    error_vel      ; si C=0 es negativo --> error
   
   ; la velocidad esta bien
      goto   finesperavel
;****************************************************
fincalcula
      movfw   teclapulsada
      call   hextoascii
      movfw   ASCII2
      call    LCD_DATOS       ; Visualiza caracter
finesperavel
   return
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
LeeTipo
      banksel   PORTA
          bcf     PORTA,2         ; Desactiva LCD
      call   LeeTecla
      movwf   teclapulsada   ; guardamos la tecla pulsada
      bsf   STATUS,RP0   ;banco 1 
   movlw   b'00000000'         ; deshabilita interrupciones
   movwf   INTCON
      bcf         STATUS,RP0      ; banco 0
;*******************************************************
; aqui lee lo introducido, lo almacena en variables y calcula lo que va a enviar
; antes de nada ha de mirar si es A o B para salir del bucle y ordenar los datos
; antes de calcular el valor de la velocidad en hexadecimal
      movlw   0x0A
      subwf   teclapulsada,0      ; es A?
      btfsc   STATUS,Z         ; 
      goto    otratipo      ; si
      movlw   0x0B
      subwf   teclapulsada,0      ; es B?
      btfsc   STATUS,Z         ; 
      goto    mete_unidades_tipo      ; si
      ; no es ni A ni B
      ; almacena lo tecleado
      decf   pulsaciones
      
      movlw   0x00
      subwf   pulsaciones,0      ; es unidades?
      btfss   STATUS,Z         ; 
      goto    finespera_tipo      ; no, no hace nada
      
      movfw   teclapulsada   ; si
      movwf   unidades      ; guarda unidades
      goto fincalcula_tipo   ; pinta la letra y vuelve al sleep
mete_unidades_tipo    ; llega aqui si pulsa correctamente B
               ; solo puede haber 1 digito, 0, 1 o 2
      movlw   0x01
      subwf   pulsaciones,0      ; ha pulsado solo B?
      btfsc   STATUS,Z         ; si, Z estara a 1
      goto    error_tipo      ; no, no hace nada
   movlw   0x03   ; comprueba si es mayor de 2
   subwf   unidades,0   ; unidades-3 = negativo
   btfsc   STATUS,C   ; si C=0 es negativo --> salta
   goto    error_tipo   ; el tipo esta mal --> repetir tipo
   
   movfw   unidades   ; el tipo esta bien, lo almacena
   movwf   tipo      ; en tipo
   goto    finespera_tipo
   
error_tipo
            
            call   Borra_home
                  movlw   0x80            ;Direccion caracter
                call    LCD_REG                           
            call   Cursor_off
            call    MensTipoInc
            call   PDelay      ; retardo 2 segundos
;            call   Borra_home
      goto otratipo   ; vuelve a pedir el tipo
;****************************************************
fincalcula_tipo
      movfw   teclapulsada
      call   hextoascii
      bsf     PORTA,2         ; activa LCD
      movfw   ASCII2
      call    LCD_DATOS       ; Visualiza caracter
finespera_tipo
   return
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************
LeeCirc
      banksel   PORTA
          bcf     PORTA,2         ;Desactiva LCD
      call   LeeTecla
      movwf   teclapulsada   ; guardamos la tecla pulsada
      bsf   STATUS,RP0   ;banco 1 
   movlw   b'00000000'         ; deshabilita interrupciones
   movwf   INTCON
      bcf         STATUS,RP0      ; banco 0
;*******************************************************
; aqui lee lo introducido, lo almacena en variables y calcula lo que va a enviar
; antes de nada ha de mirar si es A o B para salir del bucle y ordenar los datos
; antes de calcular el valor de la velocidad en hexadecimal
      movlw   0x0A
      subwf   teclapulsada,0      ; es A?
      btfsc   STATUS,Z         ; 
      goto    otracirc      ; si
      movlw   0x0B
      subwf   teclapulsada,0      ; es B?
      btfsc   STATUS,Z         ; 
      goto    mete_unidades_circ      ; si
      ; no es ni A ni B
      ; almacena lo tecleado
      decf   pulsaciones
      
      movlw   0x00
      subwf   pulsaciones,0      ; es unidades?
      btfss   STATUS,Z         ; 
      goto    finespera_circ      ; no, no hace nada
      
      movfw   teclapulsada   ; si
      movwf   unidades      ; guarda unidades
      goto fincalcula_circ   ; pinta la letra y vuelve al sleep
mete_unidades_circ    ; llega aqui si pulsa correctamente A o B
               ; solo puede haber 1 digito, 0, 1 o 2
   movlw   0x0A   ; comprueba si es mayor de 9
   subwf   unidades,0   ;unidades-A = negativo
   btfsc   STATUS,C   ; si C=0 es negativo --> salta
   goto    error_circ   ; el tipo esta mal --> repetir mensaje
   
   movfw   unidades   ; el tipo esta bien, lo almacena
   movwf   circ      ; en tipo
   goto    finespera_circ
   
error_circ
            
            call   Borra_home
                  movlw   0x80            ;Direccion caracter
                call    LCD_REG                          
            call   Cursor_off
            call    MensCircInc
            call   PDelay      ; retardo 2 segundos
            call   Borra_home
      goto otracirc   ; vuelve a pedir el tipo
;****************************************************
fincalcula_circ
      movfw   teclapulsada
      call   hextoascii
      bsf     PORTA,2         ; activa LCD
      movfw   ASCII2
      call    LCD_DATOS       ; Visualiza caracter
finespera_circ
   return
;************************************************************************
ServicioInterrupcion
;   GUARDAR WREG, STATUS, FSR EN LA PILA
      MOVWF   GUARDA_W
      SWAPF   STATUS,W
      MOVWF   GUARDA_S   
      SWAPF    FSR,W
      MOVWF   GUARDA_FSR
      bcf         STATUS,RP0      ; banco 0
      btfss      PIR1,RCIF      ; ha sido por recepcion?
      goto       otras          ; no, mira otras interrupciones
      bcf         PIR1,RCIF      ; si, borra el bit de aviso
; escribimos en ram con direccionamiento indirecto
      call   escribeindir      ; pinta en pantalla lo recibido
   
      goto    finirq
otras      ; aqui ponemos las otras interrupciones   (teclado)
      bcf   STATUS,RP0   ;banco 0
   movlw   0x00
   subwf   flujo,0         ; mira a ver si es 0
   btfsc   STATUS,Z      ; si es velocidad (1) o circunstancia (2), salta
   goto    estaentipo
   
   movlw   0x01
   subwf   flujo,0         ; mira a ver si es 1
   btfss   STATUS,Z      ; si es velocidad (1), salta
   goto    estaencirc
   goto   estaenvel
estaentipo
      call   LeeTipo
      goto    finirq
estaenvel
      call     LeeVelocidad
      goto    finirq
estaencirc
      call   LeeCirc
      
      goto    finirq
finirq 
; RECUPERAMOS DE LA PILA
      MOVF   GUARDA_FSR,W
      MOVWF FSR
      SWAPF GUARDA_S,W
      MOVWF STATUS
      SWAPF   GUARDA_W,W
   retfie
      INCLUDE <MENSAJES_P.INC>
      INCLUDE <MICRO.INC>
      INCLUDE <CONVIERTE.INC>
      INCLUDE <LCD.INC>
      INCLUDE <RETARDOS.INC>
      INCLUDE <COMUNICACION.INC>
      INCLUDE <TECLADO_3X4.INC>
      INCLUDE <API.INC>
      INCLUDE <AT.INC>
      END