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

 
 
4 страниц V  « < 2 3 4  
Reply to this topicStart new topic
> Хочется программно инициировать прерывание, Но не INT0/INT1, как бы погламурнее
singlskv
сообщение May 20 2008, 21:16
Сообщение #46


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ May 21 2008, 00:56) *
Насчет каждый такт на счету - не верю, не может каждый такт быть на счету для чего-то настолько длительного, что ест аж 4 периода таймера и в то же время настолько редкого, что происходит раз в 100 периодов таймера. Нестукуется с таким событием понятие каждый такт на счету.
Ну и почему же это не стыкуется ?
допустим хочу:
- передачу по SPI на максимальной скорости(кб этак 250-500 в сек) но при этом чтобы
джиттер был минимален и предсказуем
- опрос кнопок(типа процесс в 100 раз более медленный)
- запись в EEPROM когда надо(тоже не быстро).
- итд итп

ну и кто мешает это все совместить ?


Цитата(ReAl @ May 21 2008, 01:03) *
Кстати, я очень обижен на атмел в том, что битики force output compare у таймеров не вызывают соответствующее прерывание output compare :-(
А Вы ими пробовали вобще пользоваться ? (битиками)
я нет, поэтому и интересно...
но кстати таймером тож можно чего-нить такое намутить, тока топикстартер не сознается какие
узлы кроме комаратора у него еще не задействованны...
Go to the top of the page
 
+Quote Post
defunct
сообщение May 20 2008, 21:19
Сообщение #47


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ May 21 2008, 00:11) *
Ну и почему же это не стыкуется ?

Несктыкуется это событие (длиной в 4 периода таймера) с надобностью обработки в прерывании.

Цитата
допустим хочу:
- передачу по SPI на максимальной скорости(кб этак 250-500 в сек) но при этом чтобы
джиттер был минимален и предсказуем
- опрос кнопок(типа процесс в 100 раз более медленный)
- запись в EEPROM когда надо(тоже не быстро).
- итд итп

ну и кто мешает это все совместить ?

Ничто и не помешает все это совместить если обработку события длиной в 4 периода таймера кинуть в основной цикл.
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 20 2008, 21:35
Сообщение #48


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ May 21 2008, 01:19) *
Несктыкуется это событие (длиной в 4 периода таймера) с надобностью обработки в прерывании.
Ничто и не помешает все это совместить если обработку события длиной в 4 периода таймера кинуть в основной цикл.
А кто сказал что это событие обязательно нужно обработать за один присест ?
Вне зависимости от того где оно будет обрабатывться, всегда есть возможность
обработать его по частям.
Те просто делаем автомат обработки события с внутренним разбиением на части...

Те например пусть нам нужно записать X байт в EEPROM,
запись каждого байта это процесс который может растянуться на очень много периодов
нашего таймера, но у нас автомат который запустил запись X байтов и пока они все не записались
он не освободился.
Ну конечно если там голые рассчеты без всяких ожиданий то они конечно должны
жить в главном цикле...
Go to the top of the page
 
+Quote Post
galjoen
сообщение May 20 2008, 21:59
Сообщение #49


Знающий
****

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



Цитата(defunct @ May 21 2008, 01:19) *
Несктыкуется это событие (длиной в 4 периода таймера) с надобностью обработки в прерывании.

Тут прерывание ТОЛЬКО для того, чтоб приоритет этого события поднять, а основной цикл отдать кому то другому (на, делай в нём что хочешь, всё равно мне не навредишь).
Go to the top of the page
 
+Quote Post
defunct
сообщение May 20 2008, 23:30
Сообщение #50


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ May 21 2008, 00:35) *
Те просто делаем автомат обработки события с внутренним разбиением на части...

Ну так ведь ничто не мешает этот автомат сделать в основном цикле. Ввести там сколько надо приоритетов 10-100-1000 (на скоко памяти хватит) и следовать им.

Цитата
Тут прерывание ТОЛЬКО для того, чтоб приоритет этого события поднять

Если только для этого, то обрабатывать можно в том же прерывании, зачем еще одно плодить?
результат одинаковый будет.
Go to the top of the page
 
+Quote Post
Дон Амброзио
сообщение May 21 2008, 05:13
Сообщение #51


Местный
***

Группа: Участник*
Сообщений: 323
Регистрация: 11-02-08
Пользователь №: 34 947



У меня для "быстрых" потоков, которые должны вызваться не позднее одного тика таймера после возникновения Event-а, требующего их вмешательства, есть регистр , в котором каждый битик является Ready-флагом соответствующего потока. И перед выходом из ISR системного таймера я проверяю не стоит ли Ready-флажок какого-нить потока. Если стоит, то запускаю соответ.поток в порядке приоритета (от 7 к 0 )


--------------------
После устранения бага в программе она стала работать....хуже
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение May 21 2008, 05:44
Сообщение #52


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(defunct @ May 21 2008, 02:30) *
Ну так ведь ничто не мешает этот автомат сделать в основном цикле. Ввести там сколько надо приоритетов 10-100-1000 (на скоко памяти хватит) и следовать им.

Автоматами только в основном цикле, как правило, не обойтись. У меня обычно автоматы и на процессах в прерываниях.

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

__interrupt void low_priority_interrupt()
{ interrupt_no++;
if (interrupt_no>1) DISABLE_HIGH_PRIORITY_INTERRUPT();
__enable_interrupt();
...
}
Ну и попытка все устройства сделать на AVR , выжимая все соки? Даже в 8080 была система приоритетных прерываний, что других контроллеров не существует?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Rst7
сообщение May 21 2008, 05:48
Сообщение #53


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

Группа: Модераторы
Сообщений: 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
Сообщение #54


Знающий
****

Группа: Свой
Сообщений: 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
SasaVitebsk
сообщение May 21 2008, 07:15
Сообщение #55


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



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

В XMEGA будет проще данную проблему решать. smile.gif
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение May 21 2008, 07:23
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(SasaVitebsk @ May 21 2008, 10:15) *
Обсуждать подход автора, считаю глупым, так как он к нам за этим не обращался, к тому же постановка вопроса близка и понятна мне.

А поговорить? smile.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Rst7
сообщение May 21 2008, 07:37
Сообщение #57


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

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



Цитата
Зато прерывания от таймера вообще возникать не будут - уменьшение времени нахождения с запрещёнными прерываниями ну и красота.


В общем итоге - с запрещением через TIMSK хуже.

Цитата
В XMEGA будет проще данную проблему решать.


А то, там костыль есть для генерации эвентов вручную. О нас подумали wink.gif

Цитата
А поговорить?


Неси литру, поговорим smile.gif


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


Местный
***

Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530



Цитата(Rst7 @ May 21 2008, 08:48) *
В принципе, из-за того, что управление прерыванием доступно через SBI/CBI время нахождения в состоянии с запрещенным прерыванием даже уменьшилось... Красота только пропала wink.gif

Это уже есть мысль. Круто
Да и не сказалбы я что красота пропала
Есть в общем над чем поломать голову и поучиться a14.gif


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
galjoen
сообщение May 21 2008, 09:30
Сообщение #59


Знающий
****

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



М.б. конечно я уже надоел своим занудством, но...
Цитата(Rst7 @ May 21 2008, 11:37) *
В общем итоге - с запрещением через TIMSK хуже.

Мне вот это всё не нравится (некрасивым кажется):
Код
//   88   if (TASK3_LOCK) return; // вот это (лишних 12 тактов при возникновении прерывания от таймера при  TASK3_LOCK=1)
        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)(); // и ОСОБЕННО это (3+4=7 тактов лишних при КАЖДОМ вызове)
        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:

Всё это ведь сделано что-бы регистры при возникновении прерывания при TASK3_LOCK=1 не сохранялись. А если в прерывании от таймера __interrupt void использовать, а там и TASK3_LOCK=1 устанавливать (для INT0), и TIMSK запрещать (всего 3 такта лишних)? Вроде по всем параметрам лучше. Ну а главное красивее smile.gif .
Go to the top of the page
 
+Quote Post
Rst7
сообщение May 21 2008, 09:38
Сообщение #60


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

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



Цитата
Мне вот это всё не нравится (некрасивым кажется):


Ну попробуйте переделать. Рыба, которую я привел - она компилируется...


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

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 00:53
Рейтинг@Mail.ru


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