Я действительно не знаю, для какой конкретной PIC вы используете, но, как правило, во встроенных системах прерывания должны состоять из краткого лаконичного кода. Механизм прерываний вызовет этот код, и ожидается, что он завершится в течение короткого времени, так как другое прерывание может возникнуть и пропустить (даже один и тот же ISR). Таким образом, обычной практикой является небольшая обработка внутри обратного вызова ISR (например, пометка прерывания как посещенного) и изменение флага, помечающего, что прерывание было сгенерировано, и выполнение большей части работы в main()
или другая функция. Это не всегда возможно, так как это похоже на пул, а не на обратный вызов, но это характерно для микроконтроллеров низкого уровня.
Помимо кода, большого для ISR, вы должны избегать вызова других функций внутри обратного вызова прерывания из-за накладных расходов, которые он добавляет. Кроме того, в данном конкретном случае вы используете оператор модуля %
, который подразумевает деление: если PIC не имеет аппаратного делителя, это действительно медленная операция.
Что вам нужно сделать, это переместить код внутри ISR void interrupt interrupcao ()
в другую функцию и оставить только код, который должен изменить регистр внутри нее, и пометить, что прерывание было снято. Затем проверьте этот флаг внутри основного цикла и выполните обработку.
Еще одна вещь, которая когда-то все испортила, когда обратный вызов прерывания был длинным, это пространство, физическая память, которая была назначена функции. Увеличение его размера привело к переполнению кода в другое пространство прерываний; но я сомневаюсь, что это случилось с вами, так как я видел только кодирование в ассемблере (компилятор поместит код в нужное место, но я не знаю, как вы компилируете;)).