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

 
 
> Keil C51 прерывания
AndreyS
сообщение Aug 30 2012, 15:07
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 235
Регистрация: 28-01-05
Из: Санкт-Петербург
Пользователь №: 2 276



Добрый день.

Подскажите пожалуйста, как заставить Keil (проект на Си) не укладывать сохранение в стек регистров и соответственно не восстанавливать их из стека?

Пояснение:
Объявляю функцию с параметром interrupt 0 и в теле ее вызываю проверку с битовой переменной, если переменная возведена, то делаю прямой переход (через #pragma asm) на требуемый внешний обработчик. Если нет, то хочу отсюда выйти. В конце внешнего обработчика конечно стоит RETI (средствами Си, потому что этот внешний обработчик есть другая прошивка) и по нему прерывание нормально завершится. Но вот при такой конструкции Кеил упорно обрамляет вызов прерывания сохранением полного набора регистров в стек и соответственно его полного восставноления. Как это обрамление отключить??


--------------------
Удачи.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
редактор
сообщение Aug 31 2012, 06:44
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Для interrupt функций ВСЕГДА сохраняются регистры, опция usng 1 (2,3,0) лишь уменьшает их количество, поскольку сохраняет в стек регистр статуса и меняет банк, при выходе из функции банк восстанавливается. Остальные регистры сохраняются-восстанавливаются при необходимости. Выход из Interrupt функции осуществляется командой RETI. Все это делается для того, что бы при возвращении в основную программу оставить неизменными регистры, используемые в обработчике прерываний.

Для Interrupt функций компилятор делает следующее. По указанному вектору располагает команду перехода на функцию. В функции сохраняет используемые регистры (ACC, DPTR и т.д), переключает банк рабочих регистров (если есть опция USING) и выполняет тело функции.
По завершении функции все регистры восстанавливаются и выход осуществляется командой RETI.
поэтому ваш подход
Цитата
Объявляю функцию с параметром interrupt 0 и в теле ее вызываю проверку с битовой переменной, если переменная возведена, то делаю прямой переход (через #pragma asm) на требуемый внешний обработчик

в принципе не верен. Функцию надо объявлять без параметра interrupt. А если вы в функции проверяете именно флаг этого прерывания, то вообще непонятно зачем все так сложно. При возникновении прерывания, если оно разрешено, управление автоматически передается на соответствующий вектор. Если хотите работать по опросу, то после проверки флага надо вызывать обычную функцию.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
barabek
сообщение Aug 31 2012, 06:57
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(редактор @ Aug 31 2012, 16:44) *
поэтому ваш подход
в принципе не верен. Функцию надо объявлять без параметра interrupt.

Хм. Я ТС понял несколько иначе. Думаю, что битовая переменная у него имеется ввиду другая. И регистры, думаю, он имеет ввиду те, что не используются в прерывании, но все равно сохраняются. В общем, пусть он сам прокоментирует.
А вот про вызов внешней функции из прерывания Вы не зря сказали. Я и забыл про это, хотя ловился на этих граблях. При использованиии using настоятельно не рекомендую вызывать из прерывания другие функции. Можно нарваться. И если используются прерывания с разными приоритетами, то для них обязательно использовать using с разными банками.
Go to the top of the page
 
+Quote Post



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

 


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


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