我使用stc8a8k64d4,在官网下了那个软件,也安装好了,但是还是无法使用大中断号,啥毛病啊下面是报错
*** 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
我使用stc8a8k64d4,在官网下了那个软件,也安装好了,但是还是无法使用大中断号,啥毛病啊下面是报错
*** 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
就用的那个官网中断号扩展软件
看到你的报错信息 ERROR L121: IMPROPER FIXUP,这个问题在 Keil 中处理 STC 单片机的大中断号(超过 31)时非常经典。
简单来说:Keil 的 C51 编译器原生只支持 0-31 的中断号。你使用的是 STC8A8K64D4,其中一些中断号(如串口 2、3、4 或 PCA 等)往往大于 31,直接写就会报这个错。
你提到已经用了官网的“中断号扩展软件”,但依然报错,通常是因为步骤没完全走对。我给你两个解决方案,推荐先试方案一(如果已经装过软件,大概率是没正确调用)。
STC-ISP 软件自带了这个工具,很多人以为“安装了”就行,实际上每次编译前都需要通过它来启动 Keil,或者需要替换系统文件。
C:\Keil_v5),确认添加。\Keil\C51\BIN 文件夹,里面应该有一个 C51.EXE。如果扩展成功,实际上 STC 已经用一个支持大中断号的 C51.EXE 替换或打补丁了。如果方案一操作后依然报错,说明扩展工具可能因为系统权限等原因没生效。此时建议使用汇编跳转,这是最可靠、不依赖编译器补丁的方法。
写法示例:
假设你的中断函数原本是这样写的(这里假设中断号是 46):
void UART4_ISR(void) interrupt 46
{
// 你的中断处理代码
}
改为这样写:
// 1. 中断函数本体:不加 interrupt 关键字,用普通函数
void UART4_ISR(void)
{
// 你的中断处理代码(原封不动)
}
// 2. 在汇编区设置跳转:将中断向量地址映射到上面的函数
void UART4_ISR_Entry(void) interrupt 46
{
// 内嵌汇编,跳转到真正的函数
__asm
LJMP _UART4_ISR
__asm
}
关键点:
_UART4_ISR(C 函数编译后在汇编中前面会加一个下划线)。LX51 链接器,语法稍有不同,但上述写法在 Keil 中通用。兄弟别急,STC8系列用大中断报 L121: IMPROPER FIXUP 这个错太常见了。虽然你用了官方的中断号扩展插件,但大概率是 Keil 内部的设置没跟上。
你可以按顺序排查以下几个最可能的原因:
1. 没有切换到扩展链接器(LX51)—— 最常见原因
Keil C51 默认的 BL51 链接器对31号以上的大中断支持很差,极易报 L121 错误。
Device 选项卡 → 勾选上 Use Extended Linker (LX51) instead of BL51。然后再重新 Rebuild All 试试,90%的情况下这招能秒杀。2. 插件安装到了错误的 Keil 路径
如果你电脑上装了多个版本的 Keil(比如 MDK-ARM 和 C51 混装,或者不同盘各装了一个),官方扩展补丁可能打到了没在用的那个目录里。
C51\BIN 文件夹里的编译器文件是否被正确替换)。3. Keil C51 版本过低
官方的中断号扩展补丁对 Keil 的版本有一定要求。如果你的 Keil 版本太老(比如低于 v9.54),即使打了补丁,底层的汇编器也可能认不出大中断的偏移地址。
4. 编译残留物导致
有时候打完补丁后,旧的 .obj 文件会干扰链接。
你先试试第一步切换 LX51,如果还不行,建议截个魔术棒 Target 和 Device 的图发上来看看。