I’m using the STC8A8K64D4. I downloaded the software from the official website and installed it properly, but I still can’t use large interrupt numbers. What’s wrong? Here’s the error message:
*** ERROR L121: IMPROPER FIXUP
MODULE: .\Objects\main.obj (MAIN)
OFFSET: 0001C4H
Program Size: data=18.3 xdata=1048 const=0 code=5874
Target not created.
Build Time Elapsed: 00:00:00
Seeing your error message ERROR L121: IMPROPER FIXUP, this is a classic issue in Keil when handling large interrupt numbers (greater than 31) on STC microcontrollers.
In short: Keil’s C51 compiler natively only supports interrupt numbers 0–31. You’re using the STC8A8K64D4, where certain interrupts (such as UART2, UART3, UART4, or PCA) often have numbers greater than 31. Using them directly will trigger this error.
You mentioned you’ve already used the official “interrupt number extension tool”, but still get the error. This usually happens because the setup steps weren’t fully completed correctly. I’ll give you two solutions—start with Solution 1 (if you’ve already installed the tool, the issue is likely that it wasn’t properly applied).
Solution 1: Correctly Use STC’s Official “Interrupt Vector Number Extension Tool”
The STC-ISP software includes this tool. Many users think that just “installing” it is enough, but in reality, you must either launch Keil through this tool before each compilation, or ensure it has replaced/patched system files.
Locate the tool: Open the STC-ISP software, go to the right-hand panel and click on “Keil Simulation Settings”. There you’ll find a button labeled “Add MCU model and header files to Keil”.
Note: This step doesn’t just add the MCU model—it also automatically installs the plugin for extended interrupt support.
Re-add it once more: Regardless of whether you’ve done this before, click the button again, select your Keil installation directory (e.g., C:\Keil_v5), and confirm.
Verify the patch: After successful installation, navigate to your Keil directory, specifically the \\Keil\\C51\\BIN folder. Look for C51.EXE. If the extension was successfully applied, STC should have replaced or patched this file with a version that supports larger interrupt numbers.
Rebuild the project: Close Keil, reopen your project, and click Rebuild (not just Build). Check if the error persists.
Solution 2: Manual Assembly Jump (The Most Reliable “Hard Fix” Method)
If you still get the error after trying Solution 1, the extension tool may not have taken effect due to system permissions or other issues. In this case, use an assembly-level jump, which is the most reliable method and does not depend on compiler patches.
Example:
Suppose your original interrupt function was written like this (assuming interrupt number 46):
// 1. Main interrupt function body: defined as a normal function without 'interrupt'
void UART4_ISR(void)
{
// Your original interrupt handling code (unchanged)
}
// 2. Set up a jump in assembly: map the interrupt vector address to the actual function
void UART4_ISR_Entry(void) interrupt 46
{
// Inline assembly to jump to the real function
__asm
LJMP _UART4_ISR
__endasm;
}
Key Points:
The function name in assembly must include an underscore prefix: _UART4_ISR (C functions are prefixed with an underscore in compiled assembly).
If you’re using the LX51 linker, syntax may vary slightly, but the above approach works universally in Keil.
Summary & Recommendations
First, go back to STC-ISP and re-run the “Add MCU model and header files” step, making sure you selected the correct root directory of your Keil installation.
If the error still occurs, stop troubleshooting the tool and immediately switch to Solution 2 (assembly jump). Although it adds a few lines of code, this method will never cause the L121 error, offers excellent portability, and is widely used by experienced STC developers.
Brother, don’t panic. The L121: IMPROPER FIXUP error is very common when using large interrupt numbers in the STC8 series. Even though you’ve installed the official interrupt number extension plugin, the issue most likely lies within Keil’s internal settings not being properly configured.
Please check the following possible causes in order:
1. Not switched to the Extended Linker (LX51) — Most Common Cause
The default BL51 linker in Keil C51 has poor support for interrupts above number 31 and is highly prone to triggering the L121 error.
Solution: Click the “magic wand” icon in Keil (Options for Target) → go to the Device tab → check the option Use Extended Linker (LX51) instead of BL51. Then perform a full Rebuild All. In 90% of cases, this will solve the problem immediately.
2. Plugin installed into the wrong Keil directory
If you have multiple versions of Keil installed (e.g., MDK-ARM and C51 co-installed, or installations on different drives), the official patch might have been applied to a directory that isn’t currently in use.
Solution: Verify that the patch was extracted to the Keil root directory you’re actually using—especially confirm that the compiler files inside the C51\\BIN folder have been correctly replaced.
3. Keil C51 version too old
The official interrupt number extension patch has minimum version requirements. If your Keil version is too outdated (e.g., earlier than v9.54), the underlying assembler may fail to recognize the offset addresses of large interrupts, even after applying the patch.
Solution: Upgrade Keil C51 to version v9.60 or later.
4. Compilation leftovers causing interference
Sometimes, after applying the patch, old .obj files can interfere with the linking process.
Solution: Don’t just click “Build”—use “Rebuild All” to completely clean up old files and recompile from scratch.
Start by trying step 1 (switching to LX51). If it still doesn’t work, please take a screenshot of the Target and Device tabs in the Options for Target window and share it for further inspection.