Startseite   |  Site map   |  A-Z artikel   |  Artikel einreichen   |   Kontakt   |  
  


informatik artikel (Interpretation und charakterisierung)

Drucker

Mail

Druckeransteuerung unter turbo-pascal für dos


1. Java
2. Viren

1.1 Zweck und Anwendungsbereich />
Dieses Druckprogramm ist nur für den Schul- und Hausgebrauch geeignet, obwohl es leicht zu bedienen und einfach aufgebaut ist, verfügt es aber nicht über einstellbare Druckoptionen. Dieses Programm wurde im Informatikunterricht und teils in Heimarbeit, unter der Projektaufgabe \"Entwickeln und testen sie ein Pascal-Programm, mit dessen Hilfe ASCII-Textdateien auf einem Drucker durch direkte Druckeransteuerung ausgedruckt werden können,\" entwickelt und geschrieben. In diesem Pascal-Programm wurden die geforderten Richtlinien erfüllt, sowie einige der möglichen Erweiterungen eingebunden.


Spezifikationen :

- Das Datenübertragungsprotokoll zum Drucker ist ADQ-Handshake.
- Es wird auf DIN A4-Einzelblätter mit insgesamt 58 Zeilen/Druckseite gedruckt.
- Nach dem Druck jeder Seite, jedoch nicht nach der letzten, ist auf dem Bildschirm eine
Meldung auszugeben, mit der der Benutzer aufgefordert wird, ein neues Blatt in den
Drucker einzulegen sowie der Hinweis, daß erst dann weitergedruckt wird, wenn die
ESC-Taste - und nur diese - gedrückt wurde.

Erweiterungen :

. die Textzeilen sind fortlaufend numeriert
. auf Seite 1 wird der Dateiname ausgedruckt
. des weiteren wird das aktuelle Systemdatum auf Seite 1 ausgedruckt
. ebenfalls nützlich bei der Archivierung ist die fortlaufende Seitennumerierung mit Angabe
der Gesamtanzahl der Seiten und der Drucker wird nach dem Druck einer Datei auf seine Standardeinstellungen zurückgesetzt

1.2 Anweisungen

Bei der Benutzung dieses Druck-Programms braucht der Anwender nur sehr wenig zu beachten, da es nur wenige, dafür aber eindeutige Anweisungen gibt. Aus diesem Grund ist ein leichtes, problemloses Arbeiten möglich.
Voraussetzung für den Ausdruck ist, daß der Drucker eingeschaltet und das bei Programmstart Papier im Drucker ist. Ansonsten meldet sich das Programm mit einer Fehlermeldung und der Aufforderung den Drucker einzuschalten bzw. Papier einzulegen. Das Programm wird nach diesen Fehlermeldungen beendet und kann nach Behebung der Fehler erneut gestartet werden.
Die Arbeitsanweisungen beschränken sich auf das Eingeben des Dateinamens, der zum Ausdruck gewünschten Datei, sowie dem Blatteinlegen. Der Dateiname darf nicht mehr als 8 Zeichen und die Dateiendung nicht mehr als 3 Zeichen lang sein. Das sind jedoch Beschränkungen der FAT (File Allocation Table = Dateizuordnungstabelle) von DOS. Erst mit VFAT unter Windows 95 bzw. mit NTFS, dem File System von Windows NT könnten theoretisch auch mehr Dateizeichen verwendet werden. Microsoft bietet zum Zweck der Erweiterung der Funktionalität von DOS-Programmen unter Windows ab Version 95 ein Support Pack für Programmierer an, um dann auch mit mehr als 8 Zeichen zu arbeiten. Die Eingabe des Dateinamens wird dann mit bestätigt.

2 Entwickler-Dokumentation

2.1 Lösungsideen und Teilalgorithmen

Die gestellte Aufgabe aus dem Bereich der Technischen Informatik befaßt sich mit dem Thema der direkten Druckeransteuerung über die Centronics-Schnittstelle. Diese Schnittstelle ist eine spezielle parallele Schnittstelle, bei der die Daten bit-parallel auf 8 parallelen Datenleitungen übertragen werden. Für die Übertragungung der Zeichen vom Computer zum Drucker wurde in diesem Druck-Programm ein einfaches, aber erprobtes Übertragungsprotokoll, das ADQ-Handshake oder ADQ-Protokoll verwendet. Obwohl der Aufbau der CENTRONICS-Schnittstelle die Realisierung unterschiedlicher Übertragungsprotokolle zuläßt, so ist das ADQ-Handshake doch eines der zuverlässigsten und wurde auch verwendet, damit die Arbeit mit dem Programm problemlos erfolgen kann.
Zunächst habe ich mich mit dem Aufbau der Druckerschnittstelle und den Zuständen ausgewählter Register-Signale beschäftigt, worauf erste kleine Pascal-Programme folgten, die durch Bitmanipulation in Bytes Zugriff auf die Register der Schnittstelle erhielten. Diese Programme nutzen selbstentwickelte Bit-Filter, die Bit-Masken einsetzen. Dabei verwendet man die in PASCAL zulässige Verknüpfung von Bytes mit Hilfe der logischen Operatoren AND, OR sowie XOR. Um die Codierung dieser Programme in PASCAL zu erleichtern, sollte man Lösungsalgorithmen aufstellen, in denen eindeutig der Programmablauf mit eigenen Worten beschrieben ist.
Um eine komplette und umfangreiche Datei fehlerfrei auszudrucken, waren die Prozeduren Zeilenvorschub und Seitenvorschub notwendig. Alle globalen Variablen des Programms sind im Programmkopf vereinbart worden, weil mehrere Prozeduren mit ihnen arbeiten. Dagegen sind viele Variablen lokal deklariert, da die Prozeduren und Funktionen ähnliche Programmabläufe haben, und man deshalb Variablennamen mehrmals verwenden kann, ohne das Komplikationen auftreten.
Ich habe mir zur Aufgabe gestellt, die wichtigsten Prozeduren zu erläutern, da ein PASCAL-Programm meistens aus mehreren Prozeduren besteht, die miteinander verknüpft zusammenarbeiten. Den Anfang macht hierbei die Prozedur strobeimpuls.
Quelltext:

procedure strobeimpuls;
var steuer_byte,ergebnis_byte,maske:byte;

begin

maske:=1;

steuer_byte:=port[890];
ergebnis_byte:=(steuer_byte XOR maske);

port[890]:=ergebnis_byte;
delay(10);

port[890]:=steuer_byte;

end;
Diese Prozedur ist charakteristisch für das Druck-Programm, da sie eine der wichtigsten im ganzen Programm ist und da sie nach dem Prinzip der Bitmanipulation arbeiten.Die Aufgabe der Prozedur liegt in der Aussendung eines Signals, das dem Drucker mitteilt, daß ein Datenwort zu \"Weiterverarbeitung\" bereits im Datenregister vorhanden ist.
Die Realisierung erfolgt, indem der PC dem Drucker mitteilt, daß er das Steuerbyte A0 mindestens 10 Millisekunden lang auf Eins setzt, somit einen Bitwechsel vollführt, der ein Signal darstellt.



In der ersten Zeile wird formal der Prozedurname festgelegt, ihm folgt in der zweiten Zeile
die Deklaration der zu benutzenden Variabeln steuer_byte, ergebnis_byte und der Bitmaske des Typus byte. Die Anweisungen beginnen mit dem Setzen der Bitmaske auf 1. Dann wird aus dem Steuerregister mit der Adresse 890 dez das steuer_byte ausgelesen. Da die Maske 1 ist, wird nun mit Hilfe der Operation XOR das ergebnis_byte auf jeden Fall auf 1 gesetzt. Das ergebnis_byte wird nun in das Steuerregister mit der Adresse 890 dez zurückgeschrieben. Eine Pause von 10 ms ermöglicht dem PC die Auswertung und Reaktion auf das ergebnis_byte. Der Strobeimpuls wird generiert, womit die Aufgabe ein Signal abzugeben erfüllt wurde. Anschließend wird das Byte steuer_byte in das Steuerregister mit der Adresse 890 dez zurückgeschrieben.
Die Prozedur strobeimpuls wird in meinem Programm in 50% aller Prozeduren verwendet, man benötigt diese Prozedur zum Druck jeden Zeichens, sowie zur Konfigurierung des Druckers, sie ist für mich ein kausales Hilfsmittel.
Bevor die Daten ausgedruckt werden können, müssen sie jedoch erst einmal aus der Datei ausgelesen werden. Dies geschieht mit Hilfe der Prozedur datei_sequentiell_lesen.
Quelltext:

procedure datei_sequentiell_lesen;

var znummer, zzaehler, seite:integer;
s,seiten:string;


begin

seitenanzahl;

seite:=1;

str(seite,seiten);
wort_drucken(\'Seite\'+\' \'+Seiten+\' \'+\'von\'+\' \'+gesamt);

zeilenvorschub;

reset(quelldatei);

znummer:=0;

while not eof(quelldatei) do


begin

znummer:=znummer+1;

str(znummer,s);

readln(quelldatei,zeile);

zeile:=s+\' \'+zeile;

wort_drucken(zeile);
if ((znummer MOD 58=0) AND (not eof(quelldatei)))

then

begin
seitenvorschub;

seite:=seite+1;

str(seite,seiten);
writeln(\'Bitte neues Blatt einlegen, wenn Drucker fertig ist!\');

delay(10000);

writeln(\'Weiter mit Escape-Taste!\');

repeat until readkey=escape;
wort_drucken(\'Seite\'+\' \'+Seiten+\' \'+\'von\'+\' \'+gesamt);
zeilenvorschub;
clrscr;

end;

end;

if eof(quelldatei) then

begin
clrscr;

writeln(\'Drucken beendet\');
seitenvorschub;

end;

end;

Wieder wird zunächst der Prozedurname festgelegt. In dieser Prozedur kommen schon einige Erweiterungen zum Einsatz. Zum Beispiel wird jede einzelne Zeile der auszulesenden Datei numeriert. Dies geschieht über den Zähler znummer, der bei jedem Durchlauf der While not
Eof Schleife um 1 hochgesetzt wird, also bei jeder neu eingelesenen Zeile. Der Zähler wird über den Befehl str dann noch ins String-Format übersetzt, um dann zusammen mit der Zeile
ausgedruckt zu werden. Wenn der Zähler znummer 58 oder ein Vielfaches davon beträgt, wird ein Seitenvorschub gestartet; eine im Programm definierte Prozedur. Die aktuelle Seitenanzahl Seite, die zuvor auf 1 gesetzt wurde, wird nun um 1 erhöht, um dann auf der nächsten Seite zusammen mit der in der Prozedur seitenanzahl ermittelten Gesamtseitenzahl gesamt ausgedruckt zu werden. Um dem Anwender jedoch Zeit zum Neueinlegen eines Blattes Papier zu geben, wird der Seiteneinzug solange verzögert, bis der Anwender die Escape-Taste betätigt hat. Dann wird der Druck der restlichen Zeilen der Datei fortgesetzt, immer mit einem Seitenvorschub und einem darauf folgenden Seiteneinzug führt. Der Seiteneinzug ist aber nur eine Folge des Strobeimpulses, der in der Prozedur wort_drucken durchgeführt wird, um die nach dort übergebene Variable zeile auszudrucken.
Hier noch einmal zum näheren Verständnis der Quelltext der Prozedur wort_drucken:

procedure wort_drucken(zeile: string) ;

var zk_laenge,i:integer;

zeichen:char;

begin

zk_laenge:=length(zeile);

For i:=1 to zk_laenge do

begin

zeichen:=zeile[i];

port[888]:=ord(zeichen);

strobeimpuls;
delay(10);

end;
zeilenvorschub;

end;

Wie sehr schön zu erkennen ist, findet sich hier unsere eingelesene Zeile aus der Prozedur datei_sequentiell_lesen wieder. Diese wird jetzt auf ihre Länge hin untersucht. Vom ersten Zeichen an bis zum letzten der Zeichenkette wird nun das jeweilige Zeichen ins Datenregister
verschoben, um von dort per Strobeimpuls an den Drucker zu wandern. Dieser führt dann noch einen Zeilenvorschub aus, um schließlich die nächste Zeile zu drucken. Es sei an dieser Stelle angemerkt, daß der Computer die Zeilen viel schneller aus der Datei ausliest, als diese gedruckt werden können. Das stellt jedoch keinen Nachteil dar, da der Puffer im Drucker groß
genug ist, die ankommenden Daten zwischenzuspeichern.

Das war eigentlich schon der gesamte Vorgang des Druckens samt Auslesen der Informationen aus der ASCII-Datei. Der Auslesevorgang findet sich, diesmal aber ohne Druckvorgang, auch noch einmal in der Prozedur seitenanzahl. Sie dient lediglich dazu, im voraus die Gesamtanzahl der Zeilen der Datei festzustellen, um diese dann später immer mit
der aktuellen Seitenzahl auszudrucken, wenn eine neue Seite beginnt. Hier der Quelltext der Prozedur Seitenanzahl:

procedure seitenanzahl;
var zeilennummer, seitenzahl:integer;


begin

reset(quelldatei);

zeilennummer:=0;

while not eof(quelldatei) do

begin

zeilennummer:=zeilennummer+1;

readln(quelldatei);

end;

seitenzahl:=zeilennummer div 58;
if zeilennummer mod 58 0 then seitenzahl:=seitenzahl+1;

str(seitenzahl, gesamt);

close(quelldatei);

end;

Dividiert man die Anzahl der Zeilen, gespeichert in der Variablen zeilennummer durch die Anzahl der Zeilen pro Seite, so ergibt sich daraus die Gesamtseitenzahl. Bei einer nicht ganzen Zahl ist die Seitenzahl entsprechend immer einen Zähler höher. Die Prozeduren online_test (Abfrage, ob der Drucker eingeschaltet bzw. neudeutsch "online"Ist), busy (Abfrage der Verfügbarkeit des Druckers) fragen mittels bestimmter Bitmasken das Statusregister des Druckers mit der Adresse 889 dez ab und sind im Hauptprogramm dem eigentlichen Druckvorgang vorgestellt, ebenso wie die Prozedur prüfen.

In der Prozedur pruefen wird beim Öffnen der zu druckenden Datei auf das IO-Ergebnis gewartet und entsprechend seinem Wert der Vorgang weitergeführt oder mit einem Hinweis auf die nicht vorhandene Datei beeendet.

Besonders erwähnenswert ist die Prozedur datum_drucken. In ihr wird das Systemdatum mit Hilfe des Befehls getDate ausgelesen. Mittels eines Datenfeldes werden den Werten 0 bis 6, je nach Wochentag, der Variable dow, die Wochentage zugeordnet und dann zusammen mit dem Datum gedruckt. Hier der Quelltext:
procedure datum_drucken;

var

Jahr, Monat, tag:string; const Tage: array [0..6] of String[10] =(\'Sonntag\',\'Montag\',\'Dienstag\',
\'Mittwoch\',\'Donnerstag\',\'Freitag\',\'Samstag\');

var

y, m, d, dow : Word;

begin
GetDate(y,m,d,dow);
str(y,Jahr);
str(m,Monat);
str(d,Tag);
wort_drucken(Tage[dow]+\',\'+\' \'+\'der\'+\' \'+

Tag+\'.\'+Monat+\'.\'+Jahr);zeilenvorschub;end;


1 Zusammenfassung

Obwohl heute sicherlich niemand mehr einen Druckertreiber für DOS schreiben würde, der derart generelle Funktionen bietet, war die Arbeit an diesem Projekt doch sehr interessant. Ob nun DOS oder Windows, die Prinzipien der Bitmaskenprogrammierung kommen in allen möglichen Gerätetreibern und bei allen Betriebssystemen zum Einsatz.

2 vollständiger Sourcecode

program druck;
uses dos, crt;

var quelldatei:text;
quelldateiname:string[12];

zeile:string[125];
busy_wert:integer;

druck_string:string[125];
zeichen:char;

datei_vorhanden:boolean;
taste:char;

gesamt:string;
const escape=chr(27);


{--------Abfrage, ob der Drucker druckbereit ist------}


procedure busy;
var status_byte,maske,ergebnis_byte:byte;

begin
clrscr;
maske:=128;

status_byte:=port[889];
ergebnis_byte:=(status_byte and maske);
if ergebnis_byte=maske then busy_wert:=1 else busy_wert:=0;

end;


procedure strobeimpuls;
var steuer_byte,ergebnis_byte,maske:byte;

begin

maske:=1;

steuer_byte:=port[890];
ergebnis_byte:=(steuer_byte XOR maske);

port[890]:=ergebnis_byte;
delay(10);

port[890]:=steuer_byte;

end;
















procedure zeilenvorschub;

begin

port[888]:=10;
strobeimpuls;

end;


procedure wort_drucken(zeile: string) ;

var zk_laenge,i:integer;

zeichen:char;

begin

zk_laenge:=length(zeile);

For i:=1 to zk_laenge do

begin

zeichen:=zeile[i];

port[888]:=ord(zeichen);

strobeimpuls;
delay(10);

end;
zeilenvorschub;

end;

{------Abfrage, ob Drucker an ist-----}

procedure online_test;

var status_byte, neu_byte, maske:byte;
bit_wert,i:integer;

begin
i:=1;

repeat
clrscr;

maske:=16;

status_byte:=port[889];

neu_byte:=(status_byte AND maske);
if neu_byte=maske then bit_wert:=1 else bit_wert:=0;
if bit_wert=0 then writeln(\'Bitte schalten Sie den Drucker ein!\');
delay (1000);

i:=i+1;
until (neu_byte=maske) or (i=15);

if neu_bytemaske then

begin
writeln(\'Abbruch des Druckprogrammes\');
delay(5000);

halt;

end;

end;


procedure druckerpuffer_leeren;

begin

port[888]:=13;
strobeimpuls;

end;


procedure seitenvorschub;

begin

port[888]:=12;
strobeimpuls;

end;






procedure seitenanzahl;
var zeilennummer, seitenzahl:integer;


begin

reset(quelldatei);

zeilennummer:=0;

while not eof(quelldatei) do

begin

zeilennummer:=zeilennummer+1;

readln(quelldatei);

end;

seitenzahl:=zeilennummer div 58;
if zeilennummer mod 58 0 then seitenzahl:=seitenzahl+1;

str(seitenzahl, gesamt);

close(quelldatei);

end;



procedure datei_sequentiell_lesen;

var znummer, zzaehler, seite:integer;
s,seiten:string;


begin

seitenanzahl;

seite:=1;

str(seite,seiten);
wort_drucken(\'Seite\'+\' \'+Seiten+\' \'+\'von\'+\' \'+gesamt);

zeilenvorschub;

reset(quelldatei);

znummer:=0;

while not eof(quelldatei) do


begin

znummer:=znummer+1;

str(znummer,s);

readln(quelldatei,zeile);

zeile:=s+\' \'+zeile;

wort_drucken(zeile);
if ((znummer MOD 58=0) AND (not eof(quelldatei)))

then

begin
seitenvorschub;

seite:=seite+1;

str(seite,seiten);
writeln(\'Bitte neues Blatt einlegen, wenn Drucker fertig ist!\');

delay(10000);

writeln(\'Weiter mit Escape-Taste!\');

repeat until readkey=escape;
wort_drucken(\'Seite\'+\' \'+Seiten+\' \'+\'von\'+\' \'+gesamt);
zeilenvorschub;
clrscr;

end;

end;

if eof(quelldatei) then

begin
clrscr;

writeln(\'Drucken beendet\');
seitenvorschub;

end;

end;




procedure pruefen (VAR quelldatei:text;
var datei_vorhanden:boolean);

begin
(*$I-*)

reset (quelldatei);
(*$I+*)

if IOresult 0
then

begin
datei_vorhanden:=false;

end
else

begin
datei_vorhanden:=true;

close(quelldatei);

end;

end;


procedure kopfzeile_drucken;

begin

wort_drucken(quelldateiname);
zeilenvorschub;

end;

procedure datum_drucken;

var

Jahr, Monat, tag:string;
const Tage: array [0..6] of String[10] =
(\'Sonntag\',\'Montag\',\'Dienstag\',
\'Mittwoch\',\'Donnerstag\',\'Freitag\',

\'Samstag\');

var

y, m, d, dow : Word;


begin
GetDate(y,m,d,dow);
str(y,Jahr);
str(m,Monat);
str(d,Tag);
wort_drucken(Tage[dow]+\',\'+\' \'+\'der\'+\' \'+

Tag+\'.\'+Monat+\'.\'+Jahr);
zeilenvorschub;

end;



begin
clrscr;
online_test;
write(\'Welche Datei soll gedruckt werden? :\');readln(quelldateiname);
assign(quelldatei,quelldateiname);

pruefen(quelldatei,datei_vorhanden);
if datei_vorhanden=false then

begin
writeln(\'Die zu druckende Datei ist nicht da\');

readln;
halt;

end;


busy;
if busy_wert=1 then

begin
kopfzeile_drucken;

datum_drucken;
datei_sequentiell_lesen;

close(quelldatei);
delay(10);

druckerpuffer_leeren;
seitenvorschub;

end; end.

 
 

Datenschutz
Top Themen / Analyse
indicator Online-Marketing
indicator Verbindungsorientierte Datenübermittlung
indicator 3D-Beschleuniger
indicator Die Architektur von PHP
indicator Multitasking
indicator Das Interruptsystem
indicator Die fünf Formate der DVD
indicator Windows-Beschleuniger
indicator Chipkarte als elektronische Geldbörse
indicator Sinn und Zweck


Datenschutz
Zum selben thema
icon Netzwerk
icon Software
icon Entwicklung
icon Windows
icon Programm
icon Unix
icon Games
icon Sicherheit
icon Disk
icon Technologie
icon Bildung
icon Mp3
icon Cd
icon Suche
icon Grafik
icon Zahlung
icon Html
icon Internet
icon Hardware
icon Cpu
icon Firewall
icon Speicher
icon Mail
icon Banking
icon Video
icon Hacker
icon Design
icon Sprache
icon Dvd
icon Drucker
icon Elektronisches
icon Geschichte
icon Fehler
icon Website
icon Linux
icon Computer
A-Z informatik artikel:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z #

Copyright © 2008 - : ARTIKEL32 | Alle rechte vorbehalten.
Vervielfältigung im Ganzen oder teilweise das Material auf dieser Website gegen das Urheberrecht und wird bestraft, nach dem Gesetz.
dsolution