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

 
 
> Хочется программно инициировать прерывание, Но не 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 21 2008, 05:48
Сообщение #2


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

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



Ну вообщем, проверил на железе - не приводит к установке флага прерывания от компаратора дрыг режимом фронт/спад. Плохо, конечно. Пришлось перенести на прерывание от EEPROM и завести флаг запроса. Теперь это выглядит примерно так
Код
#define TASK2_LOCK GPIOR0_Bit0
#define TASK3_LOCK GPIOR0_Bit1
#define TASK2_WAKEUP GPIOR0_Bit2

#define DISABLE_TASK2() {EECR_EERIE=0;}
#define ENABLE_TASK2() {EECR_EERIE=1;}
#define WAKEUP_TASK2() {TASK2_WAKEUP=1;}

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


#pragma vector=EE_RDY_vect
__interrupt __raw void TASK2dispatch(void)
{
  DISABLE_TASK2();
  TASK2_LOCK=1;
  TASK2_WAKEUP=0;
  __enable_interrupt();
  ((void(*)(void))TASK2)();  
  __disable_interrupt();
  TASK2_LOCK=0;
  if (TASK2_WAKEUP) 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) return;
  if (TASK2_WAKEUP) 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 (TASK3_LOCK) return;
  if (TASK2_LOCK) return;
  if (TASK2_WAKEUP) ENABLE_TASK2();
}


И код
Код
        RSEG CODE:CODE:NOROOT(1)
//   48 __interrupt void TASK2(void)
TASK2:
//   49 {
        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
//   50   __no_operation();
        NOP
//   51   //....
//   52   //....много всякой долгой каки...
//   53   main(); //Например так
        RCALL   main
//   54   //....
//   55   __no_operation();
        NOP
//   56 }
        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
//   57 #pragma diag_default=Ta006
//   58
//   59
//   60 #pragma vector=EE_RDY_vect

        RSEG CODE:CODE:NOROOT(1)
//   61 __interrupt __raw void TASK2dispatch(void)
TASK2dispatch:
//   62 {
//   63   DISABLE_TASK2();
        CBI     0x1F, 0x03
//   64   TASK2_LOCK=1;
        SBI     0x1E, 0x00
//   65   TASK2_WAKEUP=0;
        CBI     0x1E, 0x02
//   66   __enable_interrupt();
        SEI
//   67   ((void(*)(void))TASK2)();  
        RCALL   TASK2
//   68   __disable_interrupt();
        CLI
//   69   TASK2_LOCK=0;
        CBI     0x1E, 0x00
//   70   if (TASK2_WAKEUP) ENABLE_TASK2();
        SBIC    0x1E, 0x02
        SBI     0x1F, 0x03
//   71 }
??TASK2dispatch_0:
        RETI
        REQUIRE _A_EECR
        REQUIRE _A_GPIOR0
//   72
//   73 #pragma diag_suppress=Ta006

        RSEG CODE:CODE:NOROOT(1)
//   74 __interrupt void TASK3(void)
TASK3:
//   75 {
//   76   __no_operation();
        NOP
//   77   //....
//   78   //....не очень много всякой долгой каки...
//   79   if (PINB_Bit0) WAKEUP_TASK2(); //К примеру
        SBIC    0x03, 0x00
        SBI     0x1E, 0x02
//   80   //....
//   81   __no_operation();
??TASK3_0:
        NOP
//   82 }
        RETI
        REQUIRE _A_GPIOR0
        REQUIRE _A_PINB
//   83 #pragma diag_default=Ta006
//   84
//   85 #pragma vector=TIMER0_OVF_vect

        RSEG CODE:CODE:NOROOT(1)
//   86 __interrupt __raw void TASK3dispatch(void)
TASK3dispatch:
//   87 {
//   88   if (TASK3_LOCK) return;
        SBIC    0x1E, 0x01
        RJMP    ??TASK3dispatch_0
//   89   TASK3_LOCK=1;
        SBI     0x1E, 0x01
//   90   DISABLE_TASK2();
        CBI     0x1F, 0x03
//   91   __enable_interrupt();
        SEI
//   92   ((void(*)(void))TASK3)();  
        RCALL   TASK3
//   93   __disable_interrupt();
        CLI
//   94   TASK3_LOCK=0;
        CBI     0x1E, 0x01
//   95   if (TASK2_LOCK) return;
        SBIC    0x1E, 0x00
        RJMP    ??TASK3dispatch_0
//   96   if (TASK2_WAKEUP) ENABLE_TASK2();
        SBIC    0x1E, 0x02
        SBI     0x1F, 0x03
??TASK3dispatch_0:
        RETI
        REQUIRE _A_EECR
        REQUIRE _A_GPIOR0
//   97 }
//   98
//   99 #pragma vector=INT0_vect

        RSEG CODE:CODE:NOROOT(1)
//  100 __interrupt void TASK4(void)
TASK4:
//  101 {
        ST      -Y, R17
        ST      -Y, R16
        IN      R17, 0x3F
//  102   //Тут тоже колдовство, запрещаем все прерывания, например
//  103   TIMSK0=0;
        LDI     R16, 0
        STS     110, R16
//  104   //Запрещаем и TASK2
//  105   DISABLE_TASK2();
        CBI     0x1F, 0x03
//  106   __enable_interrupt();
        SEI
//  107   //Чего-то делаем, тут еще бывает INT1, но это уже не суть
//  108   __disable_interrupt();
        CLI
//  109   if (PINB_Bit1) WAKEUP_TASK2(); //К примеру
        SBIC    0x03, 0x01
        SBI     0x1E, 0x02
//  110   TIMSK0=1<<TOV0;
??TASK4_0:
        LDI     R16, 1
        STS     110, R16
//  111   if (TASK3_LOCK) return;
        SBIC    0x1E, 0x01
        RJMP    ??TASK4_1
//  112   if (TASK2_LOCK) return;
        SBIC    0x1E, 0x00
        RJMP    ??TASK4_1
//  113   if (TASK2_WAKEUP) ENABLE_TASK2();
        SBIC    0x1E, 0x02
        SBI     0x1F, 0x03
??TASK4_1:
        OUT     0x3F, R17
        LD      R16, Y+
        LD      R17, Y+
        RETI


В принципе, из-за того, что управление прерыванием доступно через SBI/CBI время нахождения в состоянии с запрещенным прерыванием даже уменьшилось... Красота только пропала wink.gif


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


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(Rst7 @ May 21 2008, 09:48) *
Код
#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) return;
  if (TASK2_WAKEUP) ENABLE_TASK2();
}

Не совсем понял вот этот кусок, поэтому м.б. задам глупый вопрос.
Код
  if (TASK3_LOCK) return;
  TASK3_LOCK=1;

Это видимо антирекурсия, так?
Почему вы, любитель красоты в программировании (я наверное такой-же) использовали для этого лишний бит (#define TASK3_LOCK GPIOR0_Bit1), а не сам бит разрешения прерывания TOIE0 из регистра TIMSK? Это из-за того, что в вашем процессоре он не доступен командами cbi, sbic и поэтому требует вспомогательного регистра (и его сохранения) в т.ч. для проверки в прерывании INT0? Зато прерывания от таймера вообще возникать не будут - уменьшение времени нахождения с запрещёнными прерываниями ну и красота.
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
- - Rst7   Давайте я попробую все-таки подробностей добавить....   May 20 2008, 16:29
|- - 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
|- - 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 Текстовая версия Сейчас: 19th July 2025 - 12:52
Рейтинг@Mail.ru


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