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

 
 
> Хочу прерывание на Паскале от СОМ-порта, (Турбо Паскаль, не Дельфи)
Diusha
сообщение May 26 2009, 17:11
Сообщение #1


Вечный студент
****

Группа: Участник
Сообщений: 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;"
Причина редактирования: Оформление цитаты исходника.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 18)
SysRq
сообщение May 26 2009, 17:34
Сообщение #2


Чайник, 1 литр
****

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



Цитата(Diusha @ May 26 2009, 21:11) *
port[COM+4]:=0;

Попробуйте $0B вместо 0 (подсмотрел).
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 26 2009, 18:08
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Diusha @ May 26 2009, 20:11) *
Программка ..

Moderator:
Пожалуйста пользуйтесь форматированием исходников.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение May 26 2009, 23:06
Сообщение #4


кекс
******

Группа: Свой
Сообщений: 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

Это не нужно. Мы ж мышку питать не собираемся.
Go to the top of the page
 
+Quote Post
Diusha
сообщение May 27 2009, 04:20
Сообщение #5


Вечный студент
****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 27 2009, 07:48
Сообщение #6


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



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


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


http://74.205.121.223/svn/firelab/Lidar/programs/ASYNC4U.PAS
Go to the top of the page
 
+Quote Post
XVR
сообщение May 27 2009, 08:52
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Прерывание от COM порта еще надо разрешить в контролере прерываний (предполагаю, что оно весит на IRQ3)
Код
port[$21] := port[$21] and $f7;
Ну и про
Код
port[$20] := $20;
в конце тоже забывать не надо
Go to the top of the page
 
+Quote Post
vvs157
сообщение May 27 2009, 12:46
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 526
Регистрация: 8-04-05
Пользователь №: 3 960



Цитата(XVR @ May 27 2009, 12:52) *
Прерывание от COM порта еще надо разрешить в контролере прерываний (
И еще в USART чипе разрешить прохождение прерывание на контроллер (помимо разрешения на прерывание в самом контроллере). Проще взять готовую библитотеку для ДОС для работы с COM. Вообще-то работа с СОМ по прерываниям в ДОС требует большой аккуратности и имеет много нюансов, "наскоком" не берется. BIOS поддерживает только поопросный режим работы с портом, что малоприемлемо.
Go to the top of the page
 
+Quote Post
defunct
сообщение May 27 2009, 14:05
Сообщение #9


кекс
******

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



Цитата(vvs157 @ May 27 2009, 15:46) *
И еще в USART чипе разрешить прохождение прерывание на контроллер

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

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

Вот чего не надо делать, так это брать готовую г...о-библиотеку.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 27 2009, 14:13
Сообщение #10


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



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

Человек хотел понять, как написать ISR под ДОС. Я дал ссылку на классику (правда, гуаноподобную), достаточную для понимания и допиливания. А Вы ее в сад отправляете. sad.gif
Go to the top of the page
 
+Quote Post
Diusha
сообщение May 27 2009, 17:15
Сообщение #11


Вечный студент
****

Группа: Участник
Сообщений: 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;

Бэзрезультатно.
И смысл этой магии мне непонятен, т.к. не нашел понятного описания этих портов
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 27 2009, 17:25
Сообщение #12


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(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
Go to the top of the page
 
+Quote Post
defunct
сообщение May 27 2009, 18:42
Сообщение #13


кекс
******

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



Цитата(_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...
Go to the top of the page
 
+Quote Post
XVR
сообщение May 28 2009, 08:25
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(Diusha @ May 27 2009, 21:15) *
И смысл этой магии мне непонятен, т.к. не нашел понятного описания этих портов
Идете на Intel, скачиваете datasheet на ICH10. Общее описание PIC - в разделе 5.8, порегистровое описание - в разделе 13.4
Go to the top of the page
 
+Quote Post
Diusha
сообщение May 29 2009, 16:40
Сообщение #15


Вечный студент
****

Группа: Участник
Сообщений: 500
Регистрация: 11-09-06
Из: Питер
Пользователь №: 20 262



В теории я немного просветился. Но практике это не помогло sad.gif
Может у кого сохранился живой примерчик?
Go to the top of the page
 
+Quote Post
Diusha
сообщение May 30 2009, 14:25
Сообщение #16


Вечный студент
****

Группа: Участник
Сообщений: 500
Регистрация: 11-09-06
Из: Питер
Пользователь №: 20 262



Уррра-ааааа!!!
Заработало!!!

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

port[COM+4]:=0;

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


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

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

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

Теперь остается только магию разоблачить
Go to the top of the page
 
+Quote Post
defunct
сообщение May 30 2009, 14:42
Сообщение #17


кекс
******

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



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

com+4 = 0xB = 0b1011 - два младших разряда отвечают за RTS/DTR сингналы, их включение ни на что не должно влиять. Потому что их можно и иногда нужно менять в процессе работы с портом.
Попробуйте вместо 0xB записать 0x8 (только bit OUT2). Если дело в нем, скорее всего этот сигнал (OUT2), что-то "запитывает" в схеме порта.
Go to the top of the page
 
+Quote Post
Diusha
сообщение May 30 2009, 15:02
Сообщение #18


Вечный студент
****

Группа: Участник
Сообщений: 500
Регистрация: 11-09-06
Из: Питер
Пользователь №: 20 262



Да, действительно, только бит 3 влияет
Go to the top of the page
 
+Quote Post
SysRq
сообщение May 30 2009, 15:36
Сообщение #19


Чайник, 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 :)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 12:06
Рейтинг@Mail.ru


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