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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Хочу прерывание на Паскале от СОМ-порта, (Турбо Паскаль, не Дельфи)
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
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

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

 


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


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