Ви не увійшли.
Сделайте код прерывания более простым, максимально быстро выполняющимся. Если нужно в прерывании сделать много вычислений долго обслуживат экран - выставьте флаг, а в основном цикле его опрашивайте - как только флаг будет установлен - выполняйте свои вычисления обслуживайте экран.
не хочется нагружать лишней "работой" цикл опроса энкодера.
Эвона как Вы все наоборот сделали. Энкодер установите на прерывания и не опрашивайте. Нельзя не нагружать лишней "работой", процессор не многоядерный, если есть какая-то нагрузка она будет выполнена в ущерб основной работе, в прерывании она или нет. И в данном случае чтобы не пропускать отсчеты енкодера единственный выход - сам енкодер поставить на прерывания.
ARM - настраивайте приоритеты прерываний как Вам будет угодно, например Teensy, RedBearLab BLE Nano и др.
То, что вы хотите сделать называется вложенными прерываниями. Программная дипетчеризация вложенных прерываний не лучшее и не самое простое решение. Для этого делают аппаратную поддержку, как в ATxmega или ARM. Обычно, такие ресурсоемкие функции, как графические, не размещают в теле обработчиков прерываний, а выполняют в основном процессе, синхронизируя с таймером если нужно. Выполненние обработчиков прерываний, при плоской модели (без вложенных), должно быть быстрым и длительность выполнения самого динного сегмента кода должна быть меньше самой маленькой допустимой задержки обслуживания других прервываний. Иначе события будут потеряны. Что бы ваша программа работала правильно вам придется все-таки усложнить основной цикл.
Привет, есть устройство, мотор с энкодером и LCD. Экран обслуживается по прерыванию таймера счетчика 1 примерно каждые 0.3 секунды.
Я решил проверить точность подсчета импульсов энкодера, параллельно к энкодеру я подключил счетчик на семисегментных индикаторах и выяснялось, что показания разные, я начал копать и понял, что при заходе в прерывание аппаратно сбрасывается 7 бит SREG (запрет глобальных прерываний). То есть когда заходит в прерывания по таймеру счетчику перестают обслуживаться прерывание INT0, отсюда и ошибка подсчета. Вопрос в том можно (уместно) разрешать глобальные прерывания из прерывания таймера счетчика 1?
ISR(TIMER1_COMPA_vect)
{
sei();
}
Или лучше будет написать код обслуживания LCD как подпрограмму и заходить в нею по счетчику на переменной, что честно сказать меня смущает, не хочется нагружать лишней "работой" цикл опроса энкодера.