Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Хочу прерывание на Паскале от СОМ-порта
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Diusha
Программка (запускается под 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;"
SysRq
Цитата(Diusha @ May 26 2009, 21:11) *
port[COM+4]:=0;

Попробуйте $0B вместо 0 (подсмотрел).
zltigo
Цитата(Diusha @ May 26 2009, 20:11) *
Программка ..

Moderator:
Пожалуйста пользуйтесь форматированием исходников.
defunct
Цитата(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

Это не нужно. Мы ж мышку питать не собираемся.
Diusha
Цитата(defunct @ May 27 2009, 02:06) *
Write() нежелательно использовать внутри прерываний насколько помню.

А почему?

Цитата(defunct @ May 27 2009, 02:06) *
...записать 20h в port 20h в конце обработчика

До начала бы добраться...
_Pasha
Цитата(Diusha @ May 27 2009, 07:20) *
До начала бы добраться...


Что-то я Вас не пойму...


http://74.205.121.223/svn/firelab/Lidar/programs/ASYNC4U.PAS
XVR
Прерывание от COM порта еще надо разрешить в контролере прерываний (предполагаю, что оно весит на IRQ3)
Код
port[$21] := port[$21] and $f7;
Ну и про
Код
port[$20] := $20;
в конце тоже забывать не надо
vvs157
Цитата(XVR @ May 27 2009, 12:52) *
Прерывание от COM порта еще надо разрешить в контролере прерываний (
И еще в USART чипе разрешить прохождение прерывание на контроллер (помимо разрешения на прерывание в самом контроллере). Проще взять готовую библитотеку для ДОС для работы с COM. Вообще-то работа с СОМ по прерываниям в ДОС требует большой аккуратности и имеет много нюансов, "наскоком" не берется. BIOS поддерживает только поопросный режим работы с портом, что малоприемлемо.
defunct
Цитата(vvs157 @ May 27 2009, 15:46) *
И еще в USART чипе разрешить прохождение прерывание на контроллер

Не USART, а UART.
Ну и это уже делается. В код топикстартера хоть заглядывали?

Цитата
Проще взять готовую библитотеку для ДОС для работы с COM.

Вот чего не надо делать, так это брать готовую г...о-библиотеку.
_Pasha
Цитата(defunct @ May 27 2009, 17:05) *
Вот чего не надо делать, так это брать готовую г...о-библиотеку.

Человек хотел понять, как написать ISR под ДОС. Я дал ссылку на классику (правда, гуаноподобную), достаточную для понимания и допиливания. А Вы ее в сад отправляете. sad.gif
Diusha
Цитата(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;

Бэзрезультатно.
И смысл этой магии мне непонятен, т.к. не нашел понятного описания этих портов
_Pasha
Цитата(Diusha @ May 27 2009, 20:15) *
И смысл этой магии мне непонятен, т.к. не нашел понятного описания этих портов

... и гугл тоже непонятен? sad.gif  http://www.google.com/search?client=opera&rls=ru&q=dos+programming+interrupt+irq&sourceid=opera&ie=utf-8&oe=utf-8
defunct
Цитата(_Pasha @ May 27 2009, 17:13) *
А Вы ее в сад отправляете. sad.gif

К ссылке у меня не было никаких вопросов. Там все ОК ;>
Смотреть - наздоровье. Пользовать-то зачем?


Цитата(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...
XVR
Цитата(Diusha @ May 27 2009, 21:15) *
И смысл этой магии мне непонятен, т.к. не нашел понятного описания этих портов
Идете на Intel, скачиваете datasheet на ICH10. Общее описание PIC - в разделе 5.8, порегистровое описание - в разделе 13.4
Diusha
В теории я немного просветился. Но практике это не помогло sad.gif
Может у кого сохранился живой примерчик?
Diusha
Уррра-ааааа!!!
Заработало!!!

Цитата(SysRq @ May 26 2009, 20:34) *
Цитата

port[COM+4]:=0;

Попробуйте $0B вместо 0


Цитата(defunct @ May 27 2009, 02:06) *
Это не нужно. Мы ж мышку питать не собираемся.

Самое смешное, что именно это и нужно было. Но вот почму так? Опять магия какая-то.

Всем большое спасибо!

Теперь остается только магию разоблачить
defunct
Цитата(Diusha @ May 30 2009, 17:25) *
Теперь остается только магию разоблачить

com+4 = 0xB = 0b1011 - два младших разряда отвечают за RTS/DTR сингналы, их включение ни на что не должно влиять. Потому что их можно и иногда нужно менять в процессе работы с портом.
Попробуйте вместо 0xB записать 0x8 (только bit OUT2). Если дело в нем, скорее всего этот сигнал (OUT2), что-то "запитывает" в схеме порта.
Diusha
Да, действительно, только бит 3 влияет
SysRq
Цитата
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 :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.