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

Йа моск ;)
     
Группа: Модераторы
Сообщений: 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. А может кто гламурнее способ знает?
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
 |
Ответов
|
May 21 2008, 05:48
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 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 время нахождения в состоянии с запрещенным прерыванием даже уменьшилось... Красота только пропала
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
May 21 2008, 06:58
|
Знающий
   
Группа: Свой
Сообщений: 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? Зато прерывания от таймера вообще возникать не будут - уменьшение времени нахождения с запрещёнными прерываниями ну и красота.
|
|
|
|
Сообщений в этой теме
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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|