![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() ![]() |
![]() |
Diusha |
![]()
Сообщение
#1
|
Группа: Пользователи Сообщений: 4 Пол: Мужской Репутация: ![]() ![]() ![]() |
Программка (запускается под 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;" |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Хм... Навскидку - где занесение значения $20 в порт $20 в конце обработчика прерывания от COM-порта? Т.е., последней командой обработчика должно быть
Port[$20] := $20; Это первое... А второе, насколько я помню, в обработчиках прерываний с номерами меньшими $16, не должно быть вызовов процедур ввода-вывода Паскаля (равно, как и процедур дин. распределения памяти и вызовов функций операционной системы), так что лучше запоминай полученный байт в глобальной переменной, устанавливай глобальный же флажок "получено", и выходи из прерывания, а в основной программе (в цикле) проверяй состояние флажка "получено", и если он установлен - то печатай байт и снимай флажок. |
Diusha |
![]()
Сообщение
#3
|
Группа: Пользователи Сообщений: 4 Пол: Мужской Репутация: ![]() ![]() ![]() |
последней командой обработчика должно быть Port[$20] := $20; Да, про это мне уже сказали. Но пока до последней команды обработчика далеко; до 1-й бы добраться... ... в обработчиках прерываний с номерами меньшими $16, не должно быть вызовов процедур ввода-вывода Паскаля ... И про это мне тоже сказали уже. Только чем это может быть чревато? int_1c я сначала повесил на $08 (<$16) - из-под 98 работало нормально, а под досом висло. Но здесь-то причина подвисания, ИМХО, в другом: в том, что я тупо заменил стандартный обработчик своим. |
Lapp |
![]()
Сообщение
#4
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
до 1-й бы добраться... Diusha, я уже настолько прочно забыл это все, что помочь вряд ли смогу. Но я сейчас порылся и нашел свои старые проги (16 лет назад писано). Гарантия, что там все работало. Комментов не то, чтобы много, но все же есть чуток. Оформлено в виде юнита (даже вроде не одного).Нужно? -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
volvo |
![]()
Сообщение
#5
|
Гость ![]() |
Цитата И про это мне тоже сказали уже. Только чем это может быть чревато? Вышеперечисленные операции нереентерабельны, следовательно, если ты их используешь - то нарушается принцип "повторной входимости": работа процедуры прерывания может быть в любой момент прервана другими прерываниями. Что тогда будет в случае, если ты внутри своего обработчика используешь операцию, которая НЕреентерабельна? |
Diusha |
![]()
Сообщение
#6
|
Группа: Пользователи Сообщений: 4 Пол: Мужской Репутация: ![]() ![]() ![]() |
|
Lapp |
![]()
Сообщение
#7
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Нужно! Извиняюсь, ложная тревога. Главная часть - резидентная - была выполнена в виде отдельной программы, и она утеряна.. Юниты используют обращение к ней - их я аккуратно сохранил)). Вся фишка была в буферизации потока, для чего, собственно, и потребовался резидент. Именно он коммуницировал с com-портом, а юниты - только с ним.Я еще гляну в одном месте, но надежды мало.. Еще раз извини.. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Гость |
![]()
Сообщение
#8
|
Гость ![]() |
Может еще у кого-нибудь завалялось?
|
Diusha |
![]()
Сообщение
#9
|
Группа: Пользователи Сообщений: 4 Пол: Мужской Репутация: ![]() ![]() ![]() |
Всем спасибо! Вопрос решился
|
![]() ![]() |
![]() |
Текстовая версия | 17.07.2025 17:07 |