stc大中断号无法使用

, ,

我使用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 官方的“中断向量号扩展工具”

STC-ISP 软件自带了这个工具,很多人以为“安装了”就行,实际上每次编译前都需要通过它来启动 Keil,或者需要替换系统文件。

  1. 找到工具:打开 STC-ISP 软件,点击右侧栏的“Keil 仿真设置”,里面有一个按钮 “添加型号和头文件到 Keil 中”
    • 注意:这个操作不仅会添加型号,还会自动处理中断号扩展的插件。
  2. 重新添加一次:不管你之前是否添加过,再次点击这个按钮,选择你的 Keil 安装目录(例如 C:\Keil_v5),确认添加。
  3. 验证插件:添加成功后,进入你的 Keil 工程目录,找到 \Keil\C51\BIN 文件夹,里面应该有一个 C51.EXE。如果扩展成功,实际上 STC 已经用一个支持大中断号的 C51.EXE 替换或打补丁了。
  4. 重新编译:关闭 Keil,重新打开你的项目,点击 Rebuild(不要只点 Build),看是否还报错。

方案二:手动汇编跳转(最稳妥的“硬解”方法)

如果方案一操作后依然报错,说明扩展工具可能因为系统权限等原因没生效。此时建议使用汇编跳转,这是最可靠、不依赖编译器补丁的方法。

写法示例
假设你的中断函数原本是这样写的(这里假设中断号是 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 中通用。

总结建议

  1. 先去 STC-ISP 重新“添加型号和头文件”,确保路径选对(一定要选到 Keil 的根目录)。
  2. 如果还是报错,不要再纠结工具,直接用方案二(汇编跳转)。这种方法虽然看起来多了几行代码,但永远不会出现 L121 错误,而且移植性最好,很多 STC 老手都这么写。

兄弟别急,STC8系列用大中断报 L121: IMPROPER FIXUP 这个错太常见了。虽然你用了官方的中断号扩展插件,但大概率是 Keil 内部的设置没跟上。

你可以按顺序排查以下几个最可能的原因:

1. 没有切换到扩展链接器(LX51)—— 最常见原因

Keil C51 默认的 BL51 链接器对31号以上的大中断支持很差,极易报 L121 错误。

  • 解决办法: 点击 Keil 的“魔术棒”图标(Options for Target) → 找到 Device 选项卡 → 勾选上 Use Extended Linker (LX51) instead of BL51。然后再重新 Rebuild All 试试,90%的情况下这招能秒杀。

2. 插件安装到了错误的 Keil 路径

如果你电脑上装了多个版本的 Keil(比如 MDK-ARM 和 C51 混装,或者不同盘各装了一个),官方扩展补丁可能打到了没在用的那个目录里。

  • 解决办法: 确认补丁释放的路径是你当前正在使用的 Keil 根目录(特别是 C51\BIN 文件夹里的编译器文件是否被正确替换)。

3. Keil C51 版本过低

官方的中断号扩展补丁对 Keil 的版本有一定要求。如果你的 Keil 版本太老(比如低于 v9.54),即使打了补丁,底层的汇编器也可能认不出大中断的偏移地址。

  • 解决办法: 建议将 Keil C51 升级到 v9.60 或以上版本。

4. 编译残留物导致

有时候打完补丁后,旧的 .obj 文件会干扰链接。

  • 解决办法: 不要点“Build”,点击 “Rebuild All” 彻底清理旧文件重新编译一次。

你先试试第一步切换 LX51,如果还不行,建议截个魔术棒 Target 和 Device 的图发上来看看。