Referát z předmětu 36PZ
Úloha A: RS232
Skupina D: Duben
Program Serial;
uses DOS,CRT;
const
{------------------- COM ports in PC -------------------}
COM1= $3f8;
COM2= $2f8;
Intr: Integer = $0b;
{------------------- 8250 registers --------------------}
RBR= 0; { received data - read only - if DLAB=0 }
THR= 0; { transmit data - write only - if DLAB=0 }
DLL= 0; { baud generator (LSB) - if DLAB=1 }
DLM= 1; { baud generator (MSB) - if DLAB=1 }
IER= 1; { interrupt enable - r/w }
IIR= 2; { interrupt identification - read only }
LCR= 3; { line control register - r/w }
MCR= 4; { modem control register - r/w }
LSR= 5; { line status - read only }
MSR= 6; { modem status register - read only }
{------------------- 8250 register bits ----------------}
IER_RX= 1; { intr on received data - priority 2 }
IER_TX= 2; { intr on data transmitted - priority 3 }
IER_ERR= 4; { intr on receive error (see LSR) - priority 1 }
IER_MS= 8; { intr on modem sts change (see MSR) - priority 4 }
IIR_PEND= 1; { active intr request }
IIR_MASK= 6; { source id mask }
IIR_MS= 0; { modem sts change }
IIR_TX= 2; { data transmitted }
IIR_RX= 4; { data received }
IIR_ERR= 6; { receive error }
LCR_5BIT= 0; { byte length codes }
LCR_6BIT= 1;
LCR_7BIT= 2;
LCR_8BIT= 3;
LCR_2STOP= 4; { two stop bits }
LCR_PTYEN= 8; { parity enabled }
LCR_EVPTY= $10; { even parity }
LCR_FIXPTY= $20; { fixed parity }
LCR_INTREN= $40; { interrupt enabled }
LCR_DLAB= $80; { baud gen. access enabled }
MCR_DTR= 1; { DTR modem signal }
MCR_RTS= 2; { RTS modem signal }
MCR_OUT1= 4; { user signal }
MCR_OUT2= 8; { user signal - wired to 3 state IRQ driver }
MCR_LOOP= $10; { test loop }
LSR_RX= 1; { data received }
LSR_OR= 2; { overrun - read once }
LSR_PR= 4; { parity error - read once }
LSR_FR= 8; { frame error - read once }
LSR_BT= $10; { break error - read once }
LSR_BF= $20; { tx buffer empty }
LSR_TX= $40; { serializer empty }
MSR_CSR_CH= 1; { CSR has changed - read once }
MSR_DSR_CH= 2; { DSR has changed - read once }
MSR_RI_END= 4; { RI ended - read once }
MSR_RLSD_CH= 8; { RLSD changed - read once }
MSR_CSR= $10;
MSR_DSR= $20;
MSR_RI= $40;
MSR_RLSD= $80;
DLM_300= 1; { 300 Baud }
DLM_HIGH= 0; { more than 300 Baud }
DLL_300= $80; { 300 Baud }
DLL_600= $c0; { 600 Baud }
DLL_1200= $60; { 1200 Baud }
DLL_2400= $30; { 2400 Baud }
DLL_4800= $18; { 4800 Baud }
DLL_9600= $0c; { 9600 Baud }
DLL_19200= $06; { 19200 Baud }
{-------------------------------------------------------------------}
type word=0..65535;
parstr=string[255];
{-------------------------------------------------------------------}
var
com: word;
loop: boolean;
c: char;
argv1, argv2: parstr;
org_int: pointer;
xp, yp ,xv ,yv: byte;
{-------------------------------------------------------------------}
procedure init_com (portaddr: word; loop: boolean);
begin
port [portaddr+LCR]:= LCR_DLAB; { path to baud gen on }
port [portaddr+DLM]:= DLM_HIGH; { more than 300 Baud }
port [portaddr+DLL]:= DLL_1200; { 1200 Baud }
port [portaddr+LCR]:= LCR_8BIT; { baud gen off, 8 bit, no par }
port [portaddr+IER]:= 0; { no interrupt }
if loop then
port [portaddr+MCR]:= MCR_DTR or MCR_LOOP
else
port [portaddr+MCR]:= MCR_DTR;
port[com + IIR]:= $07; { 1 byte length buffer and its cleaning }
port[com + MCR]:= $0b; { OUT2 to 1, enable int }
if intr = $0c then { mask int }
begin
port[$21]:= port[$21] and $EF
end
else
begin
port[$21]:= port[$21] and $F7;
end;
port[com + IER]:= $01; { int on received character }
end;
{-------------------------------------------------------------------}
function rx_rdy (portaddr: word): boolean;
begin
rx_rdy:=((port[portaddr+LSR] and LSR_RX) <>0);
end;
{-------------------------------------------------------------------}
function tx_rdy (portaddr: word): boolean;
begin
tx_rdy:=((port [portaddr+LSR] and LSR_BF) <>0);
end;
{-------------------------------------------------------------------}
function rx_get (portaddr: word): char;
begin
rx_get:= chr(port [portaddr+RBR]);
end;
{-------------------------------------------------------------------}
procedure tx_put (portaddr: word; c : char);
begin
port [portaddr+THR]:= ord (c);
end;
{-------------------------------------------------------------------}
function hx (t: parstr): word;
var ix: integer;
w: word;
ok: boolean;
begin w:=0; ok:=true;
for ix:=1 to length(t) do if ok then
begin if t[ix] in ['0'..'9'] then w:=16*w+ord(t[ix])-ord('0')
else if t[ix] in ['A'..'F'] then w:=16*w+ord(t[ix])-ord('A')+10
else if t[ix] in ['a'..'f'] then w:=16*w+ord(t[ix])-ord('a')+10
else ok:=false;
if w>$3FF then ok:=false;
end;
if ok then hx:=w else hx:=0;
end;
{-------------------------------------------------------------------}
procedure rx_int; interrupt;
begin
if (rx_rdy(com)) then
begin
window(1, 13, 80, 25);
gotoxy(xp,yp);
c:= rx_get(com);
write(c);
if c = chr(13) then writeln;
xp:= wherex;
yp:= wherey;
end;
port[$20]:= 20;
end;
{-------------------------------------------------------------------}
begin
com:=COM1;
loop:=false;
c:='a';
argv1:=ParamStr(1);
argv2:=ParamStr(2);
case ParamCount of
0: begin writeln ('Usage: serial [l]');
writeln ('COM1 is at 3F8, COM2 is at 2F8.');
halt;
end;
1: begin com:=hx(argv1);
if com=0 then
begin writeln ('Port address must be hex number in the range 10..3FF');
halt;
end;
end;
2: begin com:=hx(argv1);
if com=0 then
begin writeln ('Port address must be hex number in the range 10..3FF');
halt;
end;
loop:=true;
end;
end;
init_com (com,loop);
while (ord(c)<>0) do
begin
if (rx_rdy(com)) then write (rx_get(com));
if keypressed then
if tx_rdy(com) then
begin
c:=readkey;
tx_put (com,c);
end;
end;
c:=readkey;
setIntVec($0B, org_int);
end.
Závěr: