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

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

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

 

Самый простой способ - использовать INT0, например, и сконфигурировать прерывание по изменению состояния ноги (нога на вывод), в результате - достаточно шевельнуть ножкой (изменив ее, скажем OUT'ом в PINx) и флаг прерывания установится; соответственно, когда будет разрешено прерывание INT0 - оно и произойдет. Но, к сожалению, INT0 и INT1 заняты, надо изобретать что-то другое.

 

Вот мысль появилась использовать прерывание от компаратора, причем следующим образом:

 

Компаратор штатно выключен (он не нужен в проекте), для установки флага прерывания от него использовать последовательность

ACSR=(1<<ACD)|(1<<ACIS1)|(1<<ACIS0); //Comparator Interrupt on Rising Output Edge.
ACSR=(1<<ACD)|(1<<ACIS1); //Comparator Interrupt on Falling Output Edge.

 

Т.е. переключить туда-сюда "по фронту/по спаду". На идею натолкнула фраза

When changing the ACIS1/ACIS0 bits, the Analog Comparator Interrupt must be disabled by clearing its Interrupt Enable bit in the ACSR Register. Otherwise an interrupt can occur when the bits are changed.

в даташите.

 

К сожалению, сейчас негде попробовать этот чит. Посему пара вопросов:

 

1. Может кто делал такое и уже знает результат?

2. Может у кого есть под рукой макеточка, проверить бы?

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

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


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

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

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


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

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

 

Самый простой способ - использовать INT0, например, и сконфигурировать прерывание по изменению состояния ноги (нога на вывод), в результате - достаточно шевельнуть ножкой (изменив ее, скажем OUT'ом в PINx) и флаг прерывания установится; соответственно, когда будет разрешено прерывание INT0 - оно и произойдет. Но, к сожалению, INT0 и INT1 заняты, надо изобретать что-то другое.

 

Вот мысль появилась использовать прерывание от компаратора, причем следующим образом:

 

Компаратор штатно выключен (он не нужен в проекте), для установки флага прерывания от него использовать последовательность

ACSR=(1<<ACD)|(1<<ACIS1)|(1<<ACIS0); //Comparator Interrupt on Rising Output Edge.
ACSR=(1<<ACD)|(1<<ACIS1); //Comparator Interrupt on Falling Output Edge.

 

Т.е. переключить туда-сюда "по фронту/по спаду". На идею натолкнула фраза

 

в даташите.

 

К сожалению, сейчас негде попробовать этот чит. Посему пара вопросов:

 

1. Может кто делал такое и уже знает результат?

2. Может у кого есть под рукой макеточка, проверить бы?

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

 

А почему хочется именно пограммное прерывание, почему нелзя обычный вызов обработчика.

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


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

,Вот мысль появилась использовать прерывание от компаратора
Как раз от компаратора в scmRTOS и используют, но вроде как внешне что то к выводу компаратора припаивать надо... Лучше обратиться к первоисточнику. К сожалению адреса не знаю - но по моему в форуме про RTOS тема травой не заростает.

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


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

А почему хочется именно пограммное прерывание, почему нелзя обычный вызов обработчика.

 

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

 

Как бы так объяснить, нафиг это надо... Ну типа эмуляция прерываний с приоритетом...

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


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

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

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

USART_UDRE_vect   /* USART, Data Register Empty */

а оно возникает когда пустой регистр данных передатчика УСАП

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


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

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

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

А использование прерывания от EEPROM не будет гламурным способом?

1. Думаю, что его никто не использует. По крайней мере я - ни разу.

2. Разрешается одной командой sbi EECR,EERIE.

3. Генерируется всё время пока EEWE сброшен (EEPROM не пишется).

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


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

а оно возникает когда пустой регистр данных передатчика УСАП

 

Занято, и кроме того, как и следующий вариант

 

А использование прерывания от EEPROM не будет гламурным способом?

 

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

 

Ну нечто такое:

 

__interrupt void slow_irq(void)
{
  DISABLE_SLOW_IRQ();
  SLOW_IRQ_LOCK=1;
  __enable_interrupt();
  ....
  ....много всякой долгой каки...
  ....
  __disable_interrupt();
  SLOW_IRQ_LOCK=0;
  ENABLE_SLOW_IRQ();
}

__interrupt void fast_irq(void)
{
  DISABLE_SLOW_IRQ();
  __enable_interrupt();
  ....
  ....
  ....
  if (....) SET_SLOW_IRQ();
  ....
  ....
  __disable_interrupt();
  if (!SLOW_IRQ_LOCK) ENABLE_SLOW_IRQ();
}

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


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

Тут задача возникла следующего характера. Как бы инициировать прерывание программным путем?... Но, к сожалению, INT0 и INT1 заняты, надо изобретать что-то другое.
ИМХО, в начале нужно определиться - какие ресурсы у Вас свободны? В зависимости от используемого МК можно, наверное, использовать

INT0-INT7

EEPROM Ready

USART0 Data Register Empty

USART1 Data Register Empty

SPM Ready

 

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

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


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

Как раз от компаратора в scmRTOS и используют

 

Ага, прерыванием от компаратора и пользуются. Щас посмотрел в сорсы. Только raise делается ногодрыгом. А у меня эти лапы заняты.

 

INT0-INT7

Всего 2, оба заняты

EEPROM Ready

USART0 Data Register Empty

USART1 Data Register Empty

SPM Ready

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

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


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

Не понятно, чем Вам не угодило прерывание от EEPROM. Если, память не используете, то "ручками" делаете чтение, и получаете прерывание. Не чуть не хуже дрыгания ногой для получения INTx.

 

Так какие ресурсы у Вас свободны? Как вариант - использование прерывания от свободного таймера. Настроить его на работу без прескалера с генерацией прерывания по одному тику. Разрешили прерывание - получили прерывание.

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


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

Только raise делается ногодрыгом. А у меня эти лапы заняты.
А какие ноги свободные ? (если есть конечно)

и что из переферии не задействованно ?

и какой чип ?

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


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

Ага, прерыванием от компаратора и пользуются. Щас посмотрел в сорсы. Только raise делается ногодрыгом. А у меня эти лапы заняты.

Всего 2, оба заняты

 

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

 ICR ?

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


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

Если, память не используете,

Использую.

 

Кроме того, "The EEPROM Ready interrupt generates a constant interrupt

when EEPE is cleared."

 

Т.е. пока EEPE очищен, прерывание генерируется. А мне так не годится. Мне нужно флаг установить, а сбросится он при выполнении процедуры прерывания.

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


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

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

 

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

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


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

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

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

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

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

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

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

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

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

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