Поиск по базе сайта:
Лабораторна робота №6-7 8 ак год icon

Лабораторна робота №6-7 8 ак год




Скачати 246.8 Kb.
НазваЛабораторна робота №6-7 8 ак год
Дата конвертації25.10.2014
Розмір246.8 Kb.
ТипЛабораторна робота

Архітектура комп’ютерів www.aeom.ho.ua

Лабораторна робота № 6-7 8 ак. год.

ТЕМА: Програмування матричного принтера

МЕТА: Набути навичок програмування матричного принтера Epson, розробки й виведення на друк власних шрифтів і нестандартних символів, друку графічної інформації.
ЗАВДАННЯ

Розробити та відлагодити програмне забезпечення матричного принтера Epson, яке:

  1. Скидує принтер у початковий стан, про що виводить відповідне повідомлення на екран.

  2. Перевіряє готовність принтера (за допомогою байту стану) та виводить на екран відповідне повідомлення.

  3. Якщо принтер готовий:

    1. Видає (N mod 10) звукових сигналів, де N – номер варіанта.

    2. Друкує прізвище та ім’я студента-розробника ПЗ.

    3. Переводить сторінку паперу.

    4. Друкує рядок “КНТУ” нестандартним шрифтом (як сукупність символів у звичайному режимі, або як зображення у графічному).


^ Средства BIOS для работы с принтером

BIOS использует для работы с принтером функции 0, 1, 2 прерывания INT 17h.

Функция 00h предназначена для печати одного символа:

На входе: AH = 00h;

AL = ASCII-код символа для печати;

DX = номер принтера: 0, 1 или 2.

На выходе: AH = слово состояния принтера (см. ниже).

Эта функция выводит на принтер один символ, заданный в регистре AL. В регистр DX необходимо записать номер используемого принтера, для LPT1 это 0, для LPT2 - 1 и т.д.

После выполнения прерывания регистр AH будет содержать слово состояния, имеющее следующий формат:

D0-D1 - таймаут, слишком большая задержка привыполнении операции печати, возможно,что принтер неисправен;

D2 - не используются;

D3 - ошибка ввода/вывода;

D4 - 1 - принтер выбран для работы;0 - принтер в состоянии offline;

D5 - конец бумаги;

D6 - подтверждение;

D7 - 1 - принтер готов, 0 - принтер занят.
Вызвав функцию 0 прерывания INT 17h, программа должна проверить отдельные биты слова состояния и убедиться в том, что вывод байта произошел без ошибок. Наиболее часто оператор забывает перевести принтер в состояние ONLINE, либо вставить бумагу, либо вообще включить принтер. В этом случае целесообразно напомнить оператору о необходимости выполнения этих действий и затем повторить печать символа.

Если принтер неисправен, программа должна предоставить оператору возможность отменить печать текста. Ниже мы приведем пример программы, выполняющей печать текста и анализирующей ошибки, которые могут возникнуть в процессе печати.

Обратите внимание на бит 1 байта состояния - таймаут. Если принтер находится в состоянии OFFLINE, функция 0 прерывания INT 17h ожидает некоторое время готовности принтера, после чего если принтер так и не перешел в состояние готовности, устанавливает бит 1 в байте состояния. Область данных BIOS по адресу 0000h:0478h содержит четыре байта, которые используются в качестве счетчиков времени при ожидании готовности принтера.

Прерывание INT 17h имеет еще две функции, выпоняющие инициализацию принтера и получающую текущее состояние принтера.

Функция 01h инициализирует принтер:

На входе: AH = 01h;
DX = номер принтера: 0, 1 или 2.
На выходе: AH = слово состояния принтера.

Эта функция выполняет аппаратный сброс принтера. Если вы загрузили в принтер какой-либо шрифт (например, кириллицу), после сброса загрузку шрифта придется выполнять заново. Поэтому не следует выполнять сброс принтера, если это действительно не требуется. Обычно принтер приходится сбрасывать либо перед настройкой его на заданный режим работы, которая выполняется один раз, либо при изменении этого режима.

Слово состояния принтера может быть получено с помощью функции 02h:

На входе: AH = 02h;
DX = номер принтера: 0, 1 или 2.
На выходе: AH = слово состояния принтера.

Эту функцию удобно использовать перед началом печати для определения готовности принтера к работе.

Приведем программу, которая распечатывает содержимое файла с использованием функции 0 прерывания INT 17h.

Программа считывает содержимое файла, открытого в двоичном режиме по байтам. Считанные файлы передаются в качестве параметра функции printchar(), которая и выводит их на принтер. После вызова прерывания INT 17h проверяется состояние принтера, и в случае, когда произошла ошибка ввода/вывода, вызывается обработчик ошибки - функция error(). Эта функция выводит на экран состояние принтера (в развернутом виде, с объяснением каждого бита байта состояния) и запрашивает оператора о дальнейших действиях.

Если оператор может устранить причину ошибки (перевести принтер в состояние ONLINE, вставить бумагу, если она кончилась и т.д.), он нажимает любую клавишу кроме ESC и тогда функция error() возвращает 0. В противном случае возвращается значение 1.

Если оператор решил повторить печать, и, соответственно, если функция error() возвратила значение 0, функция printchar() повторяет печать символа. В противном случае выдается сообщение об ошибке и работа программы завершается.

Итак, приведем исходный текст программы печати содержимого текстовых файлов:

#include

#include

union REGS rg;

int main(int argc, char *argv[]) {

FILE *srcfile;

// Открываем файл, заданный первым параметром в командной строке. Если при запуске программы оператор забыл указать имя файла, выводим напоминающее сообщение.

if( (srcfile = fopen( argv[1], "rb" )) == NULL ) {

printf("\nЗадайте имя файла в качестве параметра");

exit(-1);

}

// Читаем файл по одному символу, полученный из файласимвол выводим на принтер при помощи функции //printchar().

for(;;) {

printchar(fgetc(srcfile));

if(feof(srcfile)) break;

}

// Закрываем файл.

fclose(srcfile);

}

// ------------------------------------

// Эта функция выводит один символ на первый принтер (LPT1)

// ------------------------------------

int printchar(int chr) {

int status;

// Повторяем в цикле выдачу символа на принтер до тех пор, пока он не будет выведен без ошибок, либо пока оператор не отменит распечатку файла.

for(;;) {

// Дублируем распечатываемый символ на экране

putch(chr);

// Вызываем функцию 0 прерывания INT 17h -распечатка символа на принтере.

// В регистре DX задаем номер принтера LPT1 - это 0.

rg.h.ah = 0;

rg.h.al = chr;

rg.x.dx = 0;

int86(0x17, &rg, &rg);

// Запоминаем байт состояния принтера после вывода символа.

status = rg.h.ah;

// Проверяем наличие ошибок. Нас интересуют биты:

// 0 - таймаут (задержка при печати слишком велика)

// 3 - ошибка ввода/вывода

// 4 - принтер в состоянии ONLINE (1) или OFFLINE (0)

// 5 - конец бумаги
if((status & 0x39) != 0x10) {
// Вызываем функцию обработки ошибки error(). Эта функция возвращает 0, если оператор желает повторить печать символа, или 1 - если оператор отменяет печать.

if(error(chr, status)) {

printf("\nПечать завершилась аварийно");

exit(-2);

}

}

else break;

}

}

// ------------------------------------

// Функция выводит на экран состояние принтера и запрашивает у оператора требуемые действия - повторить печать символа или отменить печать.

// ------------------------------------

int error(char chr, int status) {

// Выводим состояние принтера после ошибки

printf("\nОшибка принтера %02.2X"

"\n\nСостояние принтера:"

"\n-------------------", status);

if(status & 1)

printf("\nТаймаут при печати");

if(status & 8)

printf("\nОшибка ввода/вывода");

if(!(status & 0x10))

printf("\nПринтер находится в состоянии OFFLINE");

if(status & 0x20)

printf("\nКонец бумаги");

printf("\n\nДля отмены печати нажмите клавишу ESC,"

"\nдля повтора - любую другую клавишу\n");

if(getch() == 27) return(1);

else return(0);

}

^ Средства OC для работы с принтером

Для печати символа на стандартном печатающем устройстве LPT1 (он же PRN) вы можете использовать функцию 05h прерывания MS-DOS INT 21h:

На входе: AH = 05h;

DL = ASCII-код символа для печати.

На выходе: AH = слово состояния принтера (см. ниже).

Команда MS-DOS MODE может переназначить стандартное устройство печати LPT1 на асинхронный последовательный порт:

MODE LPT1:=COM1

Мы подготовили еще одну программу распечатки содержимого файла, но уже при помощи прерывания MS-DOS:

#include

#include

union REGS rg;

int main(int argc, char *argv[]) {

FILE *srcfile;

// Открываем файл, заданный первым параметром в командной строке. Если при запуске программы оператор забыл указать имя файла, выводим напоминающее сообщение.

if( (srcfile = fopen( argv[1], "rb" )) == NULL ) {

printf("\nЗадайте имя файла в качестве параметра");

exit(-1);

}

// Читаем файл по одному символу, полученный из файла символ выводим на принтер при помощи функции //printchar().

for(;;) {

printchar(fgetc(srcfile));

if(feof(srcfile)) break;

}

// Закрываем файл.

fclose(srcfile);

}

// ------------------------------------

// Эта функция выводит один символ на стандартный принтер (LPT1)

// ------------------------------------

int printchar(int chr) {

// Дублируем распечатываемый символ на экране

putch(chr);

// Вызываем функцию 5 прерывания INT 21h - распечатка символа на принтере.

rg.h.ah = 5;

rg.h.dl = chr;

int86(0x21, &rg, &rg);

}

Заметьте, что функция 05h прерывания INT 21h не возвращает состояния принтера при ошибке ввода/вывода. Вместо этого вызывается стандартный обработчик критических ошибок MS-DOS, который выводит на экран хорошо знакомое вам сообщение:

Write fault error writing device PRN

Abort, Retry, Ignore, Fail?

Вы можете ответить Retry, нажав клавишу "R", тогда MS-DOS выполнит попытку повторить печать символа. Если ответить Abort (нажав клавишу "A"), MS-DOS завершит работу вашей программы.

Поэтому приведенная выше программа не содержит обработчика ошибочных ситуаций error(). Если вас не устраивают действия, выполняемые стандартным обработчиком критических ошибок MS-DOS, вы можете составить собственный. В третьей книге первого тома "Библиотеки системного программиста" мы рассказывали вам о создании и подключении собственного обработчика критических ошибок.

Более интересные возможности по управлению процессом печати предоставляет программа резидентного спулера печати PRINT.COM. Вы знаете, что команда PRINT предназначена для выполнения печати в фоновом режиме.

Оказывается, что если запущена программа PRINT, другие программы могут взаимодействовать с ней, управляя процессом печати.

Для связи со спулером печати можно использовать несколько функций прерывания INT 2Fh:

На входе: AH = 01h;

AL = номер выполняемой операции.

На выходе: AH = 00 - спулер печати не установлен,

но его можно установить, запустив

программу PRINT;

01 - спулер печати не установлен и

его установка невозможна (система

не содержит ни одного принтера);

FFh - спулер установлен.

Приведем форматы регистров для выполнения различных операций со спулером печати.

На входе: AH = 01h;

AL = 0 - проверить установку спулера печати.

На выходе: AH = 00 - спулер печати не установлен,

но его можно установить, запустив

программу PRINT;

01 - спулер печати не установлен и

его установка невозможна;

FFh - спулер установлен.

На входе: AH = 01h;

AL = 1 - передача файла спулеру для печати;

DS:DX = адрес управляющего блока:

Смещение Длина

(+0) 1 уровень запроса, равен 0;

(+1) 4 FAR-адрес строки в формате ASCIIZ,

содержащей путь файла.

На выходе: AH = 00 - спулер печати не установлен,

но его можно установить, запустив

программу PRINT;

01 - спулер печати не установлен и

его установка невозможна;

FFh - спулер установлен.

На входе: AH = 01h;

AL = 2 - отменить печать файла;

DS:DX = адрес строки в формате ASCIIZ,

содержащей имя файла, удаляемого

из очереди для печати.

На выходе: AH = 00 - спулер печати не установлен,

но его можно установить, запустив

программу PRINT;

01 - спулер печати не установлен и

его установка невозможна;

FFh - спулер установлен.

На входе: AH = 01h;

AL = 3 - отменить печать всех файлов.

На выходе: AH = 00 - спулер печати не установлен,

но его можно установить, запустив

программу PRINT;

01 - спулер печати не установлен и

его установка невозможна;

FFh - спулер установлен.
На входе: AH = 01h;

AL = 4 - определить состояние спулера

и заблокировать спулер.

На выходе: DS:SI = адрес очереди печати (массив строк

в формате ASCIIZ, конец массива

отмечен строкой, состоящей из 0;

DX = количество ошибок при попытке напечатать

последний символ;

AH = 00 - спулер печати не установлен,

но его можно установить, запустив

программу PRINT;

01 - спулер печати не установлен и

его установка невозможна;

FFh - спулер установлен.
На входе: AH = 01h;

AL = 5 - разблокировать спулер для продолжения

печати.

На выходе: AH = 00 - спулер печати не установлен,

но его можно установить, запустив

программу PRINT;

01 - спулер печати не установлен и

его установка невозможна;

FFh - спулер установлен.

Если после вызова перечисленных выше функций флаг переноса CF установлен в 1, регистр AX содержит код ошибки:

  • 1

  • Неправильный код функции

  • 2

  • Файл не найден

  • 3

  • Путь не найден

  • 4

  • Слишком много открытых файлов

  • 5

  • Доступ запрещен

  • 6

  • Неправильный индекс (handle)

  • 8

  • Переполнение очереди

  • 9

  • Занято

  • 0Ch

  • Слишком длинный путь и имя файла (больше 64 байтов)

  • 0Fh

  • Неправильное определение диска

Программирование режимов принтера

Для изменения режимов работы принтера и выполнения загрузки шрифтов используются специальные командные последовательности символов. Командные последовательности посылаются в принтер как обычные символы. Вы можете использовать описанные ранее функции MS-DOS или BIOS для вывода этих последовательностей.

Признак начала командной последовательности символов - байт ESC с кодом 1Bh. Вслед за этим байтом программа посылает в принтер саму командную последовательность. Длина последовательности зависит от выполняемой команды.

Первый байт командной последовательности - код выполняемой команды. Далее следует один или несколько байтов параметра команды. Некоторым командам не предшествует байт ESC (это, например, команды перевода строки, страницы или команды табуляции).

Подробное описание всех команд не входит в задачу данной книги. В приложении, однако, приведены полные таблицы команд для принтеров Epson LQ-2550 и Epson FX-1050/850 с краткими пояснениями для каждой команды. Мы опишем подробно лишь несколько команд принтера Epson FX-850/1050 с целью иллюстрации способов программирования с использованием протокола ESC/P.

^ ESC "@" Инициализация принтера

Для сброса принтера в исходное состояние программа должна послать на принтер два байта - байт ESC (1Bh) и байт, соответствующий ASCII-символу "@" (40h).

^ 07h Генерация звукового сигнала

Если послать этот байт, принтер издаст звуковой сигнал. Сигнал удобно использовать для привлечения внимания оператора, например, когда кончилась бумага.

^ 0Dh Возврат каретки

Распечатываются все символы из буфера принтера, затем каретка (печатающая головка) возвращается к началу строки. В зависимости от переключателя конфигурации SW 2-4 может дополнительно выполняться прогон бумаги на одну строку.

^ 0Ah Перевод строки

Когда этот символ посылается на принтер, все символы, находящиеся во внутреннем буфере принтера, распечатываются, затем каретка возвращается к началу строки и происходит подача листа вперед на одну строку.

^ 0Ch Перевод страницы

Принтер распечатывает все символы, находившиеся в буфере, затем выполняет прогон одного листа бумаги.

ESC "x" n Выбор качества печати:

0 - низкое качество;

1 - качественный шрифт NLQ.

Для задания типа шрифта надо вывести на принтер три байта: символ ESC (1Bh), символ "x" (78h), затем код шрифта (30h...31h).

Существуют различные команды, позволяющие определить размер межстрочного интервала, расположение левой и правой границ листа, используемый для печати шрифт. Можно выполнять печать графических изображений, о чем мы раскажем немного позже.

Если вас не устраивает шрифт, который записан в ПЗУ принтера (например, в нем нет русских букв), вы можете использовать команды для загрузки собственного шрифта.

Приведем пример программы, которая посылает в принтер командные последовательности и обычные символы, пользуясь функцией 05h прерывания INT 21h:

#include

#include

main() {

char buffer[] = {

0x1b, '@', // Сбрасываем принтер в исходное состояние.

7,7,7, // Выдаем 3 раза звуковой сигнал.

0x1b, 'x','0', // Устанавливаем низкое качество печати.

'S','t','r','i','n','g',' ','1', // Печатаем строку.

0x1b, 'x','1', // Устанавливаем высокое качество печати.

'S','t','r','i','n','g',' ','2', // Печатаем строку.

0x0a, // Переводим строку.

7,7,7, // Выдаем 3 раза звуковой сигнал.

0

};

char *p;

// Выводим строку символов на принтер

for(p = buffer; *p != 0; p++) bdos(0x05, *p, 0);

}

Для вывода символа на принтер через функцию MS-DOS здесь использована функция bdos(), входящая в состав стандартных библиотек трансляторов Microsoft QC 2.5 и C 6.0. Первый параметр функции bdos() - номер выполняемой функции прерывания MS-DOS INT 21h, второй - содержимое регистра DX перед вызовом этой функции, и третий - содержимое регистра AL.

В комментариях к программе объясняется назначение управляющих последовательностей, посылаемых на принтер. Перед запуском программы необходимо убедиться в том, что принтер включен и находится в состоянии ON LINE, иначе программа перейдет в состояние ожидания.

^ Печать нестандартных (собственных) символов

Для разработки собственных символов используется сетка. В 9-игольчатых принтерах эта сетка имеет 11 столбцов и девять строк:



Из девяти строк может использоваться только 8 верхних или 8 нижних (это показано на левом и правом рисунках соответственно).

Обычно символ располагается выше утолщенной линии, то есть в строках с номерами от 1 до 7. Исключение составляют такие буквы, как "у", "ц" и т.п. Нижние "хвостики" этих букв должны находиться на строке с номером 0.

Есть ограничение на расположение отдельных точек определяемого символа в строке - эти точки не должны находиться рядом, то есть между точками в строке должна находиться одна свободная ячейка.

Для переопределения символов 9-игольчатый принтер Epson использует команду ESC "&":

ESC "&" "0" n1 n2 a1 d1 d2 ... dn Определить символы

Параметры n1 и n2 задают диапазон кодов ASCII символов, начертание которых необходимо переопределить. Если вы переопределяете только один символ, эти два параметра должны быть одинаковыми.

Параметр a1 определяет ширину символа в точках и его положение в сетке (использует ли символ верхние восемь линий, либо нижние восемь линий). Ширина определяемого символа требуется для печати в пропорциональном режиме, когда место, занимаемое каждой буквой в строке распечатки, зависит от ее ширины. Например, буква "Ш" шире, чем буква "И".

Старший бит параметра a1 задает расположение символа в сетке. Если этот бит равен 1, используются восемь верхних линий сетки, если 0 - восемь нижних.

Младшие семь битов задают ширину символа и представляют собой число, определяемое по следующей схеме:

  • возмите в качестве начального значения для ширины символа число 8;

  • для каждого пустого столбца в сетке с правой стороны символа надо вычесть из начального значения единицу;

  • для каждого пустого столбца в сетке с левой стороны символа надо прибавить к начальному значению число 16.

Пусть определяемый символ располагается в верхней части сетки (использует восемь верхних строк). Пусть этот символ начинается в третьем столбце и заканчивается в 7 столбце. Тогда десятичное значение параметра a1 вычисляется следующим образом:

a1 = 8(начальное значение) -

- 2(два пустых столбца справа) +

+ 32(два пустых столбца слева) +

+ 128(старший бит равен 1) = 166

Если ваш символ использует верхние восемь строк сетки, начинается в первом столбце и заканчивается в девятом, в качестве параметра a1 подходит значение 136. При этом символы будут печататься верхними восемью иголками печатающей головки. Для использования нижних восьми иголок и такой же ширины символа задайте значение a1 равное 8.

Параметры d1...dn - образцы столбцов точек для определяемого символа. Их должно быть всегда 11, даже если символ содержит пустые столбцы. Для пустых столбцов в качестве образца надо задать 0.

Для включения определенного программой набора символов в работу необходимо выдать команду ESC "%" "0", для использования набора символов из внутреннего ПЗУ принтера выдайте команду ESC "%" "1".

Приведем пример программы, изменяющей начертание символа "@" в принтере Epson FX-850/1050. Для правильной работы программы переключатель SW 1-1 должен быть установлен в положение OFF.

#include

#include

main() {

char buffer[] = {

0x1b, '@', // Сбрасываем принтер в исходное состояние.

7,7,7, // Выдаем 3 раза звуковой сигнал.

// Определяем вместо "@" новый символ:

0x1b, '&', 0,

'@', '@', 136,

32,80,168,84,42,84,168,80,32,0,0,

// Выдаем строку символов, используем начертание, заданное в ПЗУ принтера.

'@', '@', '@', '@', '@', 0x0a,

// Используем новое начертание:

0x1b, '%', 1,

'@', '@', '@', '@', '@', 0x0a,

// Возвращаемся опять к старому начертанию:

0x1b, '%', 0,

'@', '@', '@', '@', '@', 0x0a,

7,7,7, // Выдаем 3 раза звуковой сигнал.

'$' // Признак конца массива данных

};

char *p;

// Выводим строку символов на принтер

for(p = buffer; *p != '$'; p++)

bdos(0x05, *p, 0);

}

Рассмотрим теперь метод переопределения начертания символов в 24-иголочном принтере Epson LQ-2550. Для определения начертания символов в этом принтере используется сетка высотой 24 точки - соответственно, по одной точке для каждой иголки в печатающей головке.

24-иголочный принтер использует несколько наборов символов:

  • черновой набор символов (Draft);

  • качественный набор символов (Letter Quality);

  • пропорциональный набор символов (Proportional).

В зависимости от используемого набора символов ширина сетки может быть либо 9 точек (для чернового набора символов, либо 29 точек (для качественного набора символов), либо 37 точек (для пропорционального набора символов). Кроме того, для последних двух наборов столбцы сетки расположены ближе друг к другу, чем для чернового набора.

На рисунке показаны сетки для чернового и качественного/пропорционального наборов символов принтера Epson LQ-2550:



Обычные символы располагаются между жирными линиями. Нижние линии сетки используются для подчеркивания и изображения "хвостиков" таких букв, как "у", "ц" и т.п.

Так же, как и для 9-игольчатых принтеров, существует ограничение на расположение точек в узлах сетки: справа и слева от каждой точки должны располагаться пустые позиции.

Приведем формат команды для переопределения символов в принтере Epson LQ-2550:

ESC "&" "0" n1 n2 d0 d1 d2 data Определить символы

Параметры n1 и n2 задают диапазон кодов ASCII символов, начертание которых необходимо переопределить. Их назначение такое же, как и для 9-игольчатых принтеров Epson. Если вы переопределяете только один символ, эти два параметра должны быть одинаковыми.

Далее следуют три байта данных, которые задают ширину символа и размер свободного пространства вокруг символа. Параметр d0 задает количество свободных столбцов слева от символа, параметр d2 определяет количество свободных столбцов справа от символа. Параметр d1 определяет ширину символа в столбцах сетки.

Изменяя ширину символа и размер свободного пространства вокруг него можно формировать пропорциональные наборы символов.

В следующей таблице приведены максимальные значения для параметров d0, d1, d2 для различных наборов символов:

Набор d1 d0+d1+d2

Черновой 9 12

Качественный, 29 36

10 символов на дюйм

Качественный, 23 30

12 символов на дюйм

Пропорциональный 37 42

После параметра d2 следует последовательность байтов, описывающих символ, т.е. образец для символа. Для задания одного столбца сетки требуется три байта, поэтому для определения одного символа вы должны задать (d1 * 3) байтов данных.

^ Печать в графическом режиме

До сих пор мы использовали принтер только для печати символьной информации - буквы, цифры, символы псевдографики и т.д. Коды символов мы тем или иным способом выводили на принтер, принтер распечатывал их с использованием внутренних шрифтов, записанных в ПЗУ принтера, или с использованием загружаемых шрифтов.

Однако печать символов - это не все, на что способен матричный принтер. Вспомним, как происходит печать букв.

Принтерная головка содержит 9 или 24 иголки, расположенных вертикально. Печатающая головка движется в горизонтальном направлении вдоль листа бумаги, причем между головкой и листом находится красящая лента. Каждая иголка управляется отдельным электромагнитом, при включении которого она "выстреливается" в направлении красящей ленты, оставляя на бумаге маленькую точку. Цвет этой точки определяется красящей лентой. Цветные матричные принтеры (например, LQ2550) заряжаются многоцветной лентой. Эта лента напоминает черно-красную ленту для механических пишущих машинок, но на ней больше цветов. Обычно используются четырехцветные ленты, раскрашенные следующими цветами - желтый, красный, синий, черный.

В процессе печати кассета с цветной лентой может перемещаться в вертикальном направлении, поэтому перед печатающей головкой может оказаться участок ленты с одним из четырех цветов.

При наложении цветов возможно получение различных цветовых комбинаций, поэтому хотя цветов на ленте всего четыре, цветной принтер может печатать достаточно качественные и многоцветные изображения.

Когда принтер печатает алфавитно-цифровой символ, он, передвигая печатающую головку слева направо (или справа налево, что тоже возможно), "выстреливает" теми иголками, которые соответствуют заданному шрифтом изображению символа.

Очевидно, что если бы у нас была возможность самостоятельно управлять иголками и перемещением кассеты с цветной красящей лентой, мы могли бы самостоятельно формировать цветное графическое изображение, так, как это делается в полиграфии. Если вы внимательно посмотрите на фотографии, напечатанные в газетах или журналах, вы заметите, что графическое изображение состоит из отдельных точек разного цвета и очень маленького размера.

Практически любые матричные принтеры позволяют печатать графические изображения. Девяти иголочные принтеры Epson FX используют для графической печати 8 верхних иголок. При этом за один проход можно напечатать одну графическую "строку", послав в принтер битовый образ строки.

Если печатаемое графическое изображение по высоте превышает 8 точек, оно выводится в несколько приемов, построчно. После вывода очередной строки программа должна продвинуть бумагу на одну строку вперед. Для того чтобы между графическими строками не оставалось свободного места, необходимо правильно установить межстрочный интервал - не более 8/72 дюйма.

Как перевести принтер в режим графической печати?

Для этого принтер Epson FX-1050 использует следующую команду:

ESC "*" m n1 n2 data Печать в графическом режиме

В этой команде m задает режим печати:

Значение m Режим

0 Одинарная плотность, 60 точек на дюйм

1 Двойная плотность, 120 точек на дюйм

2 Двойная плотность, печать с высокой скоростью, 120 точек на дюйм

3 Учетверенная плотность, 240 точек на дюйм

4 Режим CRT I, плотность 80 точек на дюйм

5 Режим плоттера (1:1), плотность 72 точки на дюйм

6 Режим CRT II, плотность 90 точек на дюйм

7 Режим плоттера с двойной плотностью, 144 точки на дюйм

Параметры n1 и n2 определяют длину печатаемой графической строки в точках. При определении длины графической строки необходимо учитывать, что в режиме одинарной плотности на строке длиной 8 дюймов можно разместить 480 точек, в режиме учетверенной плотности - около 2000.

Так как передача данных в принтер выполняется по байтам, для представления длины строки приходится использовать два байта информации. Для вычисления параметров n1 и n2 можно использоваться следующей схемой действий:

  • делим длину строки на 256, целочисленный результат деления используем в качестве параметра n2;

  • остаток от деления используем в качестве n1.

Например, пусть нам надо распечатать строку из 1234 точек. Тогда параметр n2 будет равен 1234 / 256 = 4. Остаток от деления составит 1234 - 256 * 4 = 210. Это и есть параметр n1.

Проверяем: 4 * 256 + 210 = 1234

Команда должна всегда содержать два параметра, даже если параметр n2 получился равным нулю.

Вслед за параметрами n1 и n2 должны следовать байты графических данных, предназначенные для печати. Должно быть передано точно n2 * 256 + n1 байтов.

Если вы передатите меньше графических данных, чем это было определено в команде ESC "*", следующие вводимые в принтер команды или данные будут интерпретироваться как графические данные. Если вы передадите больше графических данных чем нужно, лишние данные будут напечатаны как обычный текст.

Для представления одного восьмиточечного столбца графической строки используется один байт данных, причем верхней точке в столбце соответствует старший разряд байта, а нижней - младший:

* 7 Этому столбцу соответствует

o 6 байт 10011011b или 9Bh

o 5

* 4

* 3

o 2

* 1

* 0

На этом рисунке "*" означает точку в столбце графической строки, "o" - отсуствие точки.

Вам необходимо подготовить таким образом байты для всех столбцов, входящих в распечатываемую графическую строку.

Цветной 24-игольчатый принтер Epson LQ-2550 может работать в описанном выше 8-битовом графическом режиме. Это сделано для обеспечения совместимости со старым программным обеспечением, рассчитанным на принтеры серий FX, RX, LX и EX. Однако все возможности этого принтера раскрываются только при использовании всех его 24 иголок. В этом случае графическое изображение печатается отдельными строчками, высота которых составляет 24 точки. При этом для представления одного столбца графической строки требуется три байта данных. Каждый байт должен готовиться отдельно, при этом можно считать, что 24-битовая графическая строка состоит из трех 8-битовых.

Формат команды графической печати для этого принтера расширен по сравнению с описанным выше:

ESC "*" m n1 n2 data Печать в графическом режиме

В этой команде m, как и раньше, задает режим печати. Однако для этого параметра определено больше значений:

Значение m Режим

0 Одинарная плотность, 60 точек на дюйм, 8-битовая графика

1 Двойная плотность, 120 точек на дюйм, 8-битовая графика

2 Двойная плотность, печать с высокой, скоростью, 120 точек на дюйм, 8-битовая графика

3 Учетверенная плотность, 240 точек на дюйм, 8-битовая графика

4 Режим CRT I, плотность 80 точек на дюйм, 8-битовая графика
6 Режим CRT II, плотность 90 точек на дюйм, 8-битовая графика

32 Одинарная плотность, 60 точек на дюйм, 24-битовая графика

33 Двойная плотность, 120 точек на дюйм, 24-битовая графика

38 Режим CRT III, плотность 90 точек на дюйм, 24-битовая графика

39 Тройная плотность, 180 точек на дюйм, 24-битовая графика

40 Шестикратное увеличение плотности, 360 точек на дюйм, 24-битовая графика

Учтите, что для команды 24-битового графического вывода требуется массив графических данных в три раза больше по размеру, чем для 8-битовой команды.

Приведем пример программы, выводящей на принтер в режиме 8-битовой графики строку, состоящую из 40 столбцов:

#include

#include

union REGS rg;

int main() {

int i;

// Переводим строку

printchar(0x0d);

printchar(0x0a);

// Выдаем на принтер команду графической печати (ESC "*" m n1 n2 data)

printchar(27);

printchar('*');

// Выбираем режим 0 - 8-битовая графика, одинарная плотность

printchar(0);

// Задаем длину графической строки: n1 = 40; n2 = 0

printchar(40);

printchar(0);

// Выводим в цикле 40 раз байт DBh

for(i=0; i<40; i++)

printchar(0xdb);

// Переводим строку

printchar(0x0d);

printchar(0x0a);

}

// ------------------------------------

// Эта функция выводит один символ на стандартный принтер (LPT1)

// ------------------------------------

int printchar(int chr) {

// Вызываем функцию 5 прерывания INT 21h - распечатка символа на принтере.

rg.h.ah = 5;

rg.h.dl = chr;

int86(0x21, &rg, &rg);

}

Аналогичная программа, использующая 24-битовую графику на принтере Epson LQ-2550:

#include

#include

union REGS rg;

int main() {

int i;

// Переводим строку

printchar(0x0d);

printchar(0x0a);

// Выдаем на принтер команду графической печати (ESC "*" m n1 n2 data)

printchar(27);

printchar('*');

// Выбираем режим 32 - 24-битовая графика, одинарная плотность

printchar(32);

// Задаем длину графической строки: n1 = 40; n2 = 0

printchar(40);

printchar(0);

// Выводим в цикле 120 раз байт DBh. Для вывода строки из 40 столбцов в 24-битовом режиме требуется в три раза больше графических данных, чем для 8-битового режима.

for(i=0; i<120; i++)

printchar(0xdb);

// Переводим строку

printchar(0x0d);

printchar(0x0a);

}

// ------------------------------------

// Эта функция выводит один символ на стандартный принтер (LPT1)

// ------------------------------------

int printchar(int chr) {

// Вызываем функцию 5 прерывания INT 21h - распечатка символа на принтере.

rg.h.ah = 5;

rg.h.dl = chr;

int86(0x21, &rg, &rg);

}

Для вывода на принтер сложных графических изображений ваша программа должна сначала подготовить массив данных для построчной 8-битовой или 24-битовой печати. Затем готовый массив можно вывести на принтер, используя несколько команд графического вывода (по одной команде на одну графическую строку).








Схожі:




База даних захищена авторським правом ©lib.exdat.com
При копіюванні матеріалу обов'язкове зазначення активного посилання відкритою для індексації.
звернутися до адміністрації