spo_1 / Отчёт
.docМинистерство образования РФ
ИжГТУ
Кафедра “ВТ”
Отчет по лабораторной работе
по курсу "Системное программное обеспечение".
Выполнили : студенты гр.863
Тутаев А.В.
Васильев А.М.
Проверил: Вахрушева Е. А.
Ижевск 2002 год
Задание: написать программу на языке высокого уровня, реализующую передачу файла с удалённой машины и выводящую этот файл на экран по последовательному порту (СОМ - порту) без и с помощью прерывания. Имя файла ввести с машины-приёмника.
Скорость обмена: 9600 бод
Длина слова : 8 бит
Проверка на чётность
Цель работы: изучить принципы работы СОМ – порта.
Листинг(без прерываний)
uses crt;
const com=1; { Порт COM1 }
var
Base:word absolute $40:(com*2-2); { Базовый адрес COM порта}
s:string;
f:text;
ch:char;
i:byte;
{---------------------------------------------------------------}
procedure InitCOM;
begin
port[Base+3]:=$80; { Регистр управления линией :DLAB =1}
port[Base]:=$0C; { Скорость обмена }
port[Base+1]:=0; { 9600 бод }
port[Base+3]:=27; { 000 11 0 11 }
{ ^^- длина слова 8 бит }
{ ^---- 1 бит останова }
{ ^^------ чет }
{ ^----------- DLAB := 0 }
port [Base+1]:=0; { Запретить прерывания }
end;
{---------------------------------------------------------------}
procedure send(_bt:byte);
begin
while port[Base+5] and $60 = 0 do {wait};
port[Base]:=_bt;
end;
{---------------------------------------------------------------}
function receive:byte;
begin
while port[Base+5] and 1 = 0 do {wait};
if port[Base+5] and $1e <> 0 then writeln('--==< Ошибка передачи! >==-- ')
else receive:=port[Base];
end;
{---------------------------------------------------------------}
{$R-}
begin
clrscr;
writeln('--==< Введите режим приёма/передачи m/s: >==--');
ch:=readkey;
case ch of
'm':begin
writeln('--==< Режим: MASTER >==--');
writeln('Введи имя файла-источника на удалёной машине:');
readln(s);
initCOM;
for i:=1 to length(s) do send(ord(s[i]));
send(13);
assign(f,'c:\priem.000');
rewrite(f);
repeat
ch:=chr(receive);
write(f,ch);
write(ch);
until ch=#0;
writeln;
writeln('--==< Принято >==--');
close(f);
readkey;
end;
's':begin
writeln('--==< Режим: SLAVE >==--');
s:='';
writeln('--==< Ожидание данных ... >==--');
initCOM;
repeat
ch:=UpCase(chr(receive));
if ch<>#13 then s:=s+ch;
until ch=#13;
writeln('--==< Передача файла >==--');
assign(f,s);
reset(f);
repeat
read(f,ch);
send(ord(ch));
write(ch);
until eof(f);
send(0);
close(f);
writeln;
writeln('--==< Передано >==--');
readkey;
end;
end;
end.
Листинг(с прерываниями)
Master
Program SendBytes; { Передатчик }
uses crt,dos;
const
com = 1; { Порт COM1 }
InterCOM = $0B+2-com; { Вектор прерывания: }
var
Base : word absolute $40:(com*2-2); { Базовый адрес COM порта }
name : string;
f : text;
Status,j,a,receive : byte;
flag : boolean;
OldVector : Pointer;
{___________________________________________________________________________}
procedure InitCOM; { Инициализация COM порта }
{ на работу по прерываниям}
var
buffer : word;
begin
port[Base+3]:=$80; { Регистр управления линией : DLAB = 1 }
port[Base]:=$0C; { Скорость обмена }
port[Base+1]:=0; { 9600 бод }
port[Base+3]:=27; { 000 11 0 11 }
{ ^^- длина слова 8 бит}
{ ^---- 1 бит останова }
{ ^^------ чет }
{ ^----------- DLAB := 0 }
port [Base+1]:=$05; { Прерывание при приеме символа и ошибкe }
port [Base+4]:=$08; { Разрешение выдачи запроса прерыван. на шину }
port [$21]:=port [$21] and $E7;
{ Разрешение прерываний от COM в контроллере прерываний }
buffer:=port[Base]; { Очистка входного регистра }
buffer:=port[Base+5]; { Очистка регистра статуса линии }
end;
{___________________________________________________________________________}
procedure send(_bt:byte); { Поcлать байт }
begin
while port[Base+5] and $40 = 0 do {wait};
port[Base]:=_bt;
delay(100);
end;
{___________________________________________________________________________}
procedure ComHandler;interrupt; { Обработчик прерываний }
{ от COM порта }
var
Status : byte;
_byte : byte;
begin
Status:=port[Base+5]; { Получить байт статуса }
_byte:=port[base]; { Получить байт }
if Status and $1E <> 0 then begin
writeln ('== Ошибка связи ==' );
halt(0);
end;
if not flag then
begin
assign(f,'c:\priem.001');
rewrite(f);
flag := true;
end;
if chr(_byte)<>#0 then begin
write(f,chr(_byte));
write(chr(_byte));
end;
if chr(_byte)=#0 then
begin
writeln;
writeln('== Файл получен ==');
close(f);
end;
port[$20]:=$20; { Сброс контроллера прерываний }
end;
{____________________________Головная программа_____________________________}
begin
clrscr;
InitCOM;
Status:=port[Base+5]; { Получить байт статуса }
if Status and $1E <> 0 then writeln('== Ошибка связи ==');
clrscr;
writeln('== Приём файла по СОМ-порту ==');
writeln('== Введите имя файла:');
readln(name);
a:=length(name); { Определяем длину строки name }
send(a);
for j:=1 to a do
send (byte(name[j]));
flag := false; { Файла для записи не открыт }
GetIntVec(InterCOM,OldVector); { Сохранить старый вектор }
SetIntVec(InterCOM,@ComHandler); { Уст-ть вектор обработчика }
clrscr;
Writeln ('== Приём файла ==');
readkey;
SetIntVec(InterCOM,OldVector);
end.
Slave
Program ReceiveBytes; { Приемник }
uses crt,dos;
const
com = 1; { Порт COM1 }
InterCOM = $0B+2-com; { Вектор прерывания: }
var
Base : word absolute $40:(com*2-2); { Базовый адрес COM порта }
Status,j,l,receive,a : byte;
name : string;
f : text;
Symbol : char;
OldVector : pointer;
flag,NameFlag : Boolean;
{___________________________________________________________________________}
procedure InitCOM; { Инициализация COM порта }
{ на работу по прерываниям}
var
buffer : word;
begin
port[Base+3]:=$80; { Регистр управления линией : DLAB = 1 }
port[Base]:=$0C; { Скорость обмена }
port[Base+1]:=0; { 9600 бод }
port[Base+3]:=27; { 000 11 0 11 }
{ ^^- длина слова 8 бит}
{ ^---- 1 бит останова }
{ ^^------ чет }
{ ^----------- DLAB := 0 }
port [Base+1]:=$05; { Прерывание при приеме символа и ошибкe }
port [Base+4]:=$08; { Разрешение выдачи запроса прерыван. на шину }
port [$21]:=port [$21] and $E7;
{ Разрешение прерываний от COM в контроллере прерываний }
buffer:=port[Base]; { Очистка входного регистра }
buffer:=port[Base+5]; { Очистка регистра статуса линии }
end;
{___________________________________________________________________________}
procedure ComHandler;interrupt; { Обработчик прерываний COM порта }
var
Status : byte;
_byte : byte;
begin
Status:=port[Base+5]; { Получить байт статуса }
_byte:=port[base]; { Получить байт файла }
if Status and $1E <> 0 then begin
writeln ('== Ошибка связи ==' );
halt(0);
end;
if not flag then
begin
a:=_byte;
flag:=true;
name:= '';
End
else
begin
name:=name+chr(_byte);
a:=a-1;
end;
If (a=0) and (flag) Then NameFlag := True;
port[$20]:=$20; { Сброс контроллера прерываний }
end;
{___________________________________________________________________________}
procedure send(_bt:byte); { Поcлать байт}
begin
while port[Base+5] and $40 = 0 do {ожидание};
port[Base]:=_bt;
delay(100);
end;
{___________________________Головная программа_____________________________}
begin
clrscr;
InitCOM;
Status:=port[Base+5]; { Получить байт статуса }
if Status and $1E <> 0 then writeln('== Ошибка связи ==');
writeln('== Передача файла по СОМ-порту ==');
NameFlag := False;
flag:= False; { Размер файла не получен }
GetIntVec(InterCOM,OldVector); { Сохранить старый вектор }
SetIntVec(InterCOM,@ComHandler); { Уст-ть вектор обработчика }
While not NameFlag do; { Пока не известно имя файла }
SetIntVec(InterCOM,OldVector); { Восстановить вектор }
assign(f,name);
reset (f);
while not eof(f) do
begin
read(f,Symbol);
send(byte(Symbol));
write(Symbol);
end;
close(f);
send(0);
writeln;
writeln('== Файл передан! ==');
readkey;
end.
