Номер stc не может использоваться из-за крупного сбоя

, ,

Я использую stc8a8k64d4, скачал с официального сайта программу, установил, но всё равно не могу использовать большие номера прерываний. В чём проблема? Ниже приведена ошибка:

*** ERROR L121: НЕПРАВИЛЬНОЕ ИСПРАВЛЕНИЕ (FIXUP)
МОДУЛЬ: .\Objects\main.obj (MAIN)
СМЕЩЕНИЕ: 0001C4H
Размер программы: data=18.3 xdata=1048 const=0 code=5874
Цель не создана.
Время сборки истекло: 00:00:00

Используйте официальное расширение для прерывания соединения на сайте

Видя вашу ошибку ERROR L121: IMPROPER FIXUP, эта проблема очень типична для Keil при работе с большими номерами прерываний (свыше 31) у микроконтроллеров STC.

Простыми словами: компилятор C51 в Keil изначально поддерживает только номера прерываний от 0 до 31. Вы используете STC8A8K64D4, где некоторые прерывания (например, UART2, UART3, UART4 или PCA) часто имеют номер больше 31 — и если указать их напрямую, возникает данная ошибка.

Вы упомянули, что уже использовали «программу расширения номеров прерываний» с официального сайта, но ошибка всё ещё появляется. Обычно это происходит потому, что процедура выполнена не полностью. Ниже я предложу два решения. Рекомендую сначала попробовать решение 1 (если вы уже устанавливали программу, вероятнее всего, вы просто неправильно её вызвали).


Решение 1: Правильное использование официального инструмента 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). Проверьте, исчезла ли ошибка.

Решение 2: Ручной переход через ассемблер (самый надёжный «жёсткий» способ)

Если после выполнения первого решения ошибка остаётся, возможно, инструмент расширения не сработал из-за прав системы и т.п. В этом случае рекомендуется использовать переход через ассемблер — самый надёжный метод, не зависящий от патчей компилятора.

Пример кода:

Допустим, ваша функция прерывания изначально была такой (предположим, номер прерывания 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
    __endasm;
}

Ключевые моменты:

  • Имя функции в ассемблере должно начинаться с подчёркивания: _UART4_ISR (компилятор C51 автоматически добавляет подчёркивание перед именами функций в ассемблере).
  • Если используется линковщик LX51, синтаксис немного отличается, но приведённый выше способ универсален для Keil.

Рекомендации

  1. Сначала зайдите в STC-ISP и повторно нажмите «Добавить модель и заголовочные файлы», убедитесь, что путь указан правильно (должен вести в корневую папку Keil).
  2. Если ошибка сохраняется, не тратьте время на диагностику инструмента, сразу переходите к решению 2 (переход через ассемблер). Да, этот способ требует на несколько строк кода больше, но он гарантированно избавит вас от ошибки L121, отлично переносится между проектами, и именно его используют многие опытные разработчики STC.

Братан, не спеши, ошибка L121: IMPROPER FIXUP при использовании больших номеров прерываний в серии STC8 — это очень распространённая проблема. Даже если вы установили официальный плагин расширения номеров прерываний, скорее всего, внутренние настройки 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 установлен на разных дисках), то официальный патч мог быть применён к той папке, которую вы фактически не используете.

  • Решение: Убедитесь, что путь, куда был распакован патч, соответствует корневой директории той версии Keil, которую вы сейчас используете (особенно проверьте, были ли корректно заменены файлы компилятора в папке C51\\BIN).

3. Слишком старая версия Keil C51

Официальный патч расширения номеров прерываний имеет определённые требования к версии Keil. Если ваша версия слишком старая (например, ниже v9.54), даже после установки патча ассемблер может не распознавать адреса смещений для больших прерываний.

  • Решение: Рекомендуется обновить Keil C51 до версии v9.60 или выше.

4. Проблема из-за остаточных файлов сборки

Иногда после установки патча старые файлы .obj могут мешать процессу линковки.

  • Решение: Не нажимайте просто «Build», а выберите «Rebuild All», чтобы полностью очистить старые объектные файлы и перекомпилировать проект с нуля.

Сначала попробуйте первый шаг — переключение на LX51. Если не поможет, сделайте скриншот окна «магической палочки», особенно вкладок Target и Device, и покажите его — посмотрим, в чём может быть дело.