Аппаратное Прерывание

Тема в разделе "Arduino & Shields", создана пользователем Евгений Сапронов, 8 авг 2018.

  1. Что будет , если при выполнении прерывания сработает оно же само?(выполняется INT1 и сработало то же INT1)
     
  2. b707

    b707 Гуру

    второе прерывание будет пропущено.
    поэтому и рекомендуют в самом коде прерывания ничего долгого не делать, например только выставлять переменную, что прерывание сработало, а все остальное - в основной программе.
     
    Igor68 и arkadyf нравится это.
  3. Airbus

    Airbus Радиохулиган Модератор

    Оно само не сработает ибо есть блок.Но может сработать другое имеющее больший приоритет.Например Int0.Тут 2 путя или как сказал b707 или сразу блокировать ВСЕ прерывания командой cli по бырому выполнить код и выйти из прерывания.
     
    arkadyf нравится это.
  4. Долго ли происходит обход If?(если условия не подходят)?
     
  5. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    ви таки код выложите на форум. а там и посоветовать можно) зачем вам if в обработчике прерываний? флаг взвели в обработчике, вышли и бегом ловить следующее прерывание. а по флагу в основном цикле хоть иифами хоть чем можно запроверяться. я так думаю
     
    arkadyf нравится это.
  6. b707

    b707 Гуру

    если стоит вопрос скорости - не должно быть никаких условий в прерывании...
     
    arkadyf нравится это.
  7. Lemurs

    Lemurs Нуб

    у меня вот такая конструкция отлично работает, это генерация импульсов для спидометра, количество импульсов достигает вроде до 600000 в секунду, сейчас уже не помню, но около того

    Код (C++):
    ISR(TIMER1_OVF_vect){
      TCNT1 = TCNT1_PRELOAD; // preload timer

      unsigned long currentMicros = micros();
      if (currentMicros < VelocityLastUpdate) VelocityLastUpdate = 1000000 - VelocityLastUpdate;
      if ((currentMicros - VelocityLastUpdate) > VelosityImpuls) // пришло время обновляться
      {
        VelocityLastUpdate = currentMicros;
        digitalWrite(6, HIGH);
        myCounter++;
      } else {
        digitalWrite(6, LOW);
      }
    }
     
    прикольно наблюдать работу мультиметром, подсоединить его к пину, чем больше импульсов тем больше вольтаж показывает.
     
  8. Daniil

    Daniil Гуру

    См. ассемблер и даташиты.
    Обычно ассемблерные команды выполняются за 1 такт (но не все), надосмотреть во что компилируется этот if и посчитать (особенно если в ифе вычисляется какое-то выражение).
     
    Igor68 и Mitrandir нравится это.
  9. parovoZZ

    parovoZZ Гуру

    Оно встанет в очередь, если оно разрешено и разрешены глобальные прерывания. Если прерывания запрещены, то просто поднимется флаг.
    При выходе из текущего прерывания МК выполнит до 4 операция в программе и только потом войдет в следующее прерывание в очереди.
    Если воля Аллаха такова, что за один такт пришло одновременно более одного прерывания, то они встанут в очередь по возрастанию адресов.
    Наивысший приоритет у ресета. По нему МК всегда уходит на нулевой адрес, где бы он сейчас не находился. А что делать? По ресету обнуляются все регистры, включая программный счетчик. Ну и ОЗУ, конечно же.
     
    arkadyf нравится это.
  10. parovoZZ

    parovoZZ Гуру

    Ни асм, ни даташит здесь вообще не при чем. Читать апноуты как правильно и эффективно программировать на СИ (где-то выигрышнее case, где-то if else - в апноуте все расписано. На русском искать на gaw.ru) и смотреть дизасм в дебаге.
     
    arkadyf нравится это.
  11. Возможно ошибаюсь не видя всего кода. Но такое очучение, что это какойто способ организовать многопоточность. Видно автор кода учел время исполнения обработчика. 600000 импульсов думаю вряд ли)
    Если очень нужно, засеките время миллис или микросом на входе в обработчик и на выходе потом из разницы можно понять ща сколько выполнился один цикл. Я так думаю
     
    Последнее редактирование: 9 авг 2018
  12. Igor68

    Igor68 Гуру

    Это Вы верно заметили... АСМ будет ВСЕГДА!!! ВСЕГДА!!! ВСЕГДА!!! быстрее всех!!!!!! Но... но знание архитектуры... и ещё для каждого применяемого ядра - это не в пузырёк пукать! А про IF точно не скажу, если это одиночный IF. Но если IF; ELSE IF, то выгоднее применять SWITCH; CASE... это я про Си. Дело в том (мои наблюдения), что при выполнении CASE параметр загружается в регистр 1 раз и потом идёт сравнение(совпадение) условий, а при IF значение(опорное) загружается каждый раз. Конечно IF более гибкое, чем CASE SWITCH... но и более медленное, потому как лишний раз идёт обращение к памяти. А если обращение к параметру INT32? Надо обратиться 4 раза. Так, что если приспичило выбирайте параметр в разрядность одного обращения к памяти. Как пример ADUC4024 одно обращение к памяти 16-бит. А ядро 32 бита. Для ускорения (в прерывании FIQ (не IRQ)) я применял разрядность не INT (что по умолчанию для ARM есть 32бита), а принудительно указывал uint16_t. Это значительно ускорило работу в прерывании (выбор из массива и загрузка в регистр ШИМ). А если учесть, что в прерывании он переходит в ARM режим (не THUMB) то и чтение инструкций(кода) происходит за два обращения (это Вам не Cortex).
     
    arkadyf, ИгорьК и Lemurs нравится это.
  13. parovoZZ

    parovoZZ Гуру

  14. Airbus

    Airbus Радиохулиган Модератор

    Switch Case вешь хорошая!Мне ее не хватает в LUA там только If/else.
     
  15. Igor68

    Igor68 Гуру

    В LUA нет таких требований в скорости... подобно быстро что-то делать в прерывании:)