No se puede usar el número de interrupción STC

, ,

Estoy usando el STC8A8K64D4, descargué el software desde el sitio oficial e instalé todo correctamente, pero aún así no puedo usar los números de interrupción grandes. ¿Qué problema puede ser? Abajo se muestra el error:

*** ERROR L121: IMPROPER FIXUP
MÓDULO: .\Objects\main.obj (MAIN)
DESPLAZAMIENTO: 0001C4H
Tamaño del programa: data=18.3 xdata=1048 const=0 code=5874
No se creó el destino.
Tiempo de compilación transcurrido: 00:00:00

Usa ese software de extensión de número interrumpido del sitio web oficial.

Viendo tu mensaje de error ERROR L121: IMPROPER FIXUP, este problema es muy clásico en Keil cuando se manejan números de interrupción grandes (superiores a 31) en microcontroladores STC.

En resumen: el compilador C51 de Keil solo soporta nativamente números de interrupción del 0 al 31. Estás utilizando el modelo STC8A8K64D4, cuyos periféricos (como UART2, UART3, UART4 o PCA) suelen tener números de interrupción mayores que 31. Si intentas usarlos directamente, aparecerá este error.

Mencionas que ya has usado el “software oficial de extensión de número de interrupción”, pero aún así aparece el error. Esto generalmente ocurre porque no se han seguido todos los pasos correctamente. A continuación te ofrezco dos soluciones. Te recomiendo probar primero la solución 1 (si ya instalaste el software, probablemente no lo estés usando adecuadamente).


Solución 1: Usar correctamente la herramienta oficial de “extensión de vectores de interrupción” de STC

El software STC-ISP incluye esta herramienta. Muchos creen que con “instalarla” basta, pero en realidad es necesario iniciar Keil a través de ella antes de cada compilación, o bien reemplazar ciertos archivos del sistema.

  1. Localizar la herramienta: Abre el software STC-ISP y haz clic en “Configuración de simulación Keil” en el panel derecho. Allí encontrarás un botón llamado “Agregar modelo y archivo de cabecera a Keil”.
    • Nota: Esta acción no solo agrega el modelo, sino que también instala automáticamente el complemento para extender los números de interrupción.
  2. Volver a agregarlo: Incluso si ya lo hiciste antes, vuelve a hacer clic en este botón y selecciona el directorio de instalación de Keil (por ejemplo, C:\Keil_v5), luego confirma.
  3. Verificar el complemento: Tras la instalación exitosa, ve al directorio de tu proyecto Keil y abre la carpeta \\Keil\\C51\\BIN. Deberías ver allí un archivo C51.EXE. Si la extensión funcionó, STC ya habrá reemplazado (o parcheado) este archivo con una versión que soporta números de interrupción grandes.
  4. Recompilar: Cierra Keil, vuelve a abrir tu proyecto y haz clic en Rebuild (no solo Build). Verifica si el error persiste.

Solución 2: Saltos mediante ensamblador (método fiable y directo)

Si tras aplicar la solución 1 sigue apareciendo el error, significa que la herramienta de extensión no funcionó (posiblemente por problemas de permisos del sistema). En ese caso, se recomienda usar saltos mediante código ensamblador, que es el método más confiable y que no depende de parches del compilador.

Ejemplo de implementación:

Supongamos que originalmente escribiste la función de interrupción así (con número de interrupción 46):

void UART4_ISR(void) interrupt 46
{
    // Tu código de manejo de interrupción
}

Debes cambiarlo así:

// 1. Función principal de interrupción: sin la palabra clave 'interrupt', como función normal
void UART4_ISR(void) 
{
    // Tu código de manejo de interrupción (sin cambios)
}

// 2. Crear un punto de entrada en ensamblador: mapear el vector de interrupción a la función anterior
void UART4_ISR_Entry(void) interrupt 46
{
    // Código embebido en ensamblador: salta a la función real
    __asm
        LJMP _UART4_ISR
    __endasm
}

Puntos clave:

  • El nombre de la función en ensamblador debe llevar un guion bajo: _UART4_ISR (el compilador C añade un guion bajo al nombre de las funciones C en el nivel de ensamblador).
  • Si usas el enlazador LX51, la sintaxis puede variar ligeramente, pero el método mostrado arriba es ampliamente compatible con Keil.

Recomendaciones finales

  1. Vuelve a ejecutar en STC-ISP la opción “Agregar modelo y archivo de cabecera a Keil”, asegurándote de seleccionar correctamente la ruta raíz de Keil.
  2. Si el error persiste, deja de intentar arreglar la herramienta y aplica directamente la solución 2 (salto mediante ensamblador). Aunque parece que requiere más líneas de código, este método elimina completamente el error L121, es totalmente estable y tiene mejor portabilidad. Muchos desarrolladores expertos en STC lo utilizan habitualmente.

Hermano, no te preocupes, el error L121: IMPROPER FIXUP al usar grandes números de interrupción en la serie STC8 es muy común. Aunque hayas instalado el complemento oficial para extender los números de interrupción, lo más probable es que la configuración interna de Keil no esté correctamente ajustada.

Puedes revisar en orden las siguientes causas más probables:

1. No has cambiado al enlazador extendido (LX51) — Causa más frecuente

El enlazador predeterminado BL51 de Keil C51 tiene un soporte deficiente para interrupciones mayores al número 31, y fácilmente genera el error L121.

  • Solución: Haz clic en el ícono de la “varita mágica” en Keil (Options for Target) → Ve a la pestaña Device → Marca la casilla Use Extended Linker (LX51) instead of BL51. Luego vuelve a compilar todo nuevamente (“Rebuild All”). En el 90% de los casos, este paso resuelve el problema inmediatamente.

2. El complemento se instaló en una ruta incorrecta de Keil

Si tienes varias versiones de Keil instaladas en tu computadora (por ejemplo, MDK-ARM y C51 instalados juntos, o instalados en diferentes unidades), es posible que el parche oficial se haya aplicado en un directorio que no estás utilizando actualmente.

  • Solución: Verifica que la ruta donde se descomprimió el parche sea efectivamente el directorio raíz de Keil que estás usando (en especial, comprueba si los archivos del compilador en la carpeta C51\\BIN fueron reemplazados correctamente).

3. La versión de Keil C51 es demasiado antigua

El parche oficial para extensión de interrupciones requiere una versión mínima de Keil. Si tu versión es demasiado vieja (por ejemplo, anterior a la v9.54), incluso tras aplicar el parche, el ensamblador subyacente podría no reconocer las direcciones de desplazamiento para grandes interrupciones.

  • Solución: Te recomendamos actualizar Keil C51 a la versión v9.60 o superior.

4. Archivos temporales de compilación antiguos están interfiriendo

A veces, después de instalar el parche, los archivos .obj antiguos pueden interferir durante el proceso de enlazado.

  • Solución: No pulses solo “Build”, haz clic en “Rebuild All” para limpiar completamente todos los archivos generados previamente y volver a compilar desde cero.

Primero prueba el paso 1 (cambiar a LX51). Si aún así no funciona, te sugerimos tomar una captura de pantalla de la ventana “Target” y la pestaña “Device” en la varita mágica y compartirla para ayudarte mejor.