IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Хочу прерывание на Паскале от СОМ-порта, (Турбо Паскаль)
Diusha
сообщение 27.05.2009 7:53
Сообщение #1





Группа: Пользователи
Сообщений: 4
Пол: Мужской

Репутация: -  0  +


Программка (запускается под DOS, Win98):


Код

Uses crt, dos;

Label Finish, ll00;

Const
  baud = 38400;
  COM=$3F8 { $2F8 };
  intr=$0C { $0B };

Var
  stv, srv : pointer;
  cnt : word;
  b : byte;
  key : char;
  speed_fr : word;

{----------------------------------------------------------------------------------}
{$F+}
Procedure int_1c; interrupt;
  Begin
    inc(cnt);
    if cnt=18 then begin cnt:=0; write ('g') end;
  End;
{$F-}
{-----------------------------------------------------------------------------------}
{$F+}
Procedure int_rs; interrupt;
  Begin
    b:=port[COM];
    write (b,' ');
  End;
{$F-}
{----------------------------------------------------------------------------------}

BEGIN
  speed_fr:=trunc(115200/baud+0.5);
  port[COM+3]:=$80; { ўЄ«. гбв ­®ўЄ бЄ®p®бвЁ }
  port[COM+1]:=hi(speed_fr); port[COM+0]:=lo(speed_fr);
  port[COM+3]:=$00; { 5 bit, 1 stop, parity=none }
  port[COM+4]:=0;
  port[COM+2]:=$03; { FIFO on }
  port[COM+1]:=$01; { interrupt when rec'd data is available }

  getintvec($1C,stv);
  getintvec(intr,srv);

  cnt:=0;
  setintvec($1C,addr(int_1c));
  setintvec(intr,addr(int_rs));

ll00 :
  if keypressed then begin
    key:=readkey;
    goto Finish;
  end;

{  b:=port[COM+5]; }
{  if (b and $01)<>0 then begin }
{    b:=port[COM]; }
{    write (b,' '); }
{  end; }

  goto ll00;

Finish :
  setintvec($1C,stv);
  setintvec(intr,srv);
  halt;
END.



Процедурка int_1c - для тренировки - раз в сек пишет "g"; работает. По ее образу и подобию - int_rs - должна нaпечатать принятые с СОМ данные. Не работает. Что не так?
Порт настраивается нормально, в этом легко убедиться раскомментировав 5 строчек выше "goto ll00;"
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 27.05.2009 10:22
Сообщение #2


Гость






Хм... Навскидку - где занесение значения $20 в порт $20 в конце обработчика прерывания от COM-порта? Т.е., последней командой обработчика должно быть
Port[$20] := $20;


Это первое... А второе, насколько я помню, в обработчиках прерываний с номерами меньшими $16, не должно быть вызовов процедур ввода-вывода Паскаля (равно, как и процедур дин. распределения памяти и вызовов функций операционной системы), так что лучше запоминай полученный байт в глобальной переменной, устанавливай глобальный же флажок "получено", и выходи из прерывания, а в основной программе (в цикле) проверяй состояние флажка "получено", и если он установлен - то печатай байт и снимай флажок.
 К началу страницы 
+ Ответить 
Diusha
сообщение 27.05.2009 12:58
Сообщение #3





Группа: Пользователи
Сообщений: 4
Пол: Мужской

Репутация: -  0  +


Цитата(volvo @ 27.05.2009 10:22) *

последней командой обработчика должно быть
Port[$20] := $20;


Да, про это мне уже сказали. Но пока до последней команды обработчика далеко; до 1-й бы добраться...

Цитата(volvo @ 27.05.2009 10:22) *

... в обработчиках прерываний с номерами меньшими $16, не должно быть вызовов процедур ввода-вывода Паскаля ...

И про это мне тоже сказали уже. Только чем это может быть чревато?
int_1c я сначала повесил на $08 (<$16) - из-под 98 работало нормально, а под досом висло. Но здесь-то причина подвисания, ИМХО, в другом: в том, что я тупо заменил стандартный обработчик своим.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Lapp
сообщение 27.05.2009 13:23
Сообщение #4


Уникум
*******

Группа: Модераторы
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Diusha @ 27.05.2009 13:58) *
до 1-й бы добраться...
Diusha, я уже настолько прочно забыл это все, что помочь вряд ли смогу. Но я сейчас порылся и нашел свои старые проги (16 лет назад писано). Гарантия, что там все работало. Комментов не то, чтобы много, но все же есть чуток. Оформлено в виде юнита (даже вроде не одного).
Нужно?


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 27.05.2009 13:35
Сообщение #5


Гость






Цитата
И про это мне тоже сказали уже. Только чем это может быть чревато?
Вышеперечисленные операции нереентерабельны, следовательно, если ты их используешь - то нарушается принцип "повторной входимости": работа процедуры прерывания может быть в любой момент прервана другими прерываниями. Что тогда будет в случае, если ты внутри своего обработчика используешь операцию, которая НЕреентерабельна?
 К началу страницы 
+ Ответить 
Diusha
сообщение 27.05.2009 18:11
Сообщение #6





Группа: Пользователи
Сообщений: 4
Пол: Мужской

Репутация: -  0  +


Цитата(Lapp @ 27.05.2009 13:23) *

[Нужно?

Нужно!
<cut>
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Lapp
сообщение 28.05.2009 13:28
Сообщение #7


Уникум
*******

Группа: Модераторы
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Diusha @ 27.05.2009 19:11) *
Нужно!
Извиняюсь, ложная тревога. Главная часть - резидентная - была выполнена в виде отдельной программы, и она утеряна.. Юниты используют обращение к ней - их я аккуратно сохранил)). Вся фишка была в буферизации потока, для чего, собственно, и потребовался резидент. Именно он коммуницировал с com-портом, а юниты - только с ним.

Я еще гляну в одном месте, но надежды мало.. Еще раз извини..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Гость
сообщение 30.05.2009 11:13
Сообщение #8


Гость






Может еще у кого-нибудь завалялось?
 К началу страницы 
+ Ответить 
Diusha
сообщение 30.05.2009 17:54
Сообщение #9





Группа: Пользователи
Сообщений: 4
Пол: Мужской

Репутация: -  0  +


Всем спасибо! Вопрос решился
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 17.07.2025 5:45
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"