Перейти к содержанию
    

Хочется программно инициировать прерывание

Разрешили прерывание - получили прерывание.

 

Да не годится мне так. Мне нужно раздельное управление flag и enable. Так понятнее?

 

 

Руками сбросить в процедуре обработки прерывания - религия не позволяет?

 

Он не сбросится для EEPROM'а, единственный выход - запрещать, а мне так не годится...

 

 

Какой у Вас контроллер и какие ресурсы свободны?

 

Разные контроллеры. На данный момент ATMega168.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ICP используется ?

 

Занята. Да и дрыгать ножками не хотелось бы, они могут пригодиться для других целей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тут задача возникла следующего характера. Как бы инициировать прерывание программным путем?.............

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

У любого устройства в MK есть регистра флага - по которому и происходит прерывание ( устанавливается и сбрасывается программным путём в большинстве случаев) .

Но не понятно зачем Вам надо вызвать прерывание - зная, что оно точно произойдёт- затем, что-то сделать и при этом по сути прерывание не использовать . Не поняттно зачем при обработке (например входов порта) зачем-то дёрнуть прерывание компаратора или таймера или EEPROM и при этом узнать что pin1 порта установлен в 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне не нужно прерывание, запрос которого сам по себе устанавливается, мне нужно его запрос руками (программно) поднять только в нужный мне момент времени. Т.е. из более приоритетного прерывания запустить менее приоритетное после окончания обработки более приоритетного.

Так вроде с готовностью EEPROM всё хорошо получается. Только ещё флаг в ОЗУ нужно завести, а м.б. счётчик (от задачи зависит). В обработчике __interrupt void fast_irq(void) вместо if (....) SET_SLOW_IRQ(); пишите if (....) Счётчик++;, а в конце вместо if (!SLOW_IRQ_LOCK) ENABLE_SLOW_IRQ(); пишите if (!Счётчик) ENABLE_SLOW_IRQ();. А в обработчике __interrupt void slow_irq(void) в начале DISABLE_SLOW_IRQ() (==cbi EECR,EERIE), а в конце делаете Счётчик--; и ещё раз if (!Счётчик) ENABLE_SLOW_IRQ();

 

Ещё могу рекомендовать более экзотический способ: использования совпадений у таймеров/счётчиков. Там при обработке флаг прерывания сам сбрасывается.

 

2 Палыч

Чтобы прерывание от EEPROM возникло никакого чтения EEPROM делать не нужно. Оно сразу возникнет - после его разрешения (если в этот момент EEPROM не пишется/читается).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так вроде с готовностью EEPROM всё хорошо получается.

 

Тут следующий момент: счетчики надо инкрементировать/декрементировать с запрещенными прерываниями. Да еще и сохранять регистр SREG. К сожалению, это занимает слишком много времени, у меня тут жестко все...

 

Как-то не очень понятна вообще логика вопроса.

 

Логика Вашего текста тоже не ясна ни разу ;)

 

У любого устройства в MK есть регистра флага - по которому и происходит прерывание ( устанавливается и сбрасывается программным путём в большинстве случаев) .

 

Сбрасывается программным путем - да, устанавливается - нет. Из-за этого и весь сыр-бор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне не нужно прерывание, запрос которого сам по себе устанавливается, мне нужно его запрос руками (программно) поднять только в нужный мне момент времени. Т.е. из более приоритетного прерывания запустить менее приоритетное после окончания обработки более приоритетного.
Можно пойти таким путем - в конце более приоритетного прерывания закидывать в стек возврата адрес менее приоритетного прерывания. Правда, надо будет вставочку на асме соорудить, и после вставочки не должно буть, естественно, ни каких вызовов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтобы прерывание от EEPROM возникло никакого чтения EEPROM делать не нужно. Оно сразу возникнет - после его разрешения (если в этот момент EEPROM не пишется/читается).
Да, конечно! Это результат спешки... Вместо "делаете чтение" - "разрешаете прерывание"...

 

Счетчик предлагаете завести для подсчета числа разрешений прерывания?

 

2 Rst7

Почему запрещать прерывания - не годиться? Это равнозначно сбросу флага. Желаете иметь два "рычага" управления: разрешение прерывания и флаг? Ну, и аппетиты у Вас... Так, что из ресурсов свободно?

 

 

 

Можно пойти таким путем - в конце более приоритетного прерывания закидывать в стек возврата адрес менее приоритетного прерывания. Правда, надо будет вставочку на асме соорудить, и после вставочки не должно буть, естественно, ни каких вызовов.
Тагда уж и закидывание в стек адреса - не нужно: в конце процедуры обработки прерывания сделать вызов процедуры обработки другого прерывания. Но, автору вопроса понадобилось зачем-то настоящее прерывание

 

Тут следующий момент: счетчики надо инкрементировать/декрементировать с запрещенными прерываниями. Да еще и сохранять регистр SREG. К сожалению, это занимает слишком много времени, у меня тут жестко все...
Из-за этого - весь сыр-бор? Но, ведь запретить/разрешить прерывания - гораздо быстрее, чем вход/выход в/из прерывания...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

К сожалению, это занимает слишком много времени, у меня тут жестко все...

Кстати регистр можно сохранять в регистр адреса EEPROM EEARL (out 1 такт), или использовать его и EEARH как данные (в т.ч. командами cbi, sbi, sbic, sbis). Всегда так делаю у тех процессоров где они до 0x20.

А прерывание от 8ми битных таймеров/счётчиков по сравнению (если есть свободные) чем вас не устраивает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тут задача возникла следующего характера. Как бы инициировать прерывание программным путем?

3. А может кто гламурнее способ знает?

А почему так нельзя: RCALL INTERRUPTVECTOR? Вот вам и будет вызов прерывания программным путём.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все не годятся, причину объяснил выше.

Ну дык и устанавливайте руками - UDRIE = 1.

так же руками и убирайте - UDRIE = 0.

 

Вы вероятно не приняли во внимание, что прерывание можно сгенерить не только по условию события возбуждения прерывания, а и просто разрещением этого прерывания (с учетом, что все внешние факторы уже готовы сгененерить прерывание).. E.g. установить прерывание по уровню INT0, держать INT0 всегда в соотв уровне, а прерывание возбуждать не дерганием пина, а дерганием GIMSK.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я использую от таймера. У меня мега640 - там этих таймеров.... :)

 

    if(Flag.EnShow)    TIMSK0=2;                            // Выполнить прерывание

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сбрасывается программным путем - да, устанавливается - нет. Из-за этого и весь сыр-бор.

Зато маска чудесно контроллируется программным путем. Включать маску везде где нужно, тушить только в обработчике.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 GM - ты немного задачу не осознал. :)

 

Например я делаю 100 прерываний от таймера, а вот после сотого мне надо выполнить хороший кусок работы. За это время придёт 4 прерывания от таймера. Короче надо в прерывании от таймера, по какому-то событию вызвать другое прерывание. Прямой вызов - не проходит, надо чтобы из того вернулась и вошла в новое.

 

:) Короче не умею я объяснять. :) Пусть кто другой попробует.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Например я делаю 100 прерываний от таймера, а вот после сотого мне надо выполнить хороший кусок работы. За это время придёт 4 прерывания от таймера.

Не, такой пример не пойдет, разобъют сразу тупым и в тоже время справедливым вопросом - почему бы не выполнить хороший кусок работы в основном цикле программы. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...