|
Хочу прерывание на Паскале от СОМ-порта, (Турбо Паскаль, не Дельфи) |
|
|
|
May 26 2009, 17:11
|
Вечный студент
   
Группа: Участник
Сообщений: 500
Регистрация: 11-09-06
Из: Питер
Пользователь №: 20 262

|
Программка (запускается под DOS, Win98): CODE 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 - должна непечатать принятые с СОМ данные. Не работает. Что не так? Порт настраивается нормально, в этом легко убедиться раскомментировав 5 строчек выше "goto ll00;"
Причина редактирования: Оформление цитаты исходника.
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
May 26 2009, 23:06
|

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

|
Цитата(Diusha @ May 26 2009, 20:11)  Не работает. Что не так? Write() нежелательно использовать внутри прерываний насколько помню. еще, если память не изменяет надо заботиться о контроллере прерываний самостоятельно тобиш записать 20h в port 20h в конце обработчика для аппаратных прерываний: Код procedure Vector0C_Handler;interrupt; begin .... обработка порта(ов) COM1/3 asm mov al, 20h out 20h, al end end; Цитата(SysRq @ May 26 2009, 20:34)  COM+4.. Попробуйте $0B вместо 0 Это не нужно. Мы ж мышку питать не собираемся.
|
|
|
|
|
May 27 2009, 04:20
|
Вечный студент
   
Группа: Участник
Сообщений: 500
Регистрация: 11-09-06
Из: Питер
Пользователь №: 20 262

|
Цитата(defunct @ May 27 2009, 02:06)  Write() нежелательно использовать внутри прерываний насколько помню. А почему? Цитата(defunct @ May 27 2009, 02:06)  ...записать 20h в port 20h в конце обработчика До начала бы добраться...
Сообщение отредактировал Diusha - May 27 2009, 04:20
|
|
|
|
|
May 27 2009, 08:52
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Прерывание от COM порта еще надо разрешить в контролере прерываний (предполагаю, что оно весит на IRQ3) Код port[$21] := port[$21] and $f7; Ну и про Код port[$20] := $20; в конце тоже забывать не надо
|
|
|
|
|
May 27 2009, 14:05
|

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

|
Цитата(vvs157 @ May 27 2009, 15:46)  И еще в USART чипе разрешить прохождение прерывание на контроллер Не USART, а UART. Ну и это уже делается. В код топикстартера хоть заглядывали? Цитата Проще взять готовую библитотеку для ДОС для работы с COM. Вот чего не надо делать, так это брать готовую г...о-библиотеку.
|
|
|
|
|
May 27 2009, 17:15
|
Вечный студент
   
Группа: Участник
Сообщений: 500
Регистрация: 11-09-06
Из: Питер
Пользователь №: 20 262

|
Цитата(XVR @ May 27 2009, 11:52)  Прерывание от COM порта еще надо разрешить в контролере прерываний (предполагаю, что оно весит на IRQ3) Код port[$21] := port[$21] and $f7; Пробовал добавлять это. Также пробовал добавлять из _Pash`иной ссылки. Упрощенный вид сих магических действий Код port[$21] := port[$21] or $10; port[$21] := port[$21] and ($FF-$10); port[$20] := $64; - для IRQ4; либо для IRQ3: Код port[$21] := port[$21] or $08; port[$21] := port[$21] and ($FF-$08); port[$20] := $63; Бэзрезультатно. И смысл этой магии мне непонятен, т.к. не нашел понятного описания этих портов
|
|
|
|
|
May 27 2009, 18:42
|

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

|
Цитата(_Pasha @ May 27 2009, 17:13)  А Вы ее в сад отправляете.  К ссылке у меня не было никаких вопросов. Там все ОК ;> Смотреть - наздоровье. Пользовать-то зачем? Цитата(Diusha @ May 27 2009, 20:15)  И смысл этой магии мне непонятен, т.к. не нашел понятного описания этих портов Понятное описание этих и всех остальных портов можно найти в TechHelp который можно взять здесьВ двух словах, есть 2 класса прерываний - программные и аппаратные. Программные прерывания такие как int 10h,.. 13h,.. 16h,.. int 21h... вызываются из программы специальной командой INT xx для доступа к BIOS/DOS (каким-то иным) программным сервисам. Аппаратные прерывания (int 8, 9 ..0Fh ..) - вызываются аппаратурой (периферией). Исторически у x86 всего один вход INT для аппаратного прерывания, а периферии много: таймер, клавиатура, ком порты, и т.д. и т.п. Вопрос как это все подключить к одному входу проца? Ответ - добавить внешний контроллер прерываний, у которого будет столько входов сколько периферии, а выход на проц - один. Вот именно этот контроллер прерываний и располагается в портах 0x20, 0x21 и его надо настроить чтобы соответвующий сигнал запроса на прерывание от COM1 порта (IRQ4) - превратить в INT...
|
|
|
|
|
May 30 2009, 14:25
|
Вечный студент
   
Группа: Участник
Сообщений: 500
Регистрация: 11-09-06
Из: Питер
Пользователь №: 20 262

|
Уррра-ааааа!!! Заработало!!! Цитата(SysRq @ May 26 2009, 20:34)  Цитата port[COM+4]:=0;
Попробуйте $0B вместо 0 Цитата(defunct @ May 27 2009, 02:06)  Это не нужно. Мы ж мышку питать не собираемся. Самое смешное, что именно это и нужно было. Но вот почму так? Опять магия какая-то. Всем большое спасибо! Теперь остается только магию разоблачить
|
|
|
|
|
May 30 2009, 15:36
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата The Interrupt Enable bit is a PC-specific item. This is normally a general purpose output (OUT 2) on the 8250 SCC. However IBM's designers connected this output to an external gate to enable or disable all interrupts from the SCC. This bit must be programmed with a one to enable interrupts. Likewise you must ensure that this bit contains a zero if you are not using interrupts. Цитата Set OUT2 in the MODEM CONTROL Register so that the interrupt signal from the 8250 ACE is passed to the IRQ4 Interrupt Request Line ..just Gooooooooooooogle it :)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|