|
Замена обработчика прерывания в WinAVR |
|
|
|
Dec 16 2008, 04:23
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Нужно использовать различные обработчики прерывания в зависимости от случая. Например в начале программы обработчик_пр = функция 1 Код ISR(INT1_vect) { обработчик_пр } а затем где-то по далее необходимо заменить его на обработчик_пр = функция 2 Как это грамотно сделать в WinAVR?
--------------------
Если все, то не я...
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 14)
|
Dec 16 2008, 06:13
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(MrYuran @ Dec 16 2008, 09:59)  Определить указатель на функцию и поставить его в тело обработчика прерывания. Указателю между делом можно присваивать адреса разных функций. Издержки - команда CALL в теле обработчика прерываний. Зато задержка будет фиксированной и независимой от условий, как в случае switch или if/else. +1 Кстати это очень удобно. Код //Прототипы функций void isr1(void); void isr2(void); //Указатель на функцию обработчик void (* cur_isr)(void) = isr1;
void isr1(void) { // тело обработчика 1 }
void isr2(void) { // тело обработчика 2 }
ISR(INT1_vect) { (* cur_isr)(); }
int main(void) { // ля-ля тополя... ... cur_isr = isr2; ... }
--------------------
Если все, то не я...
|
|
|
|
|
Dec 16 2008, 07:49
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(PhX @ Dec 16 2008, 08:13)  Код int main(void) { // ля-ля тополя... ... cur_isr = isr2; ... } Оно, конечно, "само собой разумеется", но cur_isr = isr2; надо в атомарный блок взять.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Dec 16 2008, 09:19
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Векторизация прерываний. Например, int1 Soft_vectors.S Код #include <avr/io.h> .extern vector_int1 .global INT1_vect INT1_vect: push r30 in r30,SREG push r30 push r31 lds r30,vector_int1 lds r31,(vector_int1+1) icall pop r31 pop r30 out SREG,r30 pop r30 reti Просто добавьте в проект...
|
|
|
|
|
Dec 16 2008, 09:19
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(ReAl @ Dec 16 2008, 11:49)  Оно, конечно, "само собой разумеется", но cur_isr = isr2; надо в атомарный блок взять. А как это сделать? Цитата Вызов функции по указателю внутри обработчика ведет к сохранению ВСЕХ регистров в стеке. И восстановлению их при выходе. Не быстрый обработчик получается Ну хоть как-то. Не очень хорошо конечно, но что делать. Может есть способ лучше? Правда, в мем случае, быстродействия достаточно.
--------------------
Если все, то не я...
|
|
|
|
|
Dec 16 2008, 10:23
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(_Pasha @ Dec 16 2008, 12:19)  Векторизация прерываний. Например, int1 Soft_vectors.S Код #include <avr/io.h> .extern vector_int1 .global INT1_vect INT1_vect: push r30 in r30,SREG push r30 push r31 lds r30,vector_int1 lds r31,(vector_int1+1) icall pop r31 pop r30 out SREG,r30 pop r30 reti Просто добавьте в проект... Что вам такого плохого сделали люди, что бы советовать им такую гадость???? Компилятор не просто так сохраняет r0, r1 и call-used регстры. Если их не сохранять то программа не будет работать. Анатолий.
|
|
|
|
|
Dec 16 2008, 11:24
|
Местный
  
Группа: Участник
Сообщений: 205
Регистрация: 8-03-05
Пользователь №: 3 146

|
А в своем теле функция никакие регистры не использует? Даже r24? ИМХО можно так делать, если вызываемые функции написать на ассемблере (проанализировать листинг) и самостоятельно сохранять регистры. Кстати Ваш ужас реализуется куда короче и с правильным сохранением: Код SYGNAL(SIG_INTERRUPT1){ asm("icall"::"z"(vector_int1); }
|
|
|
|
|
Dec 16 2008, 17:04
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
в некоторых случаях можно делать перезапись векторов прямо во flash... правда, при условии, что это будет достаточно редко... очень редко  а если достаточно всего пары вариантов обработчиков - то можно манипулировать IVSEL, переключая таблицы... все эти варианты - не для любого AVR, разумеется...
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|