реклама на сайте
подробности

 
 
> Хочется программно инициировать прерывание, Но не INT0/INT1, как бы погламурнее
Rst7
сообщение May 20 2008, 11:52
Сообщение #1


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



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

Самый простой способ - использовать 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. А может кто гламурнее способ знает?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Rst7
сообщение May 20 2008, 16:29
Сообщение #2


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Давайте я попробую все-таки подробностей добавить.

Есть 4 задачи. В порядке возрастания приоритетов:

1. Основной поток (тот который main()). На данный момент там банальный for(;;). Чего там будет, я пока не знаю, и поэтому, этот поток трогать мне нельзя.
2. Задача обработки. Длительная, выполняется намного дольше, чем промежуток между вызовами задач 3,4. Во время выполнения должны уметь получать управление задачи 3,4, причем с минимальным временем отклика (особенно 4). Запуск задачи происходит от события. По окончанию обработки задача засыпает до следующего события.
3. Задача - не самое приоритетное прерывание. От таймера, но вызывается часто - 256/512 тактов. В задаче - по быстренькому опрос периферии и по результатам - возможна генерация события для задачи 2. Во время выполнения этой задачи необходимо обеспечить возможность быстрого реагирования на прерывание для задачи 4.
4. Самое приоритетное прерывание. Входит, выполняет дело, по результатам дела генерирует или не генерирует событие, выходит.

Да, забыл. Задача 1 тоже потом может будет генерить события для задачи 2, а может и не будет.

Для такого менеджмента задач идеально использовать RTOS, но есть одно но - пока переключаются контексты поезд задачи 4 уходит далеко - в смысле, время реакции не устраивает. Значит, надо делать подобие RTOS, но с минимальными временами нахождения в состояниях c запретом прерываний.

План у меня таков - задача 2 - это обработчик прерывания, запрос на выполнение которого я могу создать в любой момент (это генерация события), а вот обработать - только тогда, когда не выполняются задачи 3 или 4 (и не находимся внутри задачи 2, дабы не допустить вложенности). Для этого мне и необходимо раздельное управление флагом запроса и битом разрешения прерывания.

Вариант со счетчиком плохо проходит в связи с тем, что увеличение/уменьшение счетчика требует сохранения SREG (с последующим восстановлением) и работу с самим счетчиком до разрешения прерываний.


Вот примерно такой код
Код
#define TASK2_LOCK GPIOR0_Bit0
#define TASK3_LOCK GPIOR0_Bit1

#define DISABLE_TASK2() {asm("PUSH R16");ACSR=(1<<ACD)|(1<<ACIS1);asm("POP R16");}
#define ENABLE_TASK2() {asm("PUSH R16");ACSR=(1<<ACD)|(1<<ACIS1)|(1<<ACIE);asm("POP R16");}
#define WAKEUP_TASK2() {ACSR=(1<<ACD)|(1<<ACIS1)|(1<<ACIS0);}

#pragma diag_suppress=Ta006
__interrupt void TASK2(void)
{
  __no_operation();
  //....
  //....много всякой долгой каки...
  main(); //Например так
  //....
  __no_operation();
}
#pragma diag_default=Ta006


#pragma vector=ANA_COMP_vect
__interrupt __raw void TASK2dispatch(void)
{
  DISABLE_TASK2();
  TASK2_LOCK=1;
  __enable_interrupt();
  ((void(*)(void))TASK2)();  
  __disable_interrupt();
  TASK2_LOCK=0;
  ENABLE_TASK2();
}

#pragma diag_suppress=Ta006
__interrupt void TASK3(void)
{
  __no_operation();
  //....
  //....не очень много всякой долгой каки...
  if (PINB_Bit0) WAKEUP_TASK2(); //К примеру
  //....
  __no_operation();
}
#pragma diag_default=Ta006

#pragma vector=TIMER0_OVF_vect
__interrupt __raw void TASK3dispatch(void)
{
  if (TASK3_LOCK) return;
  TASK3_LOCK=1;
  DISABLE_TASK2();
  __enable_interrupt();
  ((void(*)(void))TASK3)();  
  __disable_interrupt();
  TASK3_LOCK=0;
  if (!TASK2_LOCK) ENABLE_TASK2();
}

#pragma vector=INT0_vect
__interrupt void TASK4(void)
{
  //Тут тоже колдовство, запрещаем все прерывания, например
  TIMSK0=0;
  //Запрещаем и TASK2
  DISABLE_TASK2();
  __enable_interrupt();
  //Чего-то делаем, тут еще бывает INT1, но это уже не суть
  __disable_interrupt();
  if (PINB_Bit1) WAKEUP_TASK2(); //К примеру
  TIMSK0=1<<TOV0;
  if (!TASK2_LOCK) ENABLE_TASK2();
}


А вот чего выходит после компилятора
Код
        RSEG CODE:CODE:NOROOT(1)
//  176 __interrupt void TASK2(void)
TASK2:
//  177 {
        ST      -Y, R24
        ST      -Y, R31
        ST      -Y, R30
        ST      -Y, R3
        ST      -Y, R2
        ST      -Y, R1
        ST      -Y, R0
        ST      -Y, R23
        ST      -Y, R22
        ST      -Y, R21
        ST      -Y, R20
        ST      -Y, R19
        ST      -Y, R18
        ST      -Y, R17
        ST      -Y, R16
        IN      R24, 0x3F
//  178   __no_operation();
        NOP
//  179   //....
//  180   //....много всякой долгой каки...
//  181   main(); //Например так
        RCALL   main
//  182   //....
//  183   __no_operation();
        NOP
//  184 }
        OUT     0x3F, R24
        LD      R16, Y+
        LD      R17, Y+
        LD      R18, Y+
        LD      R19, Y+
        LD      R20, Y+
        LD      R21, Y+
        LD      R22, Y+
        LD      R23, Y+
        LD      R0, Y+
        LD      R1, Y+
        LD      R2, Y+
        LD      R3, Y+
        LD      R30, Y+
        LD      R31, Y+
        LD      R24, Y+
        RETI
//  185 #pragma diag_default=Ta006
//  186
//  187
//  188 #pragma vector=ANA_COMP_vect

        RSEG CODE:CODE:NOROOT(1)
//  189 __interrupt __raw void TASK2dispatch(void)
TASK2dispatch:
//  190 {
//  191   DISABLE_TASK2();
        PUSH R16
        LDI     R16, 130
        OUT     0x30, R16
        POP R16
//  192   TASK2_LOCK=1;
        SBI     0x1E, 0x00
//  193   __enable_interrupt();
        SEI
//  194   ((void(*)(void))TASK2)();  
        RCALL   TASK2
//  195   __disable_interrupt();
        CLI
//  196   TASK2_LOCK=0;
        CBI     0x1E, 0x00
//  197   ENABLE_TASK2();
        PUSH R16
        LDI     R16, 138
        OUT     0x30, R16
        POP R16
//  198 }
        RETI
        REQUIRE _A_ACSR
        REQUIRE _A_GPIOR0
//  199
//  200 #pragma diag_suppress=Ta006

        RSEG CODE:CODE:NOROOT(1)
//  201 __interrupt void TASK3(void)
TASK3:
//  202 {
        ST      -Y, R16
//  203   __no_operation();
        NOP
//  204   //....
//  205   //....не очень много всякой долгой каки...
//  206   if (PINB_Bit0) WAKEUP_TASK2(); //К примеру
        SBIS    0x03, 0x00
        RJMP    ??TASK3_0
        LDI     R16, 131
        OUT     0x30, R16
//  207   //....
//  208   __no_operation();
??TASK3_0:
        NOP
//  209 }
        LD      R16, Y+
        RETI
        REQUIRE _A_ACSR
        REQUIRE _A_PINB
//  210 #pragma diag_default=Ta006
//  211
//  212 #pragma vector=TIMER0_OVF_vect

        RSEG CODE:CODE:NOROOT(1)
//  213 __interrupt __raw void TASK3dispatch(void)
TASK3dispatch:
//  214 {
//  215   if (TASK3_LOCK) return;
        SBIC    0x1E, 0x01
        RJMP    ??TASK3dispatch_0
//  216   TASK3_LOCK=1;
        SBI     0x1E, 0x01
//  217   DISABLE_TASK2();
        PUSH R16
        LDI     R16, 130
        OUT     0x30, R16
        POP R16
//  218   __enable_interrupt();
        SEI
//  219   ((void(*)(void))TASK3)();  
        RCALL   TASK3
//  220   __disable_interrupt();
        CLI
//  221   TASK3_LOCK=0;
        CBI     0x1E, 0x01
//  221   if (!TASK2_LOCK) ENABLE_TASK2();
        SBIC    0x1E, 0x00
        RJMP    ??TASK3dispatch_0
        PUSH R16
        LDI     R16, 138
        OUT     0x30, R16
        POP R16
??TASK3dispatch_0:
        RETI
        REQUIRE _A_ACSR
        REQUIRE _A_GPIOR0
//  222 }
//  223
//  224 #pragma vector=INT0_vect

        RSEG CODE:CODE:NOROOT(1)
//  225 __interrupt void TASK4(void)
TASK4:
//  226 {
        ST      -Y, R17
        ST      -Y, R16
        IN      R17, 0x3F
//  227   //Тут тоже колдовство, запрещаем все прерывания, например
//  228   TIMSK0=0;
        LDI     R16, 0
        STS     110, R16
//  229   //Запрещаем и TASK2
//  230   DISABLE_TASK2();
        PUSH R16
        LDI     R16, 130
        OUT     0x30, R16
        POP R16
//  231   __enable_interrupt();
        SEI
//  232   //Чего-то делаем, тут еще бывает INT1, но это уже не суть
//  233   __disable_interrupt();
        CLI
//  234   if (PINB_Bit1) WAKEUP_TASK2(); //К примеру
        SBIS    0x03, 0x01
        RJMP    ??TASK4_0
        LDI     R16, 131
        OUT     0x30, R16
//  235   TIMSK0=1<<TOV0;
??TASK4_0:
        LDI     R16, 1
        STS     110, R16
//  236   if (!TASK2_LOCK) ENABLE_TASK2();
        SBIC    0x1E, 0x00
        RJMP    ??TASK4_1
        PUSH R16
        LDI     R16, 138
        OUT     0x30, R16
        POP R16
//  237 }
??TASK4_1:
        OUT     0x3F, R17
        LD      R16, Y+
        LD      R17, Y+
        RETI


Вариант с прерываниями хорош еще и тем, что в задаче 1 я могу выполнить WAKEUP_TASK2();ENABLE_TASK2() - и сразу полетит выполять задачу 2. Все приоритеты красиво соблюдаются.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Rst7   Хочется программно инициировать прерывание   May 20 2008, 11:52
- - prottoss   Цитата(Rst7 @ May 20 2008, 19:52) Тут зад...   May 20 2008, 11:58
- - VladimirYU   Цитата(Rst7 @ May 20 2008, 15:52) Тут зад...   May 20 2008, 11:58
- - prottoss   Цитата(Rst7 @ May 20 2008, 19:52) ,Вот мы...   May 20 2008, 12:01
|- - ReAl   Цитата(prottoss @ May 20 2008, 15:01) Как...   May 20 2008, 20:31
- - Rst7   ЦитатаА почему хочется именно пограммное прерывани...   May 20 2008, 12:12
- - sKWO   Цитата(Rst7 @ May 20 2008, 14:52) Тут зад...   May 20 2008, 12:16
- - galjoen   Цитата(Rst7 @ May 20 2008, 15:52) Тут зад...   May 20 2008, 12:25
- - Rst7   Цитатаа оно возникает когда пустой регистр данных ...   May 20 2008, 12:34
|- - Палыч   Не понятно, чем Вам не угодило прерывание от EEPRO...   May 20 2008, 13:01
|- - galjoen   Цитата(Rst7 @ May 20 2008, 16:34) Мне не ...   May 20 2008, 13:39
||- - Палыч   Цитата(galjoen @ May 20 2008, 16:39) Чтоб...   May 20 2008, 14:14
|- - prottoss   Цитата(Rst7 @ May 20 2008, 20:34) Мне не ...   May 20 2008, 13:53
- - Палыч   Цитата(Rst7 @ May 20 2008, 14:52) Тут зад...   May 20 2008, 12:44
- - Rst7   ЦитатаКак раз от компаратора в scmRTOS и использую...   May 20 2008, 12:52
|- - singlskv   Цитата(Rst7 @ May 20 2008, 16:52) Только ...   May 20 2008, 13:01
|- - &-rey   Цитата(Rst7 @ May 20 2008, 15:52) Ага, пр...   May 20 2008, 13:01
|- - defunct   Цитата(Rst7 @ May 20 2008, 15:52) Все не ...   May 20 2008, 15:03
- - Rst7   ЦитатаЕсли, память не используете, Использую. Кро...   May 20 2008, 13:03
|- - Палыч   Цитата(Rst7 @ May 20 2008, 16:03) Мне нуж...   May 20 2008, 13:09
- - Rst7   ЦитатаРазрешили прерывание - получили прерывание. ...   May 20 2008, 13:15
|- - &-rey   так и не понял, нога которая ICP используется ?   May 20 2008, 13:16
- - Rst7   ЦитатаICP используется ? Занята. Да и дрыгать нож...   May 20 2008, 13:24
- - ILYAUL   Цитата(Rst7 @ May 20 2008, 15:52) Тут зад...   May 20 2008, 13:31
- - Rst7   ЦитатаТак вроде с готовностью EEPROM всё хорошо по...   May 20 2008, 13:49
|- - galjoen   Цитата(Rst7 @ May 20 2008, 17:49) К сожал...   May 20 2008, 14:16
|- - defunct   Цитата(Rst7 @ May 20 2008, 16:49) Сбрасыв...   May 20 2008, 15:11
- - =GM=   Цитата(Rst7 @ May 20 2008, 10:52) Тут зад...   May 20 2008, 14:59
- - SasaVitebsk   Я использую от таймера. У меня мега640 - там этих ...   May 20 2008, 15:05
- - SasaVitebsk   2 GM - ты немного задачу не осознал. Например ...   May 20 2008, 15:11
|- - defunct   Цитата(SasaVitebsk @ May 20 2008, 18:11) ...   May 20 2008, 15:16
||- - galjoen   Цитата(defunct @ May 20 2008, 19:16) Не, ...   May 20 2008, 15:51
||- - Палыч   Цитата(galjoen @ May 20 2008, 18:51) Т.е....   May 20 2008, 16:08
|||- - galjoen   Цитата(Палыч @ May 20 2008, 20:08) Приори...   May 20 2008, 16:52
||- - defunct   Цитата(galjoen @ May 20 2008, 18:51) Не. ...   May 20 2008, 20:56
||- - singlskv   Цитата(defunct @ May 21 2008, 00:56) Насч...   May 20 2008, 21:16
||- - defunct   Цитата(singlskv @ May 21 2008, 00:11) Ну ...   May 20 2008, 21:19
||- - singlskv   Цитата(defunct @ May 21 2008, 01:19) Неск...   May 20 2008, 21:35
|||- - defunct   Цитата(singlskv @ May 21 2008, 00:35) Те ...   May 20 2008, 23:30
|||- - Dog Pawlowa   Цитата(defunct @ May 21 2008, 02:30) Ну т...   May 21 2008, 05:44
||- - galjoen   Цитата(defunct @ May 21 2008, 01:19) Неск...   May 20 2008, 21:59
|- - Палыч   Цитата(SasaVitebsk @ May 20 2008, 18:11) ...   May 20 2008, 15:19
|- - SasaVitebsk   Цитата(Палыч @ May 20 2008, 18:19) Почему...   May 20 2008, 15:35
|- - Палыч   Цитата(SasaVitebsk @ May 20 2008, 18:35) ...   May 20 2008, 15:41
- - _Pasha   Привет, телепаты 1. Какая у Вас мега в проекте? ...   May 20 2008, 16:04
- - SasaVitebsk   Вот уж не знаю как вам объяснить. Ещё раз...   May 20 2008, 16:12
|- - Палыч   Цитата(SasaVitebsk @ May 20 2008, 19:12) ...   May 20 2008, 16:34
|- - singlskv   Не знаю точно поможет ли это Вам в конкретной зада...   May 20 2008, 18:19
- - singlskv   Если свободен пин nSS(SPI SlaveSelect) я бы еще по...   May 20 2008, 20:50
- - ReAl   Кстати, я очень обижен на атмел в том, что битики ...   May 20 2008, 21:03
- - Дон Амброзио   У меня для "быстрых" потоков, которые до...   May 21 2008, 05:13
- - Rst7   Ну вообщем, проверил на железе - не приводит к уст...   May 21 2008, 05:48
|- - galjoen   Цитата(Rst7 @ May 21 2008, 09:48) Код#pra...   May 21 2008, 06:58
|- - sKWO   Цитата(Rst7 @ May 21 2008, 08:48) В принц...   May 21 2008, 08:21
- - SasaVitebsk   В принципе предложений накидали. Обсуждать подх...   May 21 2008, 07:15
|- - Dog Pawlowa   Цитата(SasaVitebsk @ May 21 2008, 10:15) ...   May 21 2008, 07:23
- - Rst7   ЦитатаЗато прерывания от таймера вообще возникать ...   May 21 2008, 07:37
|- - galjoen   М.б. конечно я уже надоел своим занудством, но... ...   May 21 2008, 09:30
- - Rst7   ЦитатаМне вот это всё не нравится (некрасивым каже...   May 21 2008, 09:38


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 11th August 2025 - 13:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.02301 секунд с 7
ELECTRONIX ©2004-2016